Snapshot 7ddd630e136a035ba463c427285c5c3e9f199ee0

Change-Id: If08c7b905da667dd9e5110231e4592842b634006
diff --git a/Android.mk b/Android.mk
new file mode 100755
index 0000000..a953849
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,76 @@
+define all-cpp-files-under
+$(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find $(1) -name "*.cpp" -and -not -name ".*") \
+ )
+endef
+
+
+LOCAL_PATH:= $(call my-dir)
+NFA:=src/nfa
+NFC:=src/nfc
+UDRV:=src/udrv
+
+#gki
+GKI_FILES:=$(call all-c-files-under, src/gki)
+
+#
+# libnfc-nci
+#
+#nfa
+NFA_ADAP_FILES:= \
+    $(call all-c-files-under, src/adaptation) \
+    $(call all-cpp-files-under, src/adaptation)
+
+#nfa
+NFA_FILES:= $(call all-c-files-under, $(NFA))
+NFC_FILES:= $(call all-c-files-under, $(NFC))
+
+COMMON_CFLAGS += -DANDROID -DANDROID_USE_LOGCAT=TRUE
+
+NFA_CFLAGS += -DNFC_CONTROLLER_ID=1
+D_CFLAGS += -DDEBUG -D_DEBUG -O0 -g
+
+ifeq ($(findstring maguro,$(TARGET_PRODUCT)),)
+ifeq ($(findstring crespo,$(TARGET_PRODUCT)),)
+D_CFLAGS += -DGENERIC_TARGET=1
+endif
+endif
+
+D_CFLAGS += -DBUILDCFG=1
+D_CFLAGS += -DNFA_APP_DOWNLOAD_NFC_PATCHRAM=TRUE
+
+#NTAL includes
+NTAL_CFLAGS += -I$(LOCAL_PATH)/src/include
+NTAL_CFLAGS += -I$(LOCAL_PATH)/src/gki/ulinux
+NTAL_CFLAGS += -I$(LOCAL_PATH)/src/gki/common
+
+#NFA NFC includes
+NFA_CFLAGS += -I$(LOCAL_PATH)/src/include
+NFA_CFLAGS += -I$(LOCAL_PATH)/src/gki/ulinux
+NFA_CFLAGS += -I$(LOCAL_PATH)/src/gki/common
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(NFA)/brcm
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(NFA)/include
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(NFA)/int
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(NFC)/brcm
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(NFC)/include
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(NFC)/int
+NFA_CFLAGS += -I$(LOCAL_PATH)/$(UDRV)/include
+NFA_CFLAGS += -I$(LOCAL_PATH)/src/hal/include
+
+ifneq ($(NCI_VERSION),)
+NFA_CFLAGS += -DNCI_VERSION=$(NCI_VERSION)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE:= libnfc-nci
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils libdl libstlport libhardware
+LOCAL_CFLAGS := $(COMMON_CFLAGS) $(D_CFLAGS) $(NFA_CFLAGS)
+LOCAL_C_INCLUDES := external/stlport/stlport bionic/ bionic/libstdc++/include
+LOCAL_SRC_FILES := $(NFA_ADAP_FILES) $(GKI_FILES) $(NFA_FILES) $(NFC_FILES) $(LOG_FILES)
+include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..e051104
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libnfc-nci_intermediates)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/halimpl/Android.mk b/halimpl/Android.mk
new file mode 100644
index 0000000..cfd03be
--- /dev/null
+++ b/halimpl/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/halimpl/bcm2079x/Android.mk b/halimpl/bcm2079x/Android.mk
new file mode 100644
index 0000000..99cf768
--- /dev/null
+++ b/halimpl/bcm2079x/Android.mk
@@ -0,0 +1,56 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# function to find all *.cpp files under a directory
+define all-cpp-files-under
+$(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find $(1) -name "*.cpp" -and -not -name ".*") \
+ )
+endef
+
+
+HAL_SUFFIX := $(TARGET_DEVICE)
+ifeq ($(TARGET_DEVICE),crespo)
+	HAL_SUFFIX := herring
+endif
+
+
+######################################
+######################################
+# build shared library system/lib/hw/nfc_nci.*.so
+# which is linked by libhardware.so
+
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := nfc_nci.$(HAL_SUFFIX)
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SRC_FILES := $(call all-c-files-under, .)  $(call all-cpp-files-under, .)
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware_legacy libstlport
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES += external/stlport/stlport  bionic/  bionic/libstdc++/include \
+	$(LOCAL_PATH)/include \
+	$(LOCAL_PATH)/gki/ulinux \
+ 	$(LOCAL_PATH)/gki/common \
+	$(LOCAL_PATH)/udrv/include \
+	$(LOCAL_PATH)/hal/include \
+	$(LOCAL_PATH)/hal/int
+
+LOCAL_CFLAGS += -DANDROID \
+	-DBUILDCFG=1 -DNFC_HAL_TARGET=TRUE -DNFC_RW_ONLY=TRUE
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/halimpl/bcm2079x/adaptation/CondVar.cpp b/halimpl/bcm2079x/adaptation/CondVar.cpp
new file mode 100644
index 0000000..b676942
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/CondVar.cpp
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a condition variable for thread synchronization.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "CondVar.h"
+#include <errno.h>
+
+
+/*******************************************************************************
+**
+** Function:        CondVar
+**
+** Description:     Initialize member variables.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::CondVar ()
+{
+    memset (&mCondition, 0, sizeof(mCondition));
+    int const res = pthread_cond_init (&mCondition, NULL);
+    if (res)
+    {
+        ALOGE ("CondVar::CondVar: fail init; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        ~CondVar
+**
+** Description:     Cleanup all resources.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::~CondVar ()
+{
+    int const res = pthread_cond_destroy (&mCondition);
+    if (res)
+    {
+        ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        wait
+**
+** Description:     Block the caller and wait for a condition.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void CondVar::wait (Mutex& mutex)
+{
+    int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle());
+    if (res)
+    {
+        ALOGE ("CondVar::wait: fail wait; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        wait
+**
+** Description:     Block the caller and wait for a condition.
+**                  millisec: Timeout in milliseconds.
+**
+** Returns:         True if wait is successful; false if timeout occurs.
+**
+*******************************************************************************/
+bool CondVar::wait (Mutex& mutex, long millisec)
+{
+    bool retVal = false;
+    struct timespec absoluteTime;
+
+    if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1)
+    {
+        ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno);
+    }
+    else
+    {
+        absoluteTime.tv_sec += millisec / 1000;
+        long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
+        if (ns > 1000000000)
+        {
+            absoluteTime.tv_sec++;
+            absoluteTime.tv_nsec = ns - 1000000000;
+        }
+        else
+            absoluteTime.tv_nsec = ns;
+    }
+
+    //pthread_cond_timedwait_monotonic_np() is an Android-specific function
+    //declared in /development/ndk/platforms/android-9/include/pthread.h;
+    //it uses monotonic clock.
+    //the standard pthread_cond_timedwait() uses realtime clock.
+    int waitResult = pthread_cond_timedwait_monotonic_np (&mCondition, mutex.nativeHandle(), &absoluteTime);
+    if ((waitResult != 0) && (waitResult != ETIMEDOUT))
+        ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult);
+    retVal = (waitResult == 0); //waited successfully
+    return retVal;
+}
+
+
+/*******************************************************************************
+**
+** Function:        notifyOne
+**
+** Description:     Unblock the waiting thread.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void CondVar::notifyOne ()
+{
+    int const res = pthread_cond_signal (&mCondition);
+    if (res)
+    {
+        ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res);
+    }
+}
+
diff --git a/halimpl/bcm2079x/adaptation/CondVar.h b/halimpl/bcm2079x/adaptation/CondVar.h
new file mode 100644
index 0000000..afa3fbf
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/CondVar.h
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a condition variable for thread synchronization.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <pthread.h>
+#include "Mutex.h"
+
+
+class CondVar
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        CondVar
+    **
+    ** Description:     Initialize member variables.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    CondVar ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        ~CondVar
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~CondVar ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the caller and wait for a condition.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void wait (Mutex& mutex);
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the caller and wait for a condition.
+    **                  millisec: Timeout in milliseconds.
+    **
+    ** Returns:         True if wait is successful; false if timeout occurs.
+    **
+    *******************************************************************************/
+    bool wait (Mutex& mutex, long millisec);
+
+
+    /*******************************************************************************
+    **
+    ** Function:        notifyOne
+    **
+    ** Description:     Unblock the waiting thread.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void notifyOne ();
+
+private:
+    pthread_cond_t mCondition;
+};
diff --git a/halimpl/bcm2079x/adaptation/HalAdaptation.cpp b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
new file mode 100644
index 0000000..54b1ae8
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
@@ -0,0 +1,255 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  HAL Adaptation Interface (HAI). This interface regulates the interaction
+ *  between standard Android HAL and Broadcom-specific HAL.  It adapts
+ *  Broadcom-specific features to the Android framework.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "HalAdaptation.h"
+#include "SyncEvent.h"
+#include "config.h"
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include <errno.h>
+#include <pthread.h>
+
+
+///////////////////////////////////////
+// private declaration, definition
+
+
+static nfc_stack_callback_t* gAndroidHalCallback = NULL;
+static nfc_stack_data_callback_t* gAndroidHalDataCallback = NULL;
+static SyncEvent gOpenCompletedEvent;
+static SyncEvent gPostInitCompletedEvent;
+static SyncEvent gCloseCompletedEvent;
+
+UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
+
+static void BroadcomHalCallback (UINT8 event, tHAL_NFC_STATUS status);
+static void BroadcomHalDataCallback (UINT16 data_len, UINT8* p_data);
+
+
+///////////////////////////////////////
+
+
+int HaiInitializeLibrary (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+    unsigned long freq = 0;
+    unsigned long num = 0;
+
+    InitializeGlobalAppLogLevel ();
+
+    //initialize the crystal frequency
+    if (GetNumValue((char*)NAME_XTAL_FREQUENCY, &freq, sizeof(freq)))
+    {
+        ALOGD("%s: setting xtal frequency=%lu", __FUNCTION__, freq);
+        nfc_post_reset_cb.dev_init_config.xtal_freq = (UINT16) freq;
+        nfc_post_reset_cb.dev_init_config.flags |= NFC_HAL_DEV_INIT_FLAGS_SET_XTAL_FREQ;
+    }
+
+    // Initialize protocol logging level
+    if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
+        ScrProtocolTraceFlag = num;
+
+    HAL_NfcInitialize ();
+
+    // Initialize appliation logging level
+    if ( GetNumValue ( NAME_APPL_TRACE_LEVEL, &num, sizeof ( num ) ) ) {
+        HAL_NfcSetTraceLevel(num);
+    }
+
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiTerminateLibrary ()
+{
+    int retval = EACCES;
+    ALOGD ("%s: enter", __FUNCTION__);
+
+    HAL_NfcTerminate ();
+    gAndroidHalCallback = NULL;
+    gAndroidHalDataCallback = NULL;
+    GKI_shutdown ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiOpen (const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc, nfc_stack_data_callback_t* halDataCallbackFunc)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    gAndroidHalCallback = halCallbackFunc;
+    gAndroidHalDataCallback = halDataCallbackFunc;
+
+    SyncEventGuard guard (gOpenCompletedEvent);
+    HAL_NfcOpen (BroadcomHalCallback, BroadcomHalDataCallback);
+    gOpenCompletedEvent.wait ();
+
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+void BroadcomHalCallback (UINT8 event, tHAL_NFC_STATUS status)
+{
+    ALOGD ("%s: enter; event=0x%X", __FUNCTION__, event);
+    switch (event)
+    {
+    case HAL_NFC_OPEN_CPLT_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_OPEN_CPLT_EVT; status=0x%X", __FUNCTION__, status);
+            SyncEventGuard guard (gOpenCompletedEvent);
+            gOpenCompletedEvent.notifyOne ();
+            break;
+        }
+
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_POST_INIT_CPLT_EVT", __FUNCTION__);
+            SyncEventGuard guard (gPostInitCompletedEvent);
+            gPostInitCompletedEvent.notifyOne ();
+            break;
+        }
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_CLOSE_CPLT_EVT", __FUNCTION__);
+            SyncEventGuard guard (gCloseCompletedEvent);
+            gCloseCompletedEvent.notifyOne ();
+            break;
+        }
+
+    case HAL_NFC_ERROR_EVT:
+        {
+            ALOGD ("%s: HAL_NFC_ERROR_EVT", __FUNCTION__);
+            {
+                SyncEventGuard guard (gOpenCompletedEvent);
+                gOpenCompletedEvent.notifyOne ();
+            }
+            {
+                SyncEventGuard guard (gPostInitCompletedEvent);
+                gPostInitCompletedEvent.notifyOne ();
+            }
+            {
+                SyncEventGuard guard (gCloseCompletedEvent);
+                gCloseCompletedEvent.notifyOne ();
+            }
+            break;
+        }
+    }
+    gAndroidHalCallback (event, status);
+    ALOGD ("%s: exit; event=0x%X", __FUNCTION__, event);
+}
+
+
+void BroadcomHalDataCallback (UINT16 data_len, UINT8* p_data)
+{
+    ALOGD ("%s: enter; len=%u", __FUNCTION__, data_len);
+    gAndroidHalDataCallback (data_len, p_data);
+}
+
+
+int HaiClose (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    SyncEventGuard guard (gCloseCompletedEvent);
+    HAL_NfcClose ();
+    gCloseCompletedEvent.wait ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiCoreInitialized (const bcm2079x_dev_t* device, uint8_t* coreInitResponseParams)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    SyncEventGuard guard (gPostInitCompletedEvent);
+    HAL_NfcCoreInitialized (coreInitResponseParams);
+    gPostInitCompletedEvent.wait ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiWrite (const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data)
+{
+    ALOGD ("%s: enter; len=%u", __FUNCTION__, dataLen);
+    int retval = EACCES;
+
+    HAL_NfcWrite (dataLen, const_cast<UINT8*> (data));
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiPreDiscover (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    HAL_NfcPreDiscover ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiControlGranted (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    HAL_NfcControlGranted ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+int HaiPowerCycle (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    HAL_NfcPowerCycle ();
+    retval = 0;
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
diff --git a/halimpl/bcm2079x/adaptation/Mutex.cpp b/halimpl/bcm2079x/adaptation/Mutex.cpp
new file mode 100644
index 0000000..37e388d
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.cpp
@@ -0,0 +1,141 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a mutex for thread synchronization.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "Mutex.h"
+#include <errno.h>
+
+/*******************************************************************************
+**
+** Function:        Mutex
+**
+** Description:     Initialize member variables.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+Mutex::Mutex ()
+{
+    memset (&mMutex, 0, sizeof(mMutex));
+    int res = pthread_mutex_init (&mMutex, NULL);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::Mutex: fail init; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        ~Mutex
+**
+** Description:     Cleanup all resources.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+Mutex::~Mutex ()
+{
+    int res = pthread_mutex_destroy (&mMutex);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::~Mutex: fail destroy; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        lock
+**
+** Description:     Block the thread and try lock the mutex.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void Mutex::lock ()
+{
+    int res = pthread_mutex_lock (&mMutex);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::lock: fail lock; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        unlock
+**
+** Description:     Unlock a mutex to unblock a thread.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void Mutex::unlock ()
+{
+    int res = pthread_mutex_unlock (&mMutex);
+    if (res != 0)
+    {
+        ALOGE ("Mutex::unlock: fail unlock; error=0x%X", res);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:        tryLock
+**
+** Description:     Try to lock the mutex.
+**
+** Returns:         True if the mutex is locked.
+**
+*******************************************************************************/
+bool Mutex::tryLock ()
+{
+    int res = pthread_mutex_trylock (&mMutex);
+    if ((res != 0) && (res != EBUSY))
+    {
+        ALOGE ("Mutex::tryLock: error=0x%X", res);
+    }
+    return res == 0;
+}
+
+
+/*******************************************************************************
+**
+** Function:        nativeHandle
+**
+** Description:     Get the handle of the mutex.
+**
+** Returns:         Handle of the mutex.
+**
+*******************************************************************************/
+pthread_mutex_t* Mutex::nativeHandle ()
+{
+    return &mMutex;
+}
+
+
diff --git a/halimpl/bcm2079x/adaptation/Mutex.h b/halimpl/bcm2079x/adaptation/Mutex.h
new file mode 100644
index 0000000..5091894
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.h
@@ -0,0 +1,106 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Encapsulate a mutex for thread synchronization.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <pthread.h>
+
+
+class Mutex
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        Mutex
+    **
+    ** Description:     Initialize member variables.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    Mutex ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        ~Mutex
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~Mutex ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        lock
+    **
+    ** Description:     Block the thread and try lock the mutex.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void lock ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        unlock
+    **
+    ** Description:     Unlock a mutex to unblock a thread.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void unlock ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        tryLock
+    **
+    ** Description:     Try to lock the mutex.
+    **
+    ** Returns:         True if the mutex is locked.
+    **
+    *******************************************************************************/
+    bool tryLock ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        nativeHandle
+    **
+    ** Description:     Get the handle of the mutex.
+    **
+    ** Returns:         Handle of the mutex.
+    **
+    *******************************************************************************/
+    pthread_mutex_t* nativeHandle ();
+
+private:
+    pthread_mutex_t mMutex;
+};
+
diff --git a/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
new file mode 100644
index 0000000..e007a2e
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "gki.h"
+extern "C"
+{
+    #include "nfc_hal_nv_co.h"
+}
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_int.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string>
+
+
+//directory of HAL's non-volatile storage
+static const char* bcm_nfc_location = "/data/nfc";
+static const char* filename_prefix = "/halStorage.bin";
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfc_hal_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been read, the end of file has been detected,
+**                        or an error has occurred.
+**
+*******************************************************************************/
+void nfc_hal_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block)
+{
+    std::string fn (bcm_nfc_location);
+    char filename[256];
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    sprintf (filename, "%s%u", fn.c_str(), block);
+
+    ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
+    int fileStream = open (filename, O_RDONLY);
+    if (fileStream > 0)
+    {
+        size_t actualRead = read (fileStream, p_buf, nbytes);
+        if (actualRead > 0)
+        {
+            ALOGD ("%s: read bytes=%u", __FUNCTION__, actualRead);
+            nfc_hal_nv_ci_read (actualRead, NFC_HAL_NV_CO_OK, block);
+        }
+        else
+        {
+            ALOGE ("%s: fail to read", __FUNCTION__);
+            nfc_hal_nv_ci_read (actualRead, NFC_HAL_NV_CO_FAIL, block);
+        }
+        close (fileStream);
+    }
+    else
+    {
+        ALOGD ("%s: fail to open", __FUNCTION__);
+        nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfc_hal_nv_ci_write () is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block)
+{
+    std::string fn (bcm_nfc_location);
+    char filename[256];
+    int fileStream = 0;
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    sprintf (filename, "%s%u", fn.c_str(), block);
+    ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
+
+    fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (fileStream > 0)
+    {
+        size_t actualWritten = write (fileStream, p_buf, nbytes);
+        ALOGD ("%s: %d bytes written", __FUNCTION__, actualWritten);
+        if (actualWritten > 0) {
+            nfc_hal_nv_ci_write (NFC_HAL_NV_CO_OK);
+        }
+        else
+        {
+            ALOGE ("%s: fail to write", __FUNCTION__);
+            nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
+        }
+        close (fileStream);
+    }
+    else
+    {
+        ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
+        nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
+    }
+}
diff --git a/halimpl/bcm2079x/adaptation/OverrideLog.cpp b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
new file mode 100644
index 0000000..fc41b4f
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the ALOGD(), ALOGE(), and other logging macros from
+ *  /system/core/include/cutils/log.h
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include <cutils/properties.h>
+#include "config.h"
+#define LOG_TAG "NfcNciHal"
+
+
+unsigned char appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+
+
+/*******************************************************************************
+**
+** Function:        InitializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from
+**                  Android property nfc.app_log_level.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3        * API traces
+**                  BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char InitializeGlobalAppLogLevel ()
+{
+    unsigned long num = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    GetNumValue (NAME_APPL_TRACE_LEVEL, &num, sizeof(num));
+    appl_trace_level = (unsigned char) num;
+    
+    int len = property_get ("nfc.app_log_level", valueStr, "");
+    if (len > 0)
+    {
+        //let Android property override default value
+        sscanf (valueStr, "%lu", &num);
+        appl_trace_level = (unsigned char) num;
+    }
+
+    //0xFF is a special value used by the stack to query the current
+    //trace level; it does not change any trace level
+    if (appl_trace_level == 0xFF)
+        appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+    ALOGD ("%s: level=%u", __FUNCTION__, appl_trace_level);
+    return appl_trace_level;
+}
diff --git a/halimpl/bcm2079x/adaptation/SyncEvent.h b/halimpl/bcm2079x/adaptation/SyncEvent.h
new file mode 100644
index 0000000..2a56aca
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/SyncEvent.h
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Synchronize two or more threads using a condition variable and a mutex.
+ *
+ ******************************************************************************/
+#pragma once
+#include "CondVar.h"
+#include "Mutex.h"
+
+
+class SyncEvent
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        ~SyncEvent
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~SyncEvent ()
+    {
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        start
+    **
+    ** Description:     Start a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void start ()
+    {
+        mMutex.lock ();
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the thread and wait for the event to occur.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void wait ()
+    {
+        mCondVar.wait (mMutex);
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the thread and wait for the event to occur.
+    **                  millisec: Timeout in milliseconds.
+    **
+    ** Returns:         True if wait is successful; false if timeout occurs.
+    **
+    *******************************************************************************/
+    bool wait (long millisec)
+    {
+        bool retVal = mCondVar.wait (mMutex, millisec);
+        return retVal;
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        notifyOne
+    **
+    ** Description:     Notify a blocked thread that the event has occured. Unblocks it.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void notifyOne ()
+    {
+        mCondVar.notifyOne ();
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function:        end
+    **
+    ** Description:     End a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void end ()
+    {
+        mMutex.unlock ();
+    }
+
+private:
+    CondVar mCondVar;
+    Mutex mMutex;
+};
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+
+/*****************************************************************************
+**
+**  Name:           SyncEventGuard
+**
+**  Description:    Automatically start and end a synchronization event.
+**
+*****************************************************************************/
+class SyncEventGuard
+{
+public:
+    /*******************************************************************************
+    **
+    ** Function:        SyncEventGuard
+    **
+    ** Description:     Start a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    SyncEventGuard (SyncEvent& event)
+    :   mEvent (event)
+    {
+        event.start (); //automatically start operation
+    };
+
+
+    /*******************************************************************************
+    **
+    ** Function:        ~SyncEventGuard
+    **
+    ** Description:     End a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~SyncEventGuard ()
+    {
+        mEvent.end (); //automatically end operation
+    };
+
+private:
+    SyncEvent& mEvent;
+};
+
diff --git a/halimpl/bcm2079x/adaptation/android_logmsg.cpp b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
new file mode 100644
index 0000000..ec092f7
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+extern "C"
+{
+    #include "nfc_hal_target.h"
+}
+#include <cutils/log.h>
+
+
+#ifndef BTE_LOG_BUF_SIZE
+    #define BTE_LOG_BUF_SIZE  1024
+#endif
+#define BTE_LOG_MAX_SIZE  (BTE_LOG_BUF_SIZE - 12)
+#define MAX_NCI_PACKET_SIZE  259
+#define MAX_LOGCAT_LINE     4096
+static char log_line[MAX_LOGCAT_LINE];
+static const char* sTable = "0123456789abcdef";
+
+extern UINT32 ScrProtocolTraceFlag;         // = SCR_PROTO_TRACE_ALL; // 0x017F;
+extern "C"
+{
+    void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+    void DispHciCmd (BT_HDR *p_buf);
+    void DispHciEvt (BT_HDR *p_buf);
+}
+
+
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+    static char buffer [BTE_LOG_BUF_SIZE];
+    va_list ap;
+    UINT32 trace_type = trace_set_mask & 0x07; //lower 3 bits contain trace type
+    int android_log_type = ANDROID_LOG_INFO;
+
+    va_start (ap, fmt_str);
+    vsnprintf (buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+    va_end (ap);
+    if (trace_type == TRACE_TYPE_ERROR)
+        android_log_type = ANDROID_LOG_ERROR;
+    __android_log_write (android_log_type, "NfcNciHal", buffer);
+}
+
+
+void DispNci (UINT8 *data, UINT16 len, BOOLEAN is_recv)
+{
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
+        return;
+
+    char line_buf[(MAX_NCI_PACKET_SIZE*2)+1];
+    int i,j;
+
+    for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
+    {
+        line_buf[j++] = sTable[(*data >> 4) & 0xf];
+        line_buf[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    line_buf[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
+}
+
+
+void DispHciCmd (BT_HDR *p_buf)
+{
+    int i,j;
+    int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+    UINT8 * data = (UINT8*) p_buf;
+    int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+    if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+        return;
+
+    if (nBytes > sizeof(log_line))
+        return;
+
+    for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
+    {
+        log_line[j++] = sTable[(*data >> 4) & 0xf];
+        log_line[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    log_line[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
+}
+
+
+void DispHciEvt (BT_HDR *p_buf)
+{
+    int i,j;
+    int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+    UINT8 * data = (UINT8*) p_buf;
+    int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+    if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+        return;
+
+    if (nBytes > sizeof(log_line))
+        return;
+
+    for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
+    {
+        log_line[j++] = sTable[(*data >> 4) & 0xf];
+        log_line[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    log_line[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
+}
diff --git a/halimpl/bcm2079x/adaptation/config.cpp b/halimpl/bcm2079x/adaptation/config.cpp
new file mode 100644
index 0000000..c96fdd2
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/config.cpp
@@ -0,0 +1,751 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+
+#define LOG_TAG "NfcNciHal"
+
+#if GENERIC_TARGET
+const char alternative_config_path[] = "/data/nfc/";
+#else
+const char alternative_config_path[] = "";
+#endif
+
+const char transport_config_path[] = "/etc/";
+
+#define config_name             "libnfc-brcm.conf"
+#define extra_config_base       "libnfc-brcm-"
+#define extra_config_ext        ".conf"
+#define     IsStringValue       0x80000000
+
+using namespace::std;
+
+class CNfcParam : public string
+{
+public:
+    CNfcParam();
+    CNfcParam(const char* name, const string& value);
+    CNfcParam(const char* name, unsigned long value);
+    virtual ~CNfcParam();
+    unsigned long numValue() const {return m_numValue;}
+    const char*   str_value() const {return m_str_value.c_str();}
+    size_t        str_len() const   {return m_str_value.length();}
+private:
+    string          m_str_value;
+    unsigned long   m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*>
+{
+public:
+    virtual ~CNfcConfig();
+    static CNfcConfig& GetInstance();
+    friend void readOptionalConfig(const char* optional);
+
+    bool    getValue(const char* name, char* pValue, size_t len) const;
+    bool    getValue(const char* name, unsigned long& rValue) const;
+    bool    getValue(const char* name, unsigned short & rValue) const;
+    const CNfcParam*    find(const char* p_name) const;
+    void    clean();
+private:
+    CNfcConfig();
+    bool    readConfig(const char* name, bool bResetContent);
+    void    moveFromList();
+    void    moveToList();
+    void    add(const CNfcParam* pParam);
+    list<const CNfcParam*> m_list;
+    bool    mValidFile;
+
+    unsigned long   state;
+
+    inline bool Is(unsigned long f) {return (state & f) == f;}
+    inline void Set(unsigned long f) {state |= f;}
+    inline void Reset(unsigned long f) {state &= ~f;}
+};
+
+/*******************************************************************************
+**
+** Function:    isPrintable()
+**
+** Description: detremine if a char is printable
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isPrintable(char c)
+{
+    return  (c >= 'A' && c <= 'Z') ||
+            (c >= 'a' && c <= 'z') ||
+            (c >= '0' && c <= '9') ||
+            c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function:    isDigit()
+**
+** Description: detremine if a char is numeral digit
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return true;
+    if (base == 16)
+    {
+        if (('A' <= c && c <= 'F') ||
+            ('a' <= c && c <= 'f') )
+            return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    getDigitValue()
+**
+** Description: return numercal value of a char
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return c - '0';
+    if (base == 16)
+    {
+        if ('A' <= c && c <= 'F')
+            return c - 'A' + 10;
+        else if ('a' <= c && c <= 'f')
+            return c - 'a' + 10;
+    }
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+**              move the element from linked list to a array at the end
+**
+** Returns:     none
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent)
+{
+    enum {
+        BEGIN_LINE = 1,
+        TOKEN,
+        STR_VALUE,
+        NUM_VALUE,
+        BEGIN_HEX,
+        BEGIN_QUOTE,
+        END_LINE
+    };
+
+    FILE*   fd = NULL;
+    string  token;
+    string  strValue;
+    unsigned long    numValue = 0;
+    CNfcParam* pParam = NULL;
+    int     i = 0;
+    int     base = 0;
+    char    c = 0;
+
+    state = BEGIN_LINE;
+    /* open config file, read it into a buffer */
+    if ((fd = fopen(name, "rb")) == NULL)
+    {
+        ALOGD("%s Cannot open config file %s\n", __func__, name);
+        if (bResetContent)
+        {
+            ALOGD("%s Using default value for all settings\n", __func__);
+        mValidFile = false;
+        }
+        return false;
+    }
+    ALOGD("%s Opened %s config %s\n", __func__, (bResetContent ? "base" : "optional"), name);
+
+    mValidFile = true;
+    if (size() > 0)
+    {
+        if (bResetContent)
+        clean();
+        else
+            moveToList();
+    }
+
+    while (!feof(fd) && fread(&c, 1, 1, fd) == 1)
+    {
+        switch (state & 0xff)
+        {
+        case BEGIN_LINE:
+            if (c == '#')
+                state = END_LINE;
+            else if (isPrintable(c))
+            {
+                i = 0;
+                token.erase();
+                strValue.erase();
+                state = TOKEN;
+                token.push_back(c);
+            }
+            break;
+        case TOKEN:
+            if (c == '=')
+            {
+                token.push_back('\0');
+                state = BEGIN_QUOTE;
+            }
+            else if (isPrintable(c))
+                token.push_back(c);
+            else
+                state = END_LINE;
+            break;
+        case BEGIN_QUOTE:
+            if (c == '"')
+            {
+                state = STR_VALUE;
+                base = 0;
+            }
+            else if (c == '0')
+                state = BEGIN_HEX;
+            else if (isDigit(c, 10))
+            {
+                state = NUM_VALUE;
+                base = 10;
+                numValue = getDigitValue(c, base);
+                i = 0;
+            }
+            else if (c == '{')
+            {
+                state = NUM_VALUE;
+                base = 16;
+                i = 0;
+                Set(IsStringValue);
+            }
+            else
+                state = END_LINE;
+            break;
+        case BEGIN_HEX:
+            if (c == 'x' || c == 'X')
+            {
+                state = NUM_VALUE;
+                base = 16;
+                numValue = 0;
+                i = 0;
+                break;
+            }
+            else if (isDigit(c, 10))
+            {
+                state = NUM_VALUE;
+                base = 10;
+                numValue = getDigitValue(c, base);
+                break;
+            }
+            else if (c != '\n' && c != '\r')
+            {
+                state = END_LINE;
+                break;
+            }
+            // fal through to numValue to handle numValue
+
+        case NUM_VALUE:
+            if (isDigit(c, base))
+            {
+                numValue *= base;
+                numValue += getDigitValue(c, base);
+                ++i;
+            }
+            else if (base == 16 && (c == ':' || c == '-' || c == ' ' || c == '}'))
+            {
+                if (i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                    {
+                        unsigned char c = (numValue >> (n * 8))  & 0xFF;
+                        strValue.push_back(c);
+                    }
+                }
+                Set(IsStringValue);
+                numValue = 0;
+                i = 0;
+            }
+            else
+            {
+                if (c == '\n' || c == '\r')
+                    state = BEGIN_LINE;
+                else
+                    state = END_LINE;
+                if (Is(IsStringValue) && base == 16 && i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                        strValue.push_back(((numValue >> (n * 8))  & 0xFF));
+                }
+                if (strValue.length() > 0)
+                    pParam = new CNfcParam(token.c_str(), strValue);
+                else
+                    pParam = new CNfcParam(token.c_str(), numValue);
+                add(pParam);
+                strValue.erase();
+                numValue = 0;
+            }
+            break;
+        case STR_VALUE:
+            if (c == '"')
+            {
+                strValue.push_back('\0');
+                state = END_LINE;
+                pParam = new CNfcParam(token.c_str(), strValue);
+                add(pParam);
+            }
+            else if (isPrintable(c))
+                strValue.push_back(c);
+            break;
+        case END_LINE:
+            if (c == '\n' || c == '\r')
+                state = BEGIN_LINE;
+            break;
+        default:
+            break;
+        }
+    }
+
+    fclose(fd);
+
+    moveFromList();
+    return size() > 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::CNfcConfig()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::CNfcConfig() :
+    mValidFile(true)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance()
+{
+    static CNfcConfig theInstance;
+
+    if (theInstance.size() == 0 && theInstance.mValidFile)
+    {
+        string strPath;
+        if (alternative_config_path[0] != '\0')
+        {
+            strPath.assign(alternative_config_path);
+            strPath += config_name;
+            theInstance.readConfig(strPath.c_str(), true);
+            if (!theInstance.empty())
+            {
+                return theInstance;
+        }
+        }
+        strPath.assign(transport_config_path);
+        strPath += config_name;
+        theInstance.readConfig(strPath.c_str(), true);
+    }
+
+    return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() > 0)
+    {
+        memset(pValue, 0, len);
+        memcpy(pValue, pParam->str_value(), pParam->str_len());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a long numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() == 0)
+    {
+        rValue = static_cast<unsigned long>(pParam->numValue());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a short numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() == 0)
+    {
+        rValue = static_cast<unsigned short>(pParam->numValue());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::find()
+**
+** Description: search if a setting exist in the setting array
+**
+** Returns:     pointer to the setting object
+**
+*******************************************************************************/
+const CNfcParam* CNfcConfig::find(const char* p_name) const
+{
+    if (size() == 0)
+        return NULL;
+
+    for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+    {
+        if (**it < p_name)
+            continue;
+        else if (**it == p_name)
+        {
+            if((*it)->str_len() > 0)
+                ALOGD("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+            else
+                ALOGD("%s found %s=(0x%lX)\n", __func__, p_name, (*it)->numValue());
+            return *it;
+        }
+        else
+            break;
+    }
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::clean()
+**
+** Description: reset the setting array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::clean()
+{
+    if (size() == 0)
+        return;
+
+    for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+        delete *it;
+    clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::Add()
+**
+** Description: add a setting object to the list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::add(const CNfcParam* pParam)
+{
+    if (m_list.size() == 0)
+    {
+        m_list.push_back(pParam);
+        return;
+    }
+    for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+    {
+        if (**it < pParam->c_str())
+            continue;
+        m_list.insert(it, pParam);
+        return;
+    }
+    m_list.push_back(pParam);
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList()
+{
+    if (m_list.size() == 0)
+        return;
+
+    for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+        push_back(*it);
+    m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList()
+{
+    if (m_list.size() != 0)
+        m_list.clear();
+
+    for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+        m_list.push_back(*it);
+    clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam() :
+    m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::~CNfcParam()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::~CNfcParam()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name,  const string& value) :
+    string(name),
+    m_str_value(value),
+    m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name,  unsigned long value) :
+    string(name),
+    m_numValue(value)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    GetStrValue
+**
+** Description: API function for getting a string value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetStrValue(const char* name, char* pValue, unsigned long len)
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    return rConfig.getValue(name, pValue, len);
+}
+
+/*******************************************************************************
+**
+** Function:    GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetNumValue(const char* name, void* pValue, unsigned long len)
+{
+    if (!pValue)
+        return false;
+
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+    const CNfcParam* pParam = rConfig.find(name);
+
+    if (pParam == NULL)
+        return false;
+    unsigned long v = pParam->numValue();
+    if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4)
+    {
+        const unsigned char* p = (const unsigned char*)pParam->str_value();
+        for (size_t i = 0 ; i < pParam->str_len(); ++i)
+        {
+            v *= 256;
+            v += *p++;
+        }
+    }
+    switch (len)
+    {
+    case sizeof(unsigned long):
+        *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+        break;
+    case sizeof(unsigned short):
+        *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+        break;
+    case sizeof(unsigned char):
+        *(static_cast<unsigned char*> (pValue)) = (unsigned char)v;
+        break;
+    default:
+        return false;
+    }
+    return true;
+}
+
+/*******************************************************************************
+**
+** Function:    resetConfig
+**
+** Description: reset settings array
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern void resetConfig()
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function:    readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra)
+{
+    string strPath;
+    strPath.assign(transport_config_path);
+    if (alternative_config_path[0] != '\0')
+        strPath.assign(alternative_config_path);
+
+    strPath += extra_config_base;
+    strPath += extra;
+    strPath += extra_config_ext;
+    CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
diff --git a/halimpl/bcm2079x/adaptation/patchram.cpp b/halimpl/bcm2079x/adaptation/patchram.cpp
new file mode 100644
index 0000000..273de90
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/patchram.cpp
@@ -0,0 +1,501 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+extern "C"
+{
+    #include "nfc_hal_post_reset.h"
+}
+#include <string>
+#include "spdhelper.h"
+
+#define LOG_TAG "NfcNciHal"
+
+/* Location of patchfiles */
+#ifndef NFCA_PATCHFILE_LOCATION
+#define NFCA_PATCHFILE_LOCATION ("/system/vendor/firmware/")
+#endif
+
+#define FW_PRE_PATCH                        "FW_PRE_PATCH"
+#define FW_PATCH                            "FW_PATCH"
+#define NFA_CONFIG_FORMAT                   "NFA_CONFIG_FORMAT"
+#define MAX_RF_DATA_CREDITS                 "MAX_RF_DATA_CREDITS"
+
+#define MAX_BUFFER      (512)
+static char sPrePatchFn[MAX_BUFFER+1];
+static char sPatchFn[MAX_BUFFER+1];
+static void * sPrmBuf = NULL;
+static void * sI2cFixPrmBuf = NULL;
+
+#define NFA_DM_START_UP_CFG_PARAM_MAX_LEN   100
+static UINT8 nfa_dm_start_up_cfg[NFA_DM_START_UP_CFG_PARAM_MAX_LEN];
+extern UINT8 *p_nfc_hal_dm_start_up_cfg;
+static UINT8 nfa_dm_start_up_vsc_cfg[NFA_DM_START_UP_CFG_PARAM_MAX_LEN];
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg;
+extern UINT8 *p_nfc_hal_dm_lptd_cfg;
+static UINT8 nfa_dm_lptd_cfg[LPTD_PARAM_LEN];
+extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg;
+extern BOOLEAN nfc_hal_prm_nvm_required; //true: don't download firmware if controller cannot detect EERPOM
+static void HalNciCallback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+
+tNFC_POST_RESET_CB nfc_post_reset_cb =
+{
+    "/vendor/firmware/bcm2079x_firmware.ncd",
+    NULL,
+    "/vendor/firmware/bcm2079x_pre_firmware.ncd",
+    NULL,
+    NFC_HAL_DEFAULT_BAUD,
+
+    {0, 0},                     /* tBRCM_DEV_INIT_CONFIG dev_init_config */
+
+    NFC_HAL_LP_SNOOZE_MODE_NONE,    /* Snooze Mode          */
+    NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host  */
+    NFC_HAL_LP_IDLE_THRESHOLD_HC,   /* Idle Threshold HC    */
+    NFC_HAL_LP_ACTIVE_LOW,          /* NFC_WAKE Active Mode */
+    NFC_HAL_LP_ACTIVE_HIGH          /* DH_WAKE Active Mode  */
+};
+
+
+/*******************************************************************************
+**
+** Function         getFileLength
+**
+** Description      return the size of a file
+**
+** Returns          file size in number of bytes
+**
+*******************************************************************************/
+static long getFileLength(FILE* fp)
+{
+    long sz;
+    fseek(fp, 0L, SEEK_END);
+    sz = ftell(fp);
+    fseek(fp, 0L, SEEK_SET);
+
+    return sz;
+}
+
+/*******************************************************************************
+**
+** Function         isFileExist
+**
+** Description      Check if file name exists (android does not support fexists)
+**
+** Returns          TRUE if file exists
+**
+*******************************************************************************/
+static BOOLEAN isFileExist(const char *pFilename)
+{
+    FILE *pf;
+
+    if ((pf = fopen(pFilename, "r")) != NULL)
+    {
+        fclose(pf);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         findPatchramFile
+**
+** Description      Find the patchram file name specified in the .conf
+**
+** Returns          pointer to the file name
+**
+*******************************************************************************/
+static const char* findPatchramFile(const char * pConfigName, char * pBuffer, int bufferLen)
+{
+    ALOGD("%s: config=%s", __FUNCTION__, pConfigName);
+
+    if (pConfigName == NULL)
+    {
+        ALOGD("%s No patchfile defined\n", __FUNCTION__);
+        return NULL;
+    }
+
+    if (GetStrValue(pConfigName, &pBuffer[0], bufferLen))
+    {
+        ALOGD("%s found patchfile %s\n", __FUNCTION__, pBuffer);
+        return (pBuffer[0] == '\0') ? NULL : pBuffer;
+    }
+
+    ALOGD("%s Cannot find patchfile '%s'\n", __FUNCTION__, pConfigName);
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    continueAfterSetSnoozeMode
+**
+** Description: Called after Snooze Mode is enabled.
+**
+** Returns:     none
+**
+*******************************************************************************/
+static void continueAfterSetSnoozeMode(tHAL_NFC_STATUS status)
+{
+    ALOGD("%s: status=%u", __FUNCTION__, status);
+    if (status == NCI_STATUS_OK)
+        HAL_NfcPreInitDone (HAL_NFC_STATUS_OK);
+    else
+        HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function:    postDownloadPatchram
+**
+** Description: Called after patch download
+**
+** Returns:     none
+**
+*******************************************************************************/
+static void postDownloadPatchram(tHAL_NFC_STATUS status)
+{
+    ALOGD("%s: status=%i", __FUNCTION__, status);
+
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        ALOGE("Patch download failed");
+        if (status == HAL_NFC_STATUS_REFUSED)
+        {
+            SpdHelper::setPatchAsBad();
+        }
+        else
+            SpdHelper::incErrorCount();
+
+        /* If in SPD Debug mode, fail immediately and obviously */
+        if (SpdHelper::isSpdDebug())
+            HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+        else
+        {
+            /* otherwise, power cycle the chip and let the stack startup normally */
+            USERIAL_PowerupDevice(0);
+            HAL_NfcPreInitDone (HAL_NFC_STATUS_OK);
+        }
+    }
+    /* Set snooze mode here */
+    else if (gSnoozeModeCfg.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+    {
+        status = HAL_NfcSetSnoozeMode(gSnoozeModeCfg.snooze_mode,
+                                       gSnoozeModeCfg.idle_threshold_dh,
+                                       gSnoozeModeCfg.idle_threshold_nfcc,
+                                       gSnoozeModeCfg.nfc_wake_active_mode,
+                                       gSnoozeModeCfg.dh_wake_active_mode,
+                                       continueAfterSetSnoozeMode);
+        if (status != NCI_STATUS_OK)
+        {
+            ALOGE("%s: Setting snooze mode failed, status=%i", __FUNCTION__, status);
+            HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
+        }
+    }
+    else
+    {
+        ALOGD("%s: Not using Snooze Mode", __FUNCTION__);
+        HAL_NfcPreInitDone(HAL_NFC_STATUS_OK);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:    prmCallback
+**
+** Description: Patchram callback (for static patchram mode)
+**
+** Returns:     none
+**
+*******************************************************************************/
+void prmCallback(UINT8 event)
+{
+    ALOGD("%s: event=0x%x", __FUNCTION__, event);
+    switch (event)
+    {
+    case NFC_HAL_PRM_CONTINUE_EVT:
+        /* This event does not occur if static patchram buf is used */
+        break;
+
+    case NFC_HAL_PRM_COMPLETE_EVT:
+        postDownloadPatchram(HAL_NFC_STATUS_OK);
+        break;
+
+    case NFC_HAL_PRM_ABORT_EVT:
+        postDownloadPatchram(HAL_NFC_STATUS_FAILED);
+        break;
+
+    case NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT:
+        ALOGD("%s: invalid patch...skipping patch download", __FUNCTION__);
+        postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
+        break;
+
+    case NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT:
+        ALOGD("%s: patch authentication failed", __FUNCTION__);
+        postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
+        break;
+
+    case NFC_HAL_PRM_ABORT_NO_NVM_EVT:
+        ALOGD("%s: No NVM detected", __FUNCTION__);
+        HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
+        break;
+
+    default:
+        ALOGD("%s: not handled event=0x%x", __FUNCTION__, event);
+        break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         getNfaValues
+**
+** Description      Get configuration values needed by NFA layer
+**
+** Returns:         None
+**
+*******************************************************************************/
+static void getNfaValues()
+{
+    unsigned long num;
+
+    if ( GetStrValue ( NAME_NFA_DM_START_UP_CFG, (char*)nfa_dm_start_up_cfg, sizeof ( nfa_dm_start_up_cfg ) ) )
+    {
+        p_nfc_hal_dm_start_up_cfg = &nfa_dm_start_up_cfg[0];
+        ALOGD ( "START_UP_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                                                            nfa_dm_start_up_cfg[0],
+                                                                            nfa_dm_start_up_cfg[1],
+                                                                            nfa_dm_start_up_cfg[2],
+                                                                            nfa_dm_start_up_cfg[3],
+                                                                            nfa_dm_start_up_cfg[4],
+                                                                            nfa_dm_start_up_cfg[5],
+                                                                            nfa_dm_start_up_cfg[6],
+                                                                            nfa_dm_start_up_cfg[7] );
+    }
+    if ( GetStrValue ( NAME_NFA_DM_START_UP_VSC_CFG, (char*)nfa_dm_start_up_vsc_cfg, sizeof (nfa_dm_start_up_vsc_cfg) ) )
+    {
+        p_nfc_hal_dm_start_up_vsc_cfg = &nfa_dm_start_up_vsc_cfg[0];
+        ALOGD ( "START_UP_VSC_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+                                                                            nfa_dm_start_up_vsc_cfg[0],
+                                                                            nfa_dm_start_up_vsc_cfg[1],
+                                                                            nfa_dm_start_up_vsc_cfg[2],
+                                                                            nfa_dm_start_up_vsc_cfg[3],
+                                                                            nfa_dm_start_up_vsc_cfg[4],
+                                                                            nfa_dm_start_up_vsc_cfg[5],
+                                                                            nfa_dm_start_up_vsc_cfg[6],
+                                                                            nfa_dm_start_up_vsc_cfg[7] );
+    }
+    if ( GetStrValue ( NAME_LPTD_CFG, (char*)&nfa_dm_lptd_cfg[0], sizeof( nfa_dm_lptd_cfg ) ) )
+        p_nfc_hal_dm_lptd_cfg = &nfa_dm_lptd_cfg[0];
+}
+
+/*******************************************************************************
+**
+** Function         StartPatchDownload
+**
+** Description      Reads configuration settings, and begins the download
+**                  process if patch files are configured.
+**
+** Returns:         None
+**
+*******************************************************************************/
+static void StartPatchDownload(UINT32 chipid)
+{
+    ALOGD ("%s: chipid=%lx",__FUNCTION__, chipid);
+
+    char chipID[30];
+    sprintf(chipID, "%lx", chipid);
+    ALOGD ("%s: chidId=%s", __FUNCTION__, chipID);
+
+    readOptionalConfig(chipID);     // Read optional chip specific settings
+    readOptionalConfig("fime");     // Read optional FIME specific settings
+    getNfaValues();                 // Get NFA configuration values into variables
+
+
+    findPatchramFile(FW_PATCH, sPatchFn, sizeof(sPatchFn));
+    findPatchramFile(FW_PRE_PATCH, sPrePatchFn, sizeof(sPatchFn));
+
+    {
+        FILE *fd;
+        /* If an I2C fix patch file was specified, then tell the stack about it */
+        if (sPrePatchFn[0] != '\0')
+        {
+            if ((fd = fopen(sPrePatchFn, "rb")) != NULL)
+            {
+                UINT32 lenPrmBuffer = getFileLength(fd);
+
+                if ((sI2cFixPrmBuf = malloc(lenPrmBuffer)) != NULL)
+                {
+                    fread(sI2cFixPrmBuf, lenPrmBuffer, 1, fd);
+
+                    ALOGD("%s Setting I2C fix to %s (size: %lu)", __FUNCTION__, sPrePatchFn, lenPrmBuffer);
+                    HAL_NfcPrmSetI2cPatch((UINT8*)sI2cFixPrmBuf, (UINT16)lenPrmBuffer, 0);
+                }
+                else
+                {
+                    ALOGE("%s Unable to get buffer to i2c fix (%lu bytes)", __FUNCTION__, lenPrmBuffer);
+                }
+
+                fclose(fd);
+            }
+            else
+            {
+                ALOGE("%s Unable to open i2c fix patchfile %s", __FUNCTION__, sPrePatchFn);
+            }
+        }
+    }
+
+    {
+        FILE *fd;
+
+        /* If a patch file was specified, then download it now */
+        if (sPatchFn[0] != '\0')
+        {
+            UINT32 bDownloadStarted = false;
+
+            /* open patchfile, read it into a buffer */
+            if ((fd = fopen(sPatchFn, "rb")) != NULL)
+            {
+                UINT32 lenPrmBuffer = getFileLength(fd);
+                tNFC_HAL_PRM_FORMAT patch_format = NFC_HAL_PRM_FORMAT_NCD;
+
+                GetNumValue((char*)NFA_CONFIG_FORMAT, &patch_format, sizeof(patch_format));
+
+                ALOGD("%s Downloading patchfile %s (size: %lu) format=%u", __FUNCTION__, sPatchFn, lenPrmBuffer, patch_format);
+                if ((sPrmBuf = malloc(lenPrmBuffer)) != NULL)
+                {
+                    fread(sPrmBuf, lenPrmBuffer, 1, fd);
+
+                    if (!SpdHelper::isPatchBad((UINT8*)sPrmBuf, lenPrmBuffer))
+                    {
+                        /* Download patch using static memeory mode */
+                        HAL_NfcPrmDownloadStart(patch_format, 0, (UINT8*)sPrmBuf, lenPrmBuffer, 0, prmCallback);
+                        bDownloadStarted = true;
+                    }
+                }
+                else
+                    ALOGE("%s Unable to buffer to hold patchram (%lu bytes)", __FUNCTION__, lenPrmBuffer);
+
+                fclose(fd);
+            }
+            else
+                ALOGE("%s Unable to open patchfile %s", __FUNCTION__, sPatchFn);
+
+            /* If the download never got started */
+            if (!bDownloadStarted)
+            {
+                /* If debug mode, fail in an obvious way, otherwise try to start stack */
+                postDownloadPatchram(SpdHelper::isSpdDebug() ? HAL_NFC_STATUS_FAILED :
+                        HAL_NFC_STATUS_OK);
+            }
+        }
+        else
+        {
+            ALOGE("%s: No patchfile specified or disabled. Proceeding to post-download procedure...", __FUNCTION__);
+            postDownloadPatchram(HAL_NFC_STATUS_OK);
+        }
+    }
+
+    ALOGD ("%s: exit", __FUNCTION__);
+}
+
+/*******************************************************************************
+**
+** Function:    nfc_hal_post_reset_init
+**
+** Description: Called by the NFC HAL after controller has been reset.
+**              Begin to download firmware patch files.
+**
+** Returns:     none
+**
+*******************************************************************************/
+void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type)
+{
+    ALOGD("%s: brcm_hw_id=0x%x, nvm_type=%d", __FUNCTION__, brcm_hw_id, nvm_type);
+    tHAL_NFC_STATUS stat = HAL_NFC_STATUS_FAILED;
+    UINT8 max_credits = 1;
+
+    if (nvm_type == NCI_SPD_NVM_TYPE_NONE)
+    {
+        ALOGD("%s: No NVM detected, FAIL the init stage to force a retry", __FUNCTION__);
+        USERIAL_PowerupDevice (0);
+        stat = HAL_NfcReInit (HalNciCallback);
+    }
+    else
+    {
+        /* Start downloading the patch files */
+        StartPatchDownload(brcm_hw_id);
+
+        if (GetNumValue(MAX_RF_DATA_CREDITS, &max_credits, sizeof(max_credits)) && (max_credits > 0))
+        {
+            ALOGD("%s : max_credits=%d", __FUNCTION__, max_credits);
+            HAL_NfcSetMaxRfDataCredits(max_credits);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:    HalNciCallback
+**
+** Description: Determine whether controller has detected EEPROM.
+**
+** Returns:     none
+**
+*******************************************************************************/
+void HalNciCallback (tNFC_HAL_NCI_EVT event, UINT16 dataLen, UINT8* data)
+{
+    ALOGD ("%s: enter; event=%X; data len=%u", __FUNCTION__, event, dataLen);
+    if (event == NFC_VS_GET_PATCH_VERSION_EVT)
+    {
+        if (dataLen <= NCI_GET_PATCH_VERSION_NVM_OFFSET)
+        {
+            ALOGE("%s: response too short to detect NVM type", __FUNCTION__);
+            HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+        }
+        else
+        {
+            UINT8 nvramType = *(data + NCI_GET_PATCH_VERSION_NVM_OFFSET);
+            if (nvramType == NCI_SPD_NVM_TYPE_NONE)
+            {
+                //controller did not find EEPROM, so re-initialize
+                ALOGD("%s: no nvram, try again", __FUNCTION__);
+                USERIAL_PowerupDevice (0);
+                HAL_NfcReInit (HalNciCallback);
+            }
+            else
+            {
+                UINT8 max_credits = 1;
+                ALOGD("%s: found nvram", __FUNCTION__, nvramType);
+                if (GetNumValue(MAX_RF_DATA_CREDITS, &max_credits, sizeof(max_credits)) && (max_credits > 0))
+                {
+                    ALOGD("%s : max_credits=%d", __FUNCTION__, max_credits);
+                    HAL_NfcSetMaxRfDataCredits(max_credits);
+                }
+                HAL_NfcPreInitDone (HAL_NFC_STATUS_OK);
+            }
+        }
+    }
+    ALOGD("%s: exit", __FUNCTION__);
+}
+
diff --git a/halimpl/bcm2079x/adaptation/spdhelper.cpp b/halimpl/bcm2079x/adaptation/spdhelper.cpp
new file mode 100644
index 0000000..00e9567
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/spdhelper.cpp
@@ -0,0 +1,88 @@
+#include "OverrideLog.h"
+#include "spdhelper.h"
+#include "config.h"
+
+void SpdHelper::setPatchAsBad()
+{
+    getInstance().setPatchAsBadImpl();
+}
+
+void SpdHelper::incErrorCount()
+{
+    getInstance().incErrorCountImpl();
+}
+
+bool SpdHelper::isPatchBad(UINT8* prm, UINT32 len)
+{
+    return getInstance().isPatchBadImpl(prm, len);
+}
+
+bool SpdHelper::isSpdDebug()
+{
+    bool b = getInstance().isSpdDebugImpl();
+    ALOGD("%s SpdDebug is %s", __func__, (b ? "TRUE" : "FALSE"));
+    return b;
+}
+
+void SpdHelper::incErrorCountImpl()
+{
+    if (++mErrorCount >= mMaxErrorCount)
+    {
+        setPatchAsBadImpl();
+    }
+}
+
+void SpdHelper::setPatchAsBadImpl()
+{
+    mIsPatchBad = true;
+}
+
+inline const char * toHex(UINT8 b)
+{
+    static char hex[] = "0123456789ABCDEF";
+    static char c[3];
+    c[0] = hex[((b >> 4) & 0x0F)];
+    c[1] = hex[((b >> 0) & 0x0F)];
+    c[2] = '\0';
+    return &c[0];
+}
+
+bool SpdHelper::isPatchBadImpl(UINT8* prm, UINT32 len)
+{
+    string strNew;
+
+    // Get the patch ID from the prm data.
+    for (int i = 0; i < 8 && i < len; ++i)
+        strNew.append(toHex(*prm++));
+
+    // If it is not the same patch as before, then reset things.
+    if ( strNew != mPatchId )
+    {
+        mPatchId = strNew;
+        mErrorCount = 0;
+        mIsPatchBad = false;
+    }
+
+    // Otherwise the 'mIsPatchBad' will tell if its bad or not.
+    ALOGD("%s '%s' (%d) is %sa known bad patch file", __func__, mPatchId.c_str(), mErrorCount, (mIsPatchBad ? "" : "not "));
+
+    return mIsPatchBad;
+}
+
+SpdHelper& SpdHelper::getInstance()
+{
+    static SpdHelper* theInstance = NULL;
+    if (theInstance == NULL)
+        theInstance= new SpdHelper;
+    return *theInstance;
+}
+
+SpdHelper::SpdHelper()
+{
+    mErrorCount = 0;
+    mPatchId.erase();
+    if(!GetNumValue((char*)NAME_SPD_MAXRETRYCOUNT, &mMaxErrorCount, sizeof(mMaxErrorCount)))
+        mMaxErrorCount = DEFAULT_SPD_MAXRETRYCOUNT;
+    if (!GetNumValue((char*)NAME_SPD_DEBUG, &mSpdDebug, sizeof(mSpdDebug)))
+        mSpdDebug = false;
+}
diff --git a/halimpl/bcm2079x/adaptation/userial_linux.c b/halimpl/bcm2079x/adaptation/userial_linux.c
new file mode 100755
index 0000000..ebecf95
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/userial_linux.c
@@ -0,0 +1,1599 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include "OverrideLog.h"
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+#include "nfc_target.h"
+
+#include <pthread.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <gki_int.h>
+#include "hcidefs.h"
+#include <poll.h>
+#include "upio.h"
+#include "bcm2079x.h"
+#include "config.h"
+
+#define HCISU_EVT                           EVENT_MASK(APPL_EVT_0)
+#define MAX_ERROR                           10
+#define default_transport                   "/dev/bcm2079x"
+
+#define NUM_RESET_ATTEMPTS                  5
+
+#ifndef BTE_APPL_MAX_USERIAL_DEV_NAME
+#define BTE_APPL_MAX_USERIAL_DEV_NAME           (256)
+#endif
+extern UINT8 appl_trace_level;
+
+/* Mapping of USERIAL_PORT_x to linux */
+extern UINT32 ScrProtocolTraceFlag;
+static tUPIO_STATE current_nfc_wake_state = UPIO_OFF;
+int uart_port  = 0;
+int isLowSpeedTransport = 0;
+int nfc_wake_delay = 0;
+int nfc_write_delay = 0;
+int gPowerOnDelay = 300;
+static int gPrePowerOffDelay = 0;    // default value
+static int gPostPowerOffDelay = 0;     // default value
+static pthread_mutex_t close_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+char userial_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+char power_control_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+tSNOOZE_MODE_CONFIG gSnoozeModeCfg = {
+    NFC_HAL_LP_SNOOZE_MODE_SPI_I2C,     /* Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) */
+    NFC_HAL_LP_IDLE_THRESHOLD_HOST,     /* Idle Threshold Host */
+    NFC_HAL_LP_IDLE_THRESHOLD_HC,       /* Idle Threshold HC */
+    NFC_HAL_LP_ACTIVE_LOW,              /* NFC Wake active mode (0=ActiveLow 1=ActiveHigh) */
+    NFC_HAL_LP_ACTIVE_HIGH              /* Host Wake active mode (0=ActiveLow 1=ActiveHigh) */
+};
+
+UINT8 bcmi2cnfc_client_addr = 0;
+UINT8 bcmi2cnfc_read_multi_packets = 0;
+
+#define USERIAL_Debug_verbose     ((ScrProtocolTraceFlag & 0x80000000) == 0x80000000)
+
+#include <sys/socket.h>
+
+#define LOG_TAG "USERIAL_LINUX"
+
+static UINT8 spi_negotiation[10] = { 0xF0, /* CMD */
+                                    0x00, /* SPI PARM Negotiation */
+                                    0x01, /* SPI Version */
+                                    0x00, /* SPI Mode:0, SPI_INT active low */
+                                    0x00, /* 8Bit, MSB first, Little Endian byte order */
+                                    0x00, /* Reserved */
+                                    0xFF, /* Sleep timeout Lower Byte */
+                                    0xFF, /* Sleep timeout Upper Byte */
+                                    0x00, /* Reserved */
+                                    0x00 /* Reserved */
+};
+static UINT8 spi_nego_res[20];
+
+#include <ctype.h>
+
+#define USING_BRCM_USB TRUE
+
+/* use tc interface to change baudrate instead of close/open sequence which can fail on some platforms
+ * due to tx line movement when opeing/closing the UART. the 43xx do not like this. */
+#ifndef USERIAL_USE_TCIO_BAUD_CHANGE
+#define USERIAL_USE_TCIO_BAUD_CHANGE FALSE
+#endif
+
+#ifndef USERIAL_USE_IO_BT_WAKE
+#define USERIAL_USE_IO_BT_WAKE FALSE
+#endif
+
+/* this are the ioctl values used for bt_wake ioctl via UART driver. you may need to redefine at for
+ * you platform! Logically they need to be unique and not colide with existing uart ioctl's.
+ */
+#ifndef USERIAL_IO_BT_WAKE_ASSERT
+#define USERIAL_IO_BT_WAKE_ASSERT   0x8003
+#endif
+#ifndef USERIAL_IO_BT_WAKE_DEASSERT
+#define USERIAL_IO_BT_WAKE_DEASSERT 0x8004
+#endif
+#ifndef USERIAL_IO_BT_WAKE_GET_ST
+#define USERIAL_IO_BT_WAKE_GET_ST   0x8005
+#endif
+
+/* the read limit in this current implementation depends on the GKI_BUF3_SIZE
+ * It would be better to use some ring buffer from the USERIAL_Read() is reading
+ * instead of putting it into GKI buffers.
+ */
+#define READ_LIMIT (USERIAL_POOL_BUF_SIZE-BT_HDR_SIZE)
+/*
+ * minimum buffer size requirement to read a full sized packet from NFCC = 255 + 4 byte header
+ */
+#define MIN_BUFSIZE 259
+#define     POLL_TIMEOUT    1000
+/* priority of the reader thread */
+#define USERIAL_READ_TRHEAD_PRIO 90
+/* time (ms) to wait before trying to allocate again a GKI buffer */
+#define NO_GKI_BUFFER_RECOVER_TIME 100
+#define MAX_SERIAL_PORT (USERIAL_PORT_15 + 1)
+
+extern void dumpbin(const char* data, int size);
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+
+static pthread_t      worker_thread1 = 0;
+
+typedef struct  {
+    volatile unsigned long bt_wake_state;
+    int             sock;
+    tUSERIAL_CBACK      *ser_cb;
+    UINT16      baud;
+    UINT8       data_bits;
+    UINT16      parity;
+    UINT8       stop_bits;
+    UINT8       port;
+    tUSERIAL_OPEN_CFG open_cfg;
+    int         sock_power_control;
+    int         client_device_address;
+    struct timespec write_time;
+} tLINUX_CB;
+
+static tLINUX_CB linux_cb;  /* case of multipel port support use array : [MAX_SERIAL_PORT] */
+
+void userial_close_thread(UINT32 params);
+
+static UINT8 device_name[20];
+static int   bSerialPortDevice = FALSE;
+static int _timeout = POLL_TIMEOUT;
+static BOOLEAN is_close_thread_is_waiting = FALSE;
+
+
+int   perf_log_every_count = 0;
+typedef struct {
+    const char* label;
+    long    lapse;
+    long    bytes;
+    long    count;
+    long    overhead;
+} tPERF_DATA;
+
+/*******************************************************************************
+**
+** Function         perf_reset
+**
+** Description      reset performance measurement data
+**
+** Returns          none
+**
+*******************************************************************************/
+void perf_reset(tPERF_DATA* t)
+{
+    t->count =
+    t->bytes =
+    t->lapse = 0;
+}
+
+/*******************************************************************************
+**
+** Function         perf_log
+**
+** Description      produce a log entry of cvurrent performance data
+**
+** Returns          none
+**
+*******************************************************************************/
+void perf_log(tPERF_DATA* t)
+{
+    // round to nearest ms
+    // t->lapse += 500;
+    // t->lapse /= 1000;
+    if (t->lapse)
+    {
+        if (t->bytes)
+            ALOGD( "%s:%s, bytes=%ld, lapse=%ld (%d.%02d kbps) (bus data rate %d.%02d kbps) overhead %d(%d percent)\n",
+                    __func__,
+                    t->label, t->bytes, t->lapse,
+                    (int)(8 * t->bytes / t->lapse), (int)(800 * t->bytes / (t->lapse)) % 100,
+                    (int)(9 * (t->bytes + t->count * t->overhead) / t->lapse), (int)(900 * (t->bytes + t->count * t->overhead) / (t->lapse)) % 100,
+                    (int)(t->count * t->overhead), (int)(t->count * t->overhead * 100 / t->bytes)
+                    );
+        else
+            ALOGD( "%s:%s, lapse=%ld (average %ld)\n", __func__,
+                    t->label, t->lapse, (int)t->lapse / t->count
+                    );
+    }
+    perf_reset(t);
+}
+
+/*******************************************************************************
+**
+** Function         perf_update
+**
+** Description      update perforamnce measurement data
+**
+** Returns          none
+**
+*******************************************************************************/
+void perf_update(tPERF_DATA* t, long lapse, long bytes)
+{
+    if (!perf_log_every_count)
+        return;
+    // round to nearest ms
+    lapse += 500;
+    lapse /= 1000;
+    t->count++;
+    t->bytes += bytes;
+    t->lapse += lapse;
+    if (t->count == perf_log_every_count)
+        perf_log(t);
+}
+
+static tPERF_DATA   perf_poll = {"USERIAL_Poll", 0, 0, 0, 0};
+static tPERF_DATA   perf_read = {"USERIAL_Read", 0, 0, 0, 9};
+static tPERF_DATA   perf_write = {"USERIAL_Write", 0, 0, 0, 3};
+static tPERF_DATA   perf_poll_2_poll = {"USERIAL_Poll_to_Poll", 0, 0, 0, 0};
+static clock_t      _poll_t0 = 0;
+
+static UINT32 userial_baud_tbl[] =
+{
+    300,        /* USERIAL_BAUD_300          0 */
+    600,        /* USERIAL_BAUD_600          1 */
+    1200,       /* USERIAL_BAUD_1200         2 */
+    2400,       /* USERIAL_BAUD_2400         3 */
+    9600,       /* USERIAL_BAUD_9600         4 */
+    19200,      /* USERIAL_BAUD_19200        5 */
+    57600,      /* USERIAL_BAUD_57600        6 */
+    115200,     /* USERIAL_BAUD_115200       7 */
+    230400,     /* USERIAL_BAUD_230400       8 */
+    460800,     /* USERIAL_BAUD_460800       9 */
+    921600,     /* USERIAL_BAUD_921600       10 */
+    1000000,    /* USERIAL_BAUD_1M           11 */
+    1500000,    /* USERIAL_BAUD_1_5M         12 */
+    2000000,    /* USERIAL_BAUD_2M           13 */
+    3000000,    /* USERIAL_BAUD_3M           14 */
+    4000000     /* USERIAL_BAUD_4M           15 */
+};
+
+/*******************************************************************************
+**
+** Function         wake_state
+**
+** Description      return current state of NFC_WAKE gpio
+**
+** Returns          GPIO value to wake NFCC
+**
+*******************************************************************************/
+static inline int wake_state()
+{
+    return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
+}
+
+/*******************************************************************************
+**
+** Function         sleep_state
+**
+** Description      return current state of NFC_WAKE gpio
+**
+** Returns          GPIO value to allow NFCC to goto sleep
+**
+*******************************************************************************/
+static inline int sleep_state()
+{
+    return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_OFF : UPIO_ON);
+}
+
+/*******************************************************************************
+**
+** Function         isWake
+**
+** Description      return current state of NFC_WAKE gpio based on the active mode setting
+**
+** Returns          asserted_state if it's awake, deasserted_state if it's allowed to sleep
+**
+*******************************************************************************/
+static inline int isWake(int state)
+{
+    int     asserted_state = ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
+    return (state != -1) ?
+        state == asserted_state :
+        current_nfc_wake_state == asserted_state;
+}
+
+/*******************************************************************************
+**
+** Function           setWriteDelay
+**
+** Description        Record a delay for the next write operation
+**
+** Input Parameter    delay in milliseconds
+**
+** Comments           use this function to register a delay before next write,
+**                    This is used in three instances: power up delay, wake delay
+**                    and write delay
+**
+*******************************************************************************/
+static void setWriteDelay(int delay)
+{
+    if (delay <= 0) {
+        // Set a minimum delay of 5ms between back-to-back writes
+        delay = 5;
+    }
+
+    clock_gettime(CLOCK_MONOTONIC, &linux_cb.write_time);
+    if (delay > 1000)
+    {
+        linux_cb.write_time.tv_sec += delay / 1000;
+        delay %= 1000;
+    }
+    unsigned long write_delay = delay * 1000 * 1000;
+    linux_cb.write_time.tv_nsec += write_delay;
+    if (linux_cb.write_time.tv_nsec > 1000*1000*1000)
+    {
+        linux_cb.write_time.tv_nsec -= 1000*1000*1000;
+        linux_cb.write_time.tv_sec++;
+    }
+}
+
+/*******************************************************************************
+**
+** Function           doWriteDelay
+**
+** Description        Execute a delay as registered in setWriteDelay()
+**
+** Output Parameter   none
+**
+** Returns            none
+**
+** Comments           This function calls GKI_Delay to execute a delay to fulfill
+**                    the delay registered earlier.
+**
+*******************************************************************************/
+static void doWriteDelay()
+{
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    long delay = 0;
+
+    if (now.tv_sec > linux_cb.write_time.tv_sec)
+        return;
+    else if (now.tv_sec == linux_cb.write_time.tv_sec)
+    {
+        if (now.tv_nsec > linux_cb.write_time.tv_nsec)
+            return;
+        delay = (linux_cb.write_time.tv_nsec - now.tv_nsec) / 1000000;
+    }
+    else
+        delay = (linux_cb.write_time.tv_sec - now.tv_sec) * 1000 + linux_cb.write_time.tv_nsec / 1000000 - now.tv_nsec / 1000000;
+
+    if (delay > 0 && delay < 1000)
+    {
+        ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "doWriteDelay() delay %ld ms", delay);
+        GKI_delay(delay);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         create_signal_fds
+**
+** Description      create a socketpair for read thread to use
+**
+** Returns          file descriptor
+**
+*******************************************************************************/
+
+static int signal_fds[2];
+static inline int create_signal_fds(struct pollfd* set)
+{
+    if (signal_fds[0] == 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0)
+    {
+        ALOGE("%s create_signal_sockets:socketpair failed, errno: %d", __func__, errno);
+        return -1;
+    }
+    set->fd = signal_fds[0];
+    return signal_fds[0];
+}
+
+/*******************************************************************************
+**
+** Function         close_signal_fds
+**
+** Description      close the socketpair
+**
+** Returns          none
+**
+*******************************************************************************/
+static inline void close_signal_fds()
+{
+    close(signal_fds[0]);
+    signal_fds[0] = 0;
+
+    close(signal_fds[1]);
+    signal_fds[1] = 0;
+}
+
+/*******************************************************************************
+**
+** Function         send_wakeup_signal
+**
+** Description      send a one byte data to the socket as signal to the read thread
+**                  for it to stop
+**
+** Returns          number of bytes sent, or error no
+**
+*******************************************************************************/
+static inline int send_wakeup_signal()
+{
+    char sig_on = 1;
+    ALOGD("%s: Sending signal to %d", __func__, signal_fds[1]);
+    return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+}
+
+/*******************************************************************************
+**
+** Function         reset_signal
+**
+** Description      read the one byte data from the socket
+**
+** Returns          received data
+**
+*******************************************************************************/
+static inline int reset_signal()
+{
+    char sig_recv = 0;
+    ALOGD("%s: Receiving signal from %d", __func__, signal_fds[0]);
+    recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+    return (int)sig_recv;
+}
+
+/*******************************************************************************
+**
+** Function         is_signaled
+**
+** Description      test if there's data waiting on the socket
+**
+** Returns          TRUE is data is available
+**
+*******************************************************************************/
+static inline int is_signaled(struct pollfd* set)
+{
+    return ((set->revents & POLLIN) == POLLIN) || ((set->revents & POLLRDNORM) == POLLRDNORM) ;
+}
+
+/******************************************************************************/
+
+typedef unsigned char uchar;
+
+BUFFER_Q Userial_in_q;
+
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetLineSpeed
+ **
+ ** Description        This function convert USERIAL baud to line speed.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud)
+{
+    return (baud <= USERIAL_BAUD_4M) ?
+            userial_baud_tbl[baud-USERIAL_BAUD_300] : 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetBaud
+ **
+ ** Description        This function convert line speed to USERIAL baud.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed)
+{
+    UINT8 i;
+    for (i = USERIAL_BAUD_300; i <= USERIAL_BAUD_921600; i++)
+    {
+        if (userial_baud_tbl[i-USERIAL_BAUD_300] == line_speed)
+            return i;
+    }
+
+    return USERIAL_BAUD_AUTO;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Init
+**
+** Description        This function initializes the  serial driver.
+**
+** Output Parameter   None
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+
+UDRV_API void    USERIAL_Init(void * p_cfg)
+{
+    ALOGI(__FUNCTION__);
+
+    memset(&linux_cb, 0, sizeof(linux_cb));
+    linux_cb.sock = -1;
+    linux_cb.ser_cb = NULL;
+    linux_cb.sock_power_control = -1;
+    linux_cb.client_device_address = 0;
+    GKI_init_q(&Userial_in_q);
+    return;
+}
+
+/*******************************************************************************
+ **
+ ** Function           my_read
+ **
+ ** Description        This function read a packet from driver.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            number of bytes in the packet or error code
+ **
+ *******************************************************************************/
+int my_read(int fd, uchar *pbuf, int len)
+{
+    struct pollfd fds[2];
+
+    int n = 0;
+    int ret = 0;
+    int count = 0;
+    int offset = 0;
+    clock_t t1, t2;
+
+    if (!isLowSpeedTransport && _timeout != POLL_TIMEOUT)
+        ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter, pbuf=%lx, len = %d\n", __func__, (unsigned long)pbuf, len);
+    memset(pbuf, 0, len);
+    /* need to use select in order to avoid collistion between read and close on same fd */
+    /* Initialize the input set */
+    fds[0].fd = fd;
+    fds[0].events = POLLIN | POLLERR | POLLRDNORM;
+    fds[0].revents = 0;
+
+    create_signal_fds(&fds[1]);
+    fds[1].events = POLLIN | POLLERR | POLLRDNORM;
+    fds[1].revents = 0;
+    t1 = clock();
+    n = poll(fds, 2, _timeout);
+    t2 = clock();
+    perf_update(&perf_poll, t2 - t1, 0);
+    if (_poll_t0)
+        perf_update(&perf_poll_2_poll, t2 - _poll_t0, 0);
+
+    _poll_t0 = t2;
+    /* See if there was an error */
+    if (n < 0)
+    {
+        ALOGD( "select failed; errno = %d\n", errno);
+        return -errno;
+    }
+    else if (n == 0)
+        return -EAGAIN;
+
+    if (is_signaled(&fds[1]))
+    {
+        ALOGD( "%s: exit signal received\n", __func__);
+        reset_signal();
+        return -1;
+    }
+    if (!bSerialPortDevice || len < MIN_BUFSIZE)
+        count = len;
+    else
+        count = 1;
+    do {
+        t2 = clock();
+        ret = read(fd, pbuf+offset, (size_t)count);
+        if (ret > 0)
+            perf_update(&perf_read, clock()-t2, ret);
+
+        if (ret <= 0 || !bSerialPortDevice || len < MIN_BUFSIZE)
+            break;
+
+        if (isLowSpeedTransport)
+            goto done;
+
+        if (offset == 0)
+        {
+            if (pbuf[offset] == HCIT_TYPE_NFC)
+                count = 3;
+            else if (pbuf[offset] == HCIT_TYPE_EVENT)
+                count = 2;
+            else
+            {
+                ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x\n", __func__, offset, pbuf[offset]);
+                break;
+            }
+            offset = 1;
+        }
+        else if (offset == 1)
+        {
+            offset += count;
+            count = pbuf[offset-1];
+        }
+        else
+        {
+            offset += ret;
+            count -= ret;
+        }
+        if (count == 0)
+        {
+            ret = offset;
+            break;
+        }
+    } while (count > 0);
+ #if VALIDATE_PACKET
+/*
+ * vallidate the packet structure
+ */
+    if (ret > 0 && len >= MIN_BUFSIZE)
+    {
+        count = 0;
+        while (count < ret)
+        {
+            if (pbuf[count] == HCIT_TYPE_NFC)
+            {
+                if (USERIAL_Debug_verbose)
+                    scru_dump_hex(pbuf+count, NULL, pbuf[count+3]+4, 0, 0);
+                count += pbuf[count+3]+4;
+            }
+            else if (pbuf[count] == HCIT_TYPE_EVENT)
+            {
+                if (USERIAL_Debug_verbose)
+                    scru_dump_hex(pbuf+count, NULL, pbuf[count+2]+3, 0, 0);
+                count += pbuf[count+2]+3;
+            }
+            else
+            {
+                ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x, remain %d bytes\n", __func__, count, pbuf[count], ret-count);
+                scru_dump_hex(pbuf+count, NULL, ret - count, 0, 0);
+                break;
+            }
+        } /* while*/
+    }
+#endif
+done:
+    if (!isLowSpeedTransport)
+        ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: return %d(0x%x) bytes, errno=%d count=%d, n=%d, timeout=%d\n", __func__,
+            ret, ret, errno, count, n, _timeout);
+    if (_timeout == POLL_TIMEOUT)
+        _timeout = -1;
+    return ret;
+}
+extern BOOLEAN gki_chk_buf_damage(void *p_buf);
+static int sRxLength = 0;
+
+/*******************************************************************************
+ **
+ ** Function           userial_read_thread
+ **
+ ** Description        entry point of read thread.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            0
+ **
+ *******************************************************************************/
+UINT32 userial_read_thread(UINT32 arg)
+{
+    int rx_length;
+    int error_count = 0;
+    int bErrorReported = 0;
+    int iMaxError = MAX_ERROR;
+    BT_HDR *p_buf = NULL;
+
+    worker_thread1 = pthread_self();
+
+    ALOGD( "start userial_read_thread, id=%lx", worker_thread1);
+    _timeout = POLL_TIMEOUT;
+
+    for (;linux_cb.sock > 0;)
+    {
+        BT_HDR *p_buf;
+        UINT8 *current_packet;
+
+        if ((p_buf = (BT_HDR *) GKI_getpoolbuf( USERIAL_POOL_ID ) )!= NULL)
+        {
+            p_buf->offset = 0;
+            p_buf->layer_specific = 0;
+
+            current_packet = (UINT8 *) (p_buf + 1);
+            rx_length = my_read(linux_cb.sock, current_packet, READ_LIMIT);
+
+        }
+        else
+        {
+            ALOGE( "userial_read_thread(): unable to get buffer from GKI p_buf = %p poolid = %d\n", p_buf, USERIAL_POOL_ID);
+            rx_length = 0;  /* paranoia setting */
+            GKI_delay( NO_GKI_BUFFER_RECOVER_TIME );
+            continue;
+        }
+        if (rx_length > 0)
+        {
+            bErrorReported = 0;
+            error_count = 0;
+            iMaxError = 3;
+            if (rx_length > sRxLength)
+                sRxLength = rx_length;
+            p_buf->len = (UINT16)rx_length;
+            GKI_enqueue(&Userial_in_q, p_buf);
+            if (!isLowSpeedTransport)
+                ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "userial_read_thread(): enqueued p_buf=%p, count=%d, length=%d\n",
+                            p_buf, Userial_in_q.count, rx_length);
+
+            if (linux_cb.ser_cb != NULL)
+                (*linux_cb.ser_cb)(linux_cb.port, USERIAL_RX_READY_EVT, (tUSERIAL_EVT_DATA *)p_buf);
+
+            GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
+        }
+        else
+        {
+            GKI_freebuf( p_buf );
+            if (rx_length == -EAGAIN)
+                continue;
+            else if (rx_length == -1)
+            {
+                ALOGD( "userial_read_thread(): exiting\n");
+                break;
+            }
+            else if (rx_length == 0 && !isWake(-1))
+                continue;
+            ++error_count;
+            if (rx_length <= 0 && ((error_count > 0) && ((error_count % iMaxError) == 0)))
+            {
+                if (bErrorReported == 0)
+                {
+                    ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d return USERIAL_ERR_EVT\n",
+                            rx_length, error_count, errno);
+                    if (linux_cb.ser_cb != NULL)
+                        (*linux_cb.ser_cb)(linux_cb.port, USERIAL_ERR_EVT, (tUSERIAL_EVT_DATA *)p_buf);
+
+                    GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
+                    ++bErrorReported;
+                }
+                if (sRxLength == 0)
+                {
+                    ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d exit read thread\n",
+                            rx_length, error_count, errno);
+                    break;
+                }
+            }
+        }
+    } /* for */
+
+    ALOGD( "userial_read_thread(): freeing GKI_buffers\n");
+    while ((p_buf = (BT_HDR *) GKI_dequeue (&Userial_in_q)) != NULL)
+    {
+        GKI_freebuf(p_buf);
+        ALOGD("userial_read_thread: dequeued buffer from Userial_in_q\n");
+    }
+
+    GKI_exit_task (GKI_get_taskid ());
+    ALOGD( "USERIAL READ: EXITING TASK\n");
+
+    return 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function           userial_to_tcio_baud
+ **
+ ** Description        helper function converts USERIAL baud rates into TCIO conforming baud rates
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            TRUE - success
+ **                    FALSE - unsupported baud rate, default of 115200 is used
+ **
+ *******************************************************************************/
+BOOLEAN userial_to_tcio_baud(UINT8 cfg_baud, UINT32 * baud)
+{
+    if (cfg_baud == USERIAL_BAUD_600)
+        *baud = B600;
+    else if (cfg_baud == USERIAL_BAUD_1200)
+        *baud = B1200;
+    else if (cfg_baud == USERIAL_BAUD_9600)
+        *baud = B9600;
+    else if (cfg_baud == USERIAL_BAUD_19200)
+        *baud = B19200;
+    else if (cfg_baud == USERIAL_BAUD_57600)
+        *baud = B57600;
+    else if (cfg_baud == USERIAL_BAUD_115200)
+        *baud = B115200 | CBAUDEX;
+    else if (cfg_baud == USERIAL_BAUD_230400)
+        *baud = B230400;
+    else if (cfg_baud == USERIAL_BAUD_460800)
+        *baud = B460800;
+    else if (cfg_baud == USERIAL_BAUD_921600)
+        *baud = B921600;
+    else if (cfg_baud == USERIAL_BAUD_1M)
+        *baud = B1000000;
+    else if (cfg_baud == USERIAL_BAUD_2M)
+        *baud = B2000000;
+    else if (cfg_baud == USERIAL_BAUD_3M)
+        *baud = B3000000;
+    else if (cfg_baud == USERIAL_BAUD_4M)
+        *baud = B4000000;
+    else
+    {
+        ALOGE( "USERIAL_Open: unsupported baud idx %i", cfg_baud );
+        *baud = B115200;
+        return FALSE;
+    }
+    return TRUE;
+}
+
+#if (USERIAL_USE_IO_BT_WAKE==TRUE)
+/*******************************************************************************
+ **
+ ** Function           userial_io_init_bt_wake
+ **
+ ** Description        helper function to set the open state of the bt_wake if ioctl
+ **                    is used. it should not hurt in the rfkill case but it might
+ **                    be better to compile it out.
+ **
+ ** Returns            none
+ **
+ *******************************************************************************/
+void userial_io_init_bt_wake( int fd, unsigned long * p_wake_state )
+{
+    /* assert BT_WAKE for ioctl. should NOT hurt on rfkill version */
+    ioctl( fd, USERIAL_IO_BT_WAKE_ASSERT, NULL);
+    ioctl( fd, USERIAL_IO_BT_WAKE_GET_ST, p_wake_state );
+    if ( *p_wake_state == 0)
+        ALOGI("\n***userial_io_init_bt_wake(): Ooops, asserted BT_WAKE signal, but still got BT_WAKE state == to %d\n",
+             *p_wake_state );
+
+    *p_wake_state = 1;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function           USERIAL_Open
+**
+** Description        Open the indicated serial port with the given configuration
+**
+** Output Parameter   None
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+UDRV_API void USERIAL_Open(tUSERIAL_PORT port, tUSERIAL_OPEN_CFG *p_cfg, tUSERIAL_CBACK *p_cback)
+{
+    UINT32 baud = 0;
+    UINT8 data_bits = 0;
+    UINT16 parity = 0;
+    UINT8 stop_bits = 0;
+    struct termios termios;
+    const char ttyusb[] = "/dev/ttyUSB";
+    const char devtty[] = "/dev/tty";
+    unsigned long num = 0;
+    int     ret = 0;
+
+    ALOGI("USERIAL_Open(): enter");
+
+    //if userial_close_thread() is waiting to run; let it go first;
+    //let it finish; then continue this function
+    while (TRUE)
+    {
+        pthread_mutex_lock(&close_thread_mutex);
+        if (is_close_thread_is_waiting)
+        {
+            pthread_mutex_unlock(&close_thread_mutex);
+            ALOGI("USERIAL_Open(): wait for close-thread");
+            sleep (1);
+        }
+        else
+            break;
+    }
+
+    // restore default power off delay settings incase they were changed in userial_set_poweroff_delays()
+    gPrePowerOffDelay = 0;
+    gPostPowerOffDelay = 0;
+
+    if ( !GetStrValue ( NAME_TRANSPORT_DRIVER, userial_dev, sizeof ( userial_dev ) ) )
+        strcpy ( userial_dev, default_transport );
+    if ( GetNumValue ( NAME_UART_PORT, &num, sizeof ( num ) ) )
+        uart_port = num;
+    if ( GetNumValue ( NAME_LOW_SPEED_TRANSPORT, &num, sizeof ( num ) ) )
+        isLowSpeedTransport = num;
+    if ( GetNumValue ( NAME_NFC_WAKE_DELAY, &num, sizeof ( num ) ) )
+        nfc_wake_delay = num;
+    if ( GetNumValue ( NAME_NFC_WRITE_DELAY, &num, sizeof ( num ) ) )
+        nfc_write_delay = num;
+    if ( GetNumValue ( NAME_PERF_MEASURE_FREQ, &num, sizeof ( num ) ) )
+        perf_log_every_count = num;
+    if ( GetNumValue ( NAME_POWER_ON_DELAY, &num, sizeof ( num ) ) )
+        gPowerOnDelay = num;
+    if ( GetNumValue ( NAME_PRE_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
+        gPrePowerOffDelay = num;
+    if ( GetNumValue ( NAME_POST_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
+        gPostPowerOffDelay = num;
+    ALOGI("USERIAL_Open() device: %s port=%d, uart_port=%d WAKE_DELAY(%d) WRITE_DELAY(%d) POWER_ON_DELAY(%d) PRE_POWER_OFF_DELAY(%d) POST_POWER_OFF_DELAY(%d)",
+            (char*)userial_dev, port, uart_port, nfc_wake_delay, nfc_write_delay, gPowerOnDelay, gPrePowerOffDelay,
+            gPostPowerOffDelay);
+    GetStrValue( NAME_SNOOZE_MODE_CFG, (char*)&gSnoozeModeCfg, sizeof(gSnoozeModeCfg) );
+
+    strcpy((char*)device_name, (char*)userial_dev);
+    sRxLength = 0;
+    _poll_t0 = 0;
+
+    if ((strncmp(userial_dev, ttyusb, sizeof(ttyusb)-1) == 0) ||
+        (strncmp(userial_dev, devtty, sizeof(devtty)-1) == 0) )
+    {
+        if (uart_port >= MAX_SERIAL_PORT)
+        {
+            ALOGD( "Port > MAX_SERIAL_PORT\n");
+            goto done_open;
+        }
+        bSerialPortDevice = TRUE;
+        sprintf((char*)device_name, "%s%d", (char*)userial_dev, uart_port);
+        ALOGI("USERIAL_Open() using device_name: %s ", (char*)device_name);
+        if (!userial_to_tcio_baud(p_cfg->baud, &baud))
+            goto done_open;
+
+        if (p_cfg->fmt & USERIAL_DATABITS_8)
+            data_bits = CS8;
+        else if (p_cfg->fmt & USERIAL_DATABITS_7)
+            data_bits = CS7;
+        else if (p_cfg->fmt & USERIAL_DATABITS_6)
+            data_bits = CS6;
+        else if (p_cfg->fmt & USERIAL_DATABITS_5)
+            data_bits = CS5;
+        else
+            goto done_open;
+
+        if (p_cfg->fmt & USERIAL_PARITY_NONE)
+            parity = 0;
+        else if (p_cfg->fmt & USERIAL_PARITY_EVEN)
+            parity = PARENB;
+        else if (p_cfg->fmt & USERIAL_PARITY_ODD)
+            parity = (PARENB | PARODD);
+        else
+            goto done_open;
+
+        if (p_cfg->fmt & USERIAL_STOPBITS_1)
+            stop_bits = 0;
+        else if (p_cfg->fmt & USERIAL_STOPBITS_2)
+            stop_bits = CSTOPB;
+        else
+            goto done_open;
+    }
+    else
+        strcpy((char*)device_name, (char*)userial_dev);
+
+    {
+        ALOGD("%s Opening %s\n",  __FUNCTION__, device_name);
+        if ((linux_cb.sock = open((char*)device_name, O_RDWR | O_NOCTTY )) == -1)
+        {
+            ALOGI("%s unable to open %s",  __FUNCTION__, device_name);
+            GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
+            goto done_open;
+        }
+        ALOGD( "sock = %d\n", linux_cb.sock);
+        if (GetStrValue ( NAME_POWER_CONTROL_DRIVER, power_control_dev, sizeof ( power_control_dev ) ) &&
+            power_control_dev[0] != '\0')
+        {
+            if (strcmp(power_control_dev, userial_dev) == 0)
+                linux_cb.sock_power_control = linux_cb.sock;
+            else
+            {
+                if ((linux_cb.sock_power_control = open((char*)power_control_dev, O_RDWR | O_NOCTTY )) == -1)
+                {
+                    ALOGI("%s unable to open %s",  __FUNCTION__, power_control_dev);
+                }
+            }
+        }
+
+        USERIAL_PowerupDevice(port);
+    }
+
+    linux_cb.ser_cb     = p_cback;
+    linux_cb.port = port;
+    memcpy(&linux_cb.open_cfg, p_cfg, sizeof(tUSERIAL_OPEN_CFG));
+    GKI_create_task ((TASKPTR)userial_read_thread, USERIAL_HAL_TASK, (INT8*)"USERIAL_HAL_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
+
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+    ALOGD( "Leaving USERIAL_Open\n");
+#endif
+
+#if (SERIAL_AMBA == TRUE)
+    /* give 20ms time for reader thread */
+    GKI_delay(20);
+#endif
+
+done_open:
+    pthread_mutex_unlock(&close_thread_mutex);
+    ALOGI("USERIAL_Open(): exit");
+    return;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Read
+**
+** Description        Read data from a serial port using byte buffers.
+**
+** Output Parameter   None
+**
+** Returns            Number of bytes actually read from the serial port and
+**                    copied into p_data.  This may be less than len.
+**
+*******************************************************************************/
+
+static BT_HDR *pbuf_USERIAL_Read = NULL;
+
+UDRV_API UINT16  USERIAL_Read(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
+{
+    UINT16 total_len = 0;
+    UINT16 copy_len = 0;
+    UINT8 * current_packet = NULL;
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+    ALOGD( "%s ++ len=%d pbuf_USERIAL_Read=%p, p_data=%p\n", __func__, len, pbuf_USERIAL_Read, p_data);
+#endif
+    do
+    {
+        if (pbuf_USERIAL_Read != NULL)
+        {
+            current_packet = ((UINT8 *)(pbuf_USERIAL_Read + 1)) + (pbuf_USERIAL_Read->offset);
+
+            if ((pbuf_USERIAL_Read->len) <= (len - total_len))
+                copy_len = pbuf_USERIAL_Read->len;
+            else
+                copy_len = (len - total_len);
+
+            memcpy((p_data + total_len), current_packet, copy_len);
+
+            total_len += copy_len;
+
+            pbuf_USERIAL_Read->offset += copy_len;
+            pbuf_USERIAL_Read->len -= copy_len;
+
+            if (pbuf_USERIAL_Read->len == 0)
+            {
+                GKI_freebuf(pbuf_USERIAL_Read);
+                pbuf_USERIAL_Read = NULL;
+            }
+        }
+
+        if (pbuf_USERIAL_Read == NULL && (total_len < len))
+            pbuf_USERIAL_Read = (BT_HDR *)GKI_dequeue(&Userial_in_q);
+
+    } while ((pbuf_USERIAL_Read != NULL) && (total_len < len));
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+    ALOGD( "%s: returned %d bytes", __func__, total_len);
+#endif
+    return total_len;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Readbuf
+**
+** Description        Read data from a serial port using GKI buffers.
+**
+** Output Parameter   Pointer to a GKI buffer which contains the data.
+**
+** Returns            Nothing
+**
+** Comments           The caller of this function is responsible for freeing the
+**                    GKI buffer when it is finished with the data.  If there is
+**                    no data to be read, the value of the returned pointer is
+**                    NULL.
+**
+*******************************************************************************/
+
+UDRV_API void    USERIAL_ReadBuf(tUSERIAL_PORT port, BT_HDR **p_buf)
+{
+
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_WriteBuf
+**
+** Description        Write data to a serial port using a GKI buffer.
+**
+** Output Parameter   None
+**
+** Returns            TRUE  if buffer accepted for write.
+**                    FALSE if there is already a buffer being processed.
+**
+** Comments           The buffer will be freed by the serial driver.  Therefore,
+**                    the application calling this function must not free the
+**                    buffer.
+**
+*******************************************************************************/
+
+UDRV_API BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT port, BT_HDR *p_buf)
+{
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Write
+**
+** Description        Write data to a serial port using a byte buffer.
+**
+** Output Parameter   None
+**
+** Returns            Number of bytes actually written to the transport.  This
+**                    may be less than len.
+**
+*******************************************************************************/
+UDRV_API UINT16  USERIAL_Write(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
+{
+    int ret = 0, total = 0;
+    int i = 0;
+    clock_t t;
+
+    doWriteDelay();
+    ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write: (%d bytes) - \n", len);
+    t = clock();
+    while (len != 0)
+    {
+        ret = write(linux_cb.sock, p_data + total, len);
+        if (ret < 0)
+            break;
+        total += ret;
+        len -= ret;
+    }
+    perf_update(&perf_write, clock() - t, total);
+
+    ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write len = %d, ret =  %d, errno = %d\n", len, ret, errno);
+
+    /* register a delay for next write
+     */
+    setWriteDelay(total * nfc_write_delay / 1000);
+    return ((UINT16)total);
+}
+
+/*******************************************************************************
+**
+** Function           userial_change_rate
+**
+** Description        change naud rate
+**
+** Output Parameter   None
+**
+** Returns            None
+**
+*******************************************************************************/
+void userial_change_rate(UINT8 baud)
+{
+#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
+    struct termios termios;
+#endif
+#if (USERIAL_USE_TCIO_BAUD_CHANGE==TRUE)
+    UINT32 tcio_baud;
+#endif
+
+#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
+    tcflush(linux_cb.sock, TCIOFLUSH);
+
+    tcgetattr(linux_cb.sock, &termios);
+
+    cfmakeraw(&termios);
+    cfsetospeed(&termios, baud);
+    cfsetispeed(&termios, baud);
+
+    termios.c_cflag |= (CLOCAL | CREAD | CRTSCTS | stop_bits);
+
+    tcsetattr(linux_cb.sock, TCSANOW, &termios);
+    tcflush(linux_cb.sock, TCIOFLUSH);
+
+#else
+#if (USERIAL_USE_TCIO_BAUD_CHANGE==FALSE)
+    fprintf(stderr, "userial_change_rate: Closing UART Port\n");
+    ALOGI("userial_change_rate: Closing UART Port\n");
+    USERIAL_Close(linux_cb.port);
+
+    GKI_delay(50);
+
+    /* change baud rate in settings - leave everything else the same  */
+    linux_cb.open_cfg.baud = baud;
+
+    ALOGD( "userial_change_rate: Attempting to reopen the UART Port at 0x%08x\n", (unsigned int)USERIAL_GetLineSpeed(baud));
+    ALOGI("userial_change_rate: Attempting to reopen the UART Port at %i\n", (unsigned int)USERIAL_GetLineSpeed(baud));
+
+    USERIAL_Open(linux_cb.port, &linux_cb.open_cfg, linux_cb.ser_cb);
+#else /* amba uart */
+    fprintf(stderr, "userial_change_rate(): changeing baud rate via TCIO \n");
+    ALOGI( "userial_change_rate: (): changeing baud rate via TCIO \n");
+    /* change baud rate in settings - leave everything else the same  */
+    linux_cb.open_cfg.baud = baud;
+    if (!userial_to_tcio_baud(linux_cb.open_cfg.baud, &tcio_baud))
+        return;
+
+    tcflush(linux_cb.sock, TCIOFLUSH);
+
+    /* get current settings. they should be fine besides baud rate we want to change */
+    tcgetattr(linux_cb.sock, &termios);
+
+    /* set input/output baudrate */
+    cfsetospeed(&termios, tcio_baud);
+    cfsetispeed(&termios, tcio_baud);
+    tcsetattr(linux_cb.sock, TCSANOW, &termios);
+
+    tcflush(linux_cb.sock, TCIOFLUSH);
+#endif
+#endif   /* USING_BRCM_USB  */
+}
+
+/*******************************************************************************
+**
+** Function           userial_close_port
+**
+** Description        close the transport driver
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+void userial_close_port( void )
+{
+    USERIAL_Close(linux_cb.port);
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Ioctl
+**
+** Description        Perform an operation on a serial port.
+**
+** Output Parameter   The p_data parameter is either an input or output depending
+**                    on the operation.
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+
+UDRV_API void    USERIAL_Ioctl(tUSERIAL_PORT port, tUSERIAL_OP op, tUSERIAL_IOCTL_DATA *p_data)
+{
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+    USB_SCO_CONTROL ioctl_data;
+
+    /* just ignore port parameter as we are using USB in this case  */
+#endif
+
+    switch (op)
+    {
+    case USERIAL_OP_FLUSH:
+        break;
+    case USERIAL_OP_FLUSH_RX:
+        break;
+    case USERIAL_OP_FLUSH_TX:
+        break;
+    case USERIAL_OP_BAUD_WR:
+        ALOGI( "USERIAL_Ioctl: Received USERIAL_OP_BAUD_WR on port: %d, ioctl baud%i\n", port, p_data->baud);
+        linux_cb.port = port;
+        userial_change_rate(p_data->baud);
+        break;
+
+    default:
+        break;
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Close
+**
+** Description        Close a serial port
+**
+** Output Parameter   None
+**
+** Returns            Nothing
+**
+*******************************************************************************/
+UDRV_API void    USERIAL_Close(tUSERIAL_PORT port)
+{
+    pthread_attr_t attr;
+    pthread_t      close_thread;
+
+    ALOGD ("%s: enter", __FUNCTION__);
+    // check to see if thread is already running
+    if (pthread_mutex_trylock(&close_thread_mutex) == 0)
+    {
+        // mutex aquired so thread is not running
+        is_close_thread_is_waiting = TRUE;
+        pthread_mutex_unlock(&close_thread_mutex);
+
+        // close transport in a new thread so we don't block the caller
+        // make thread detached, no other thread will join
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+        pthread_create( &close_thread, &attr, (void *)userial_close_thread,(void*)port);
+        pthread_attr_destroy(&attr);
+    }
+    else
+    {
+        // mutex not aquired to thread is already running
+        ALOGD( "USERIAL_Close(): already closing \n");
+    }
+    ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
+/*******************************************************************************
+**
+** Function         userial_close_thread
+**
+** Description      Thread to close USERIAL
+**
+** Returns          None.
+**
+*******************************************************************************/
+void userial_close_thread(UINT32 params)
+{
+    tUSERIAL_PORT port = (tUSERIAL_PORT )params;
+    BT_HDR                  *p_buf = NULL;
+    int result;
+
+    ALOGD( "%s: closing transport (%d)\n", __FUNCTION__, linux_cb.sock);
+    pthread_mutex_lock(&close_thread_mutex);
+    is_close_thread_is_waiting = FALSE;
+
+    if (linux_cb.sock <= 0)
+    {
+        ALOGD( "%s: already closed (%d)\n", __FUNCTION__, linux_cb.sock);        
+        pthread_mutex_unlock(&close_thread_mutex);
+        return;
+    }
+
+    send_wakeup_signal();
+    result = pthread_join( worker_thread1, NULL );
+    if ( result < 0 )
+        ALOGE( "%s: pthread_join() FAILED: result: %d", __FUNCTION__, result );
+    else
+        ALOGD( "%s: pthread_join() joined: result: %d", __FUNCTION__, result );
+
+    if (linux_cb.sock_power_control > 0)
+    {
+        result = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, sleep_state());
+        ALOGD("%s: Delay %dms before turning off the chip", __FUNCTION__, gPrePowerOffDelay);
+        GKI_delay(gPrePowerOffDelay);
+        result = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+        ALOGD("%s: Delay %dms after turning off the chip", __FUNCTION__, gPostPowerOffDelay);
+        GKI_delay(gPostPowerOffDelay);
+    }
+    result = close(linux_cb.sock);
+    if (result<0)
+        ALOGD("%s: close return %d", __FUNCTION__, result);
+
+    if (linux_cb.sock_power_control > 0 && linux_cb.sock_power_control != linux_cb.sock)
+    result = close(linux_cb.sock_power_control);
+    if (result<0)
+        ALOGD("%s: close return %d", __FUNCTION__, result);
+
+    linux_cb.sock_power_control = -1;
+    linux_cb.sock = -1;
+
+    close_signal_fds();
+    pthread_mutex_unlock(&close_thread_mutex);
+    ALOGD("%s: exiting", __FUNCTION__);
+}
+
+/*******************************************************************************
+**
+** Function           USERIAL_Feature
+**
+** Description        Check whether a feature of the serial API is supported.
+**
+** Output Parameter   None
+**
+** Returns            TRUE  if the feature is supported
+**                    FALSE if the feature is not supported
+**
+*******************************************************************************/
+
+UDRV_API BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE feature)
+{
+    switch (feature)
+    {
+    case USERIAL_FEAT_PORT_1:
+    case USERIAL_FEAT_PORT_2:
+    case USERIAL_FEAT_PORT_3:
+    case USERIAL_FEAT_PORT_4:
+
+    case USERIAL_FEAT_BAUD_600:
+    case USERIAL_FEAT_BAUD_1200:
+    case USERIAL_FEAT_BAUD_9600:
+    case USERIAL_FEAT_BAUD_19200:
+    case USERIAL_FEAT_BAUD_57600:
+    case USERIAL_FEAT_BAUD_115200:
+
+    case USERIAL_FEAT_STOPBITS_1:
+    case USERIAL_FEAT_STOPBITS_2:
+
+    case USERIAL_FEAT_PARITY_NONE:
+    case USERIAL_FEAT_PARITY_EVEN:
+    case USERIAL_FEAT_PARITY_ODD:
+
+    case USERIAL_FEAT_DATABITS_5:
+    case USERIAL_FEAT_DATABITS_6:
+    case USERIAL_FEAT_DATABITS_7:
+    case USERIAL_FEAT_DATABITS_8:
+
+    case USERIAL_FEAT_FC_HW:
+    case USERIAL_FEAT_BUF_BYTE:
+
+    case USERIAL_FEAT_OP_FLUSH_RX:
+    case USERIAL_FEAT_OP_FLUSH_TX:
+        return TRUE;
+    default:
+        return FALSE;
+    }
+
+    return FALSE;
+}
+
+/*****************************************************************************
+**
+** Function         UPIO_Set
+**
+** Description
+**      This function sets one or more GPIO devices to the given state.
+**      Multiple GPIOs of the same type can be masked together to set more
+**      than one GPIO. This function can only be used on types UPIO_LED and
+**      UPIO_GENERAL.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      state   The desired state.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE new_state)
+{
+    int     ret;
+    if (type == UPIO_GENERAL)
+    {
+        if (pio == NFC_HAL_LP_NFC_WAKE_GPIO)
+        {
+            if (new_state == UPIO_ON || new_state == UPIO_OFF)
+            {
+                if (linux_cb.sock_power_control > 0)
+                {
+                    ALOGD("%s: ioctl, state=%d", __func__, new_state);
+                    ret = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, new_state);
+                    if (isWake(new_state) && nfc_wake_delay > 0 && new_state != current_nfc_wake_state)
+                    {
+                        ALOGD("%s: ioctl, old state=%d, insert delay for %d ms", __func__, current_nfc_wake_state, nfc_wake_delay);
+                        setWriteDelay(nfc_wake_delay);
+                    }
+                    current_nfc_wake_state = new_state;
+                }
+            }
+        }
+    }
+}
+
+/*****************************************************************************
+**
+** Function         setReadPacketSize
+**
+** Description
+**      This function sets the packetSize to the driver.
+**      this enables faster read operation of NCI/HCI responses
+**
+** Input Parameters:
+**      len     number of bytes to read per operation.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+void setReadPacketSize(int len)
+{
+    int ret;
+    ALOGD("%s: ioctl, len=%d", __func__, len);
+    ret = ioctl(linux_cb.sock, BCMNFC_READ_FULL_PACKET, len);
+}
+
+
+UDRV_API BOOLEAN USERIAL_IsClosed()
+{
+    return (linux_cb.sock == -1) ? TRUE : FALSE;
+}
+
+UDRV_API void USERIAL_PowerupDevice(tUSERIAL_PORT port)
+{
+    int ret = -1;
+    unsigned long num = 0;
+    unsigned int resetSuccess = 0;
+    unsigned int numTries = 0;
+    unsigned char spi_negotiation[64];
+
+    if ( GetNumValue ( NAME_READ_MULTI_PACKETS, &num, sizeof ( num ) ) )
+        bcmi2cnfc_read_multi_packets = num;
+
+    if (bcmi2cnfc_read_multi_packets > 0)
+        ioctl(linux_cb.sock, BCMNFC_READ_MULTI_PACKETS, bcmi2cnfc_read_multi_packets);
+
+    while (!resetSuccess && numTries < NUM_RESET_ATTEMPTS) {
+        if (numTries++ > 0) {
+            ALOGW("BCM2079x: retrying reset, attempt %d/%d", numTries, NUM_RESET_ATTEMPTS);
+        }
+        if (linux_cb.sock_power_control > 0)
+        {
+            ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+            GKI_delay(10);
+            ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 1);
+            current_nfc_wake_state = wake_state();
+            ret = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, current_nfc_wake_state);
+        }
+
+        ret = GetStrValue ( NAME_SPI_NEGOTIATION, (char*)spi_negotiation, sizeof ( spi_negotiation ) );
+        if (ret > 0 && spi_negotiation[0] > 0 && spi_negotiation[0] < sizeof ( spi_negotiation ) - 1)
+        {
+            int len = spi_negotiation[0];
+            /* Wake control is not available: Start SPI negotiation*/
+            USERIAL_Write(port, &spi_negotiation[1], len);
+            USERIAL_Read(port, spi_negotiation, sizeof ( spi_negotiation ));
+        }
+
+        if ( GetNumValue ( NAME_CLIENT_ADDRESS, &num, sizeof ( num ) ) )
+            bcmi2cnfc_client_addr = num & 0xFF;
+        if (bcmi2cnfc_client_addr != 0 &&
+            0x07 < bcmi2cnfc_client_addr &&
+            bcmi2cnfc_client_addr < 0x78)
+        {
+            ALOGD( "Change client address to %x\n", bcmi2cnfc_client_addr);
+            GKI_delay(gPowerOnDelay);
+            ret = ioctl(linux_cb.sock, BCMNFC_CHANGE_ADDR, bcmi2cnfc_client_addr);
+            if (!ret) {
+                resetSuccess = 1;
+                linux_cb.client_device_address = bcmi2cnfc_client_addr;
+            }
+        } else {
+            resetSuccess = 1;
+        }
+    }
+
+    if (!resetSuccess) {
+        ALOGE("BCM2079x: failed to initialize NFC controller");
+    }
+    GKI_delay(gPowerOnDelay);
+}
diff --git a/halimpl/bcm2079x/gki/common/gki.h b/halimpl/bcm2079x/gki/common/gki.h
new file mode 100644
index 0000000..f2e6f1a
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki.h
@@ -0,0 +1,517 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_H
+#define GKI_H
+
+#ifdef BUILDCFG
+#if (!defined(NFC_HAL_TARGET) || (NFC_HAL_TARGET == FALSE))
+    #include "buildcfg.h"
+#else
+    /* Build config when building HAL */
+    #include "buildcfg_hal.h"
+#endif
+#endif
+
+/* Include platform-specific over-rides */
+#if (defined(NFC_STANDALONE) && (NFC_STANDALONE == TRUE))
+    #include "gki_target.h"
+    #include "bt_types.h"
+#elif (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE))
+    /* If building NFC HAL, then use hal target file */
+    #include "gki_hal_target.h"
+    #include "nfc_types.h"
+#else
+    /* For non-nfc_standalone, include Bluetooth definitions */
+    #include "bt_target.h"
+    #include "bt_types.h"
+#endif
+
+/* Uncomment this line for verbose GKI debugging and buffer tracking */
+/*#define GKI_BUFFER_DEBUG   TRUE*/
+
+
+/* Error codes */
+#define GKI_SUCCESS         0x00
+#define GKI_FAILURE         0x01
+#define GKI_INVALID_TASK    0xF0
+#define GKI_INVALID_POOL    0xFF
+
+
+/************************************************************************
+** Mailbox definitions. Each task has 4 mailboxes that are used to
+** send buffers to the task.
+*/
+#define TASK_MBOX_0    0
+#define TASK_MBOX_1    1
+#define TASK_MBOX_2    2
+#define TASK_MBOX_3    3
+
+#define NUM_TASK_MBOX  4
+
+/************************************************************************
+** Event definitions.
+**
+** There are 4 reserved events used to signal messages rcvd in task mailboxes.
+** There are 4 reserved events used to signal timeout events.
+** There are 8 general purpose events available for applications.
+*/
+#define MAX_EVENTS              16
+
+#define TASK_MBOX_0_EVT_MASK   0x0001
+#define TASK_MBOX_1_EVT_MASK   0x0002
+#define TASK_MBOX_2_EVT_MASK   0x0004
+#define TASK_MBOX_3_EVT_MASK   0x0008
+
+
+#define TIMER_0             0
+#define TIMER_1             1
+#define TIMER_2             2
+#define TIMER_3             3
+
+#define TIMER_0_EVT_MASK    0x0010
+#define TIMER_1_EVT_MASK    0x0020
+#define TIMER_2_EVT_MASK    0x0040
+#define TIMER_3_EVT_MASK    0x0080
+
+#define APPL_EVT_0          8
+#define APPL_EVT_1          9
+#define APPL_EVT_2          10
+#define APPL_EVT_3          11
+#define APPL_EVT_4          12
+#define APPL_EVT_5          13
+#define APPL_EVT_6          14
+#define APPL_EVT_7          15
+
+#define EVENT_MASK(evt)       ((UINT16)(0x0001 << (evt)))
+
+/************************************************************************
+**  Max Time Queue
+**/
+#ifndef GKI_MAX_TIMER_QUEUES
+#define GKI_MAX_TIMER_QUEUES    3
+#endif
+
+
+/************************************************************************
+**  Macro to determine the pool buffer size based on the GKI POOL ID at compile time.
+**  Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
+*/
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 1)
+
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0                0
+#endif /* ifndef GKI_POOL_ID_0 */
+
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE                0
+#endif /* ifndef GKI_BUF0_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 2)
+
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1                0
+#endif /* ifndef GKI_POOL_ID_1 */
+
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE                0
+#endif /* ifndef GKI_BUF1_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 3)
+
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2                0
+#endif /* ifndef GKI_POOL_ID_2 */
+
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE                0
+#endif /* ifndef GKI_BUF2_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 4)
+
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3                0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE                0
+#endif /* ifndef GKI_BUF3_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 5)
+
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4                0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE                0
+#endif /* ifndef GKI_BUF4_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 6)
+
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5                0
+#endif /* ifndef GKI_POOL_ID_5 */
+
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE                0
+#endif /* ifndef GKI_BUF5_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 7)
+
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6                0
+#endif /* ifndef GKI_POOL_ID_6 */
+
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE                0
+#endif /* ifndef GKI_BUF6_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 8)
+
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7                0
+#endif /* ifndef GKI_POOL_ID_7 */
+
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE                0
+#endif /* ifndef GKI_BUF7_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 9)
+
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8                0
+#endif /* ifndef GKI_POOL_ID_8 */
+
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE                0
+#endif /* ifndef GKI_BUF8_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 10)
+
+#ifndef GKI_POOL_ID_9
+#define GKI_POOL_ID_9                0
+#endif /* ifndef GKI_POOL_ID_9 */
+
+#ifndef GKI_BUF9_SIZE
+#define GKI_BUF9_SIZE                0
+#endif /* ifndef GKI_BUF9_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 11)
+
+#ifndef GKI_POOL_ID_10
+#define GKI_POOL_ID_10                0
+#endif /* ifndef GKI_POOL_ID_10 */
+
+#ifndef GKI_BUF10_SIZE
+#define GKI_BUF10_SIZE                0
+#endif /* ifndef GKI_BUF10_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 12)
+
+#ifndef GKI_POOL_ID_11
+#define GKI_POOL_ID_11                0
+#endif /* ifndef GKI_POOL_ID_11 */
+
+#ifndef GKI_BUF11_SIZE
+#define GKI_BUF11_SIZE                0
+#endif /* ifndef GKI_BUF11_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 13)
+
+#ifndef GKI_POOL_ID_12
+#define GKI_POOL_ID_12                0
+#endif /* ifndef GKI_POOL_ID_12 */
+
+#ifndef GKI_BUF12_SIZE
+#define GKI_BUF12_SIZE                0
+#endif /* ifndef GKI_BUF12_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 14)
+
+#ifndef GKI_POOL_ID_13
+#define GKI_POOL_ID_13                0
+#endif /* ifndef GKI_POOL_ID_13 */
+
+#ifndef GKI_BUF13_SIZE
+#define GKI_BUF13_SIZE                0
+#endif /* ifndef GKI_BUF13_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 15)
+
+#ifndef GKI_POOL_ID_14
+#define GKI_POOL_ID_14                0
+#endif /* ifndef GKI_POOL_ID_14 */
+
+#ifndef GKI_BUF14_SIZE
+#define GKI_BUF14_SIZE                0
+#endif /* ifndef GKI_BUF14_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 16)
+
+#ifndef GKI_POOL_ID_15
+#define GKI_POOL_ID_15                0
+#endif /* ifndef GKI_POOL_ID_15 */
+
+#ifndef GKI_BUF15_SIZE
+#define GKI_BUF15_SIZE                0
+#endif /* ifndef GKI_BUF15_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
+
+
+/* Timer list entry callback type
+*/
+typedef void (TIMER_CBACK)(void *p_tle);
+#ifndef TIMER_PARAM_TYPE
+#ifdef  WIN2000
+#define TIMER_PARAM_TYPE    void *
+#else
+#define TIMER_PARAM_TYPE    UINT32
+#endif
+#endif
+/* Define a timer list entry
+*/
+typedef struct _tle
+{
+    struct _tle  *p_next;
+    struct _tle  *p_prev;
+    TIMER_CBACK  *p_cback;
+    INT32         ticks;
+    TIMER_PARAM_TYPE   param;
+    UINT16        event;
+    UINT8         in_use;
+} TIMER_LIST_ENT;
+
+/* Define a timer list queue
+*/
+typedef struct
+{
+    TIMER_LIST_ENT   *p_first;
+    TIMER_LIST_ENT   *p_last;
+    INT32             last_ticks;
+} TIMER_LIST_Q;
+
+
+/***********************************************************************
+** This queue is a general purpose buffer queue, for application use.
+*/
+typedef struct
+{
+    void    *p_first;
+    void    *p_last;
+    UINT16   count;
+} BUFFER_Q;
+
+#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
+
+/* Task constants
+*/
+#ifndef TASKPTR
+typedef void (*TASKPTR)(UINT32);
+#endif
+
+
+#define GKI_PUBLIC_POOL         0       /* General pool accessible to GKI_getbuf() */
+#define GKI_RESTRICTED_POOL     1       /* Inaccessible pool to GKI_getbuf() */
+
+/***********************************************************************
+** Function prototypes
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Task management
+*/
+GKI_API extern UINT8   GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16, void*, void*);
+GKI_API extern void    GKI_exit_task(UINT8);
+GKI_API extern UINT8   GKI_get_taskid(void);
+GKI_API extern void    GKI_init(void);
+GKI_API extern UINT8   *GKI_map_taskname(UINT8);
+GKI_API extern UINT8   GKI_resume_task(UINT8);
+GKI_API extern void    GKI_run(void *);
+GKI_API extern void    GKI_stop(void);
+GKI_API extern UINT8   GKI_suspend_task(UINT8);
+GKI_API extern UINT8   GKI_is_task_running(UINT8);
+GKI_API extern void    GKI_shutdown(void);
+
+/* memory management
+*/
+GKI_API extern void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount);
+GKI_API extern void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len);
+
+/* To send buffers and events between tasks
+*/
+GKI_API extern UINT8   GKI_isend_event (UINT8, UINT16);
+GKI_API extern void    GKI_isend_msg (UINT8, UINT8, void *);
+GKI_API extern void   *GKI_read_mbox  (UINT8);
+GKI_API extern void    GKI_send_msg   (UINT8, UINT8, void *);
+GKI_API extern UINT8   GKI_send_event (UINT8, UINT16);
+
+
+/* To get and release buffers, change owner and get size
+*/
+GKI_API extern void    GKI_change_buf_owner (void *, UINT8);
+GKI_API extern UINT8   GKI_create_pool (UINT16, UINT16, UINT8, void *);
+GKI_API extern void    GKI_delete_pool (UINT8);
+GKI_API extern void   *GKI_find_buf_start (void *);
+GKI_API extern void    GKI_freebuf (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getbuf(size)    GKI_getbuf_debug(size, __FUNCTION__, __LINE__)
+GKI_API extern void   *GKI_getbuf_debug (UINT16, const char *, int);
+#else
+GKI_API extern void   *GKI_getbuf (UINT16);
+#endif
+GKI_API extern UINT16  GKI_get_buf_size (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getpoolbuf(id)    GKI_getpoolbuf_debug(id, __FUNCTION__, __LINE__)
+GKI_API extern void   *GKI_getpoolbuf_debug (UINT8, const char *, int);
+#else
+GKI_API extern void   *GKI_getpoolbuf (UINT8);
+#endif
+
+GKI_API extern UINT16  GKI_poolcount (UINT8);
+GKI_API extern UINT16  GKI_poolfreecount (UINT8);
+GKI_API extern UINT16  GKI_poolutilization (UINT8);
+GKI_API extern void    GKI_register_mempool (void *p_mem);
+GKI_API extern UINT8   GKI_set_pool_permission(UINT8, UINT8);
+
+
+/* User buffer queue management
+*/
+GKI_API extern void   *GKI_dequeue  (BUFFER_Q *);
+GKI_API extern void    GKI_enqueue (BUFFER_Q *, void *);
+GKI_API extern void    GKI_enqueue_head (BUFFER_Q *, void *);
+GKI_API extern void   *GKI_getfirst (BUFFER_Q *);
+GKI_API extern void   *GKI_getlast (BUFFER_Q *);
+GKI_API extern void   *GKI_getnext (void *);
+GKI_API extern void    GKI_init_q (BUFFER_Q *);
+GKI_API extern BOOLEAN GKI_queue_is_empty(BUFFER_Q *);
+GKI_API extern void   *GKI_remove_from_queue (BUFFER_Q *, void *);
+GKI_API extern UINT16  GKI_get_pool_bufsize (UINT8);
+
+/* Timer management
+*/
+GKI_API extern void    GKI_add_to_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern void    GKI_delay(UINT32);
+GKI_API extern UINT32  GKI_get_tick_count(void);
+GKI_API extern INT8   *GKI_get_time_stamp(INT8 *);
+GKI_API extern void    GKI_init_timer_list (TIMER_LIST_Q *);
+GKI_API extern void    GKI_init_timer_list_entry (TIMER_LIST_ENT  *);
+GKI_API extern INT32   GKI_ready_to_sleep (void);
+GKI_API extern void    GKI_remove_from_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern void    GKI_start_timer(UINT8, INT32, BOOLEAN);
+GKI_API extern void    GKI_stop_timer (UINT8);
+GKI_API extern void    GKI_timer_update(INT32);
+GKI_API extern UINT16  GKI_update_timer_list (TIMER_LIST_Q *, INT32);
+GKI_API extern UINT32  GKI_get_remaining_ticks (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern UINT16  GKI_wait(UINT16, UINT32);
+
+/* Start and Stop system time tick callback
+ * true for start system tick if time queue is not empty
+ * false to stop system tick if time queue is empty
+*/
+typedef void (SYSTEM_TICK_CBACK)(BOOLEAN);
+
+/* Time queue management for system ticks
+*/
+GKI_API extern BOOLEAN GKI_timer_queue_empty (void);
+GKI_API extern void    GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK *);
+
+/* Disable Interrupts, Enable Interrupts
+*/
+GKI_API extern void    GKI_enable(void);
+GKI_API extern void    GKI_disable(void);
+GKI_API extern void    GKI_sched_lock(void);
+GKI_API extern void    GKI_sched_unlock(void);
+
+/* Allocate (Free) memory from an OS
+*/
+GKI_API extern void     *GKI_os_malloc (UINT32);
+GKI_API extern void      GKI_os_free (void *);
+
+/* os timer operation */
+GKI_API extern UINT32 GKI_get_os_tick_count(void);
+
+/* Exception handling
+*/
+GKI_API extern void    GKI_exception (UINT16, char *);
+
+#if GKI_DEBUG == TRUE
+GKI_API extern void    GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used);
+GKI_API extern void    GKI_PrintBuffer(void);
+GKI_API extern void    GKI_print_task(void);
+#else
+#undef GKI_PrintBufferUsage
+#define GKI_PrintBuffer() NULL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/common/gki_buffer.c b/halimpl/bcm2079x/gki/common/gki_buffer.c
new file mode 100644
index 0000000..067c7ba
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_buffer.c
@@ -0,0 +1,1531 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+#include <stdio.h>
+
+#if (GKI_NUM_TOTAL_BUF_POOLS > 16)
+#error Number of pools out of range (16 Max)!
+#endif
+
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+static void gki_add_to_pool_list(UINT8 pool_id);
+static void gki_remove_from_pool_list(UINT8 pool_id);
+#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
+
+#if GKI_BUFFER_DEBUG
+#define LOG_TAG "GKI_DEBUG"
+#define LOGD(format, ...)  LogMsg (TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC, format, ## __VA_ARGS__)
+#endif
+/*******************************************************************************
+**
+** Function         gki_init_free_queue
+**
+** Description      Internal function called at startup to initialize a free
+**                  queue. It is called once for each free queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
+{
+    UINT16           i;
+    UINT16           act_size;
+    BUFFER_HDR_T    *hdr;
+    BUFFER_HDR_T    *hdr1 = NULL;
+    UINT32          *magic;
+    INT32            tempsize = size;
+    tGKI_COM_CB     *p_cb = &gki_cb.com;
+
+    /* Ensure an even number of longwords */
+    tempsize = (INT32)ALIGN_POOL(size);
+    act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
+
+    /* Remember pool start and end addresses */
+    if(p_mem)
+    {
+        p_cb->pool_start[id] = (UINT8 *)p_mem;
+        p_cb->pool_end[id]   = (UINT8 *)p_mem + (act_size * total);
+    }
+
+    p_cb->pool_size[id]  = act_size;
+
+    p_cb->freeq[id].size      = (UINT16) tempsize;
+    p_cb->freeq[id].total     = total;
+    p_cb->freeq[id].cur_cnt   = 0;
+    p_cb->freeq[id].max_cnt   = 0;
+
+#if GKI_BUFFER_DEBUG
+    LOGD("gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d start=%p", id, size, tempsize, total, p_mem);
+#endif
+
+    /* Initialize  index table */
+    if(p_mem)
+    {
+        hdr = (BUFFER_HDR_T *)p_mem;
+        p_cb->freeq[id].p_first = hdr;
+        for (i = 0; i < total; i++)
+        {
+            hdr->task_id = GKI_INVALID_TASK;
+            hdr->q_id    = id;
+            hdr->status  = BUF_STATUS_FREE;
+            magic        = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
+            *magic       = MAGIC_NO;
+            hdr1         = hdr;
+            hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+            hdr1->p_next = hdr;
+        }
+        hdr1->p_next = NULL;
+        p_cb->freeq[id].p_last = hdr1;
+    }
+    return;
+}
+
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+static BOOLEAN gki_alloc_free_queue(UINT8 id)
+{
+    FREE_QUEUE_T  *Q;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    printf("\ngki_alloc_free_queue in, id:%d \n", id);
+
+    Q = &p_cb->freeq[p_cb->pool_list[id]];
+
+    if(Q->p_first == 0)
+    {
+        void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
+        if(p_mem)
+        {
+            //re-initialize the queue with allocated memory
+            printf("\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            gki_init_free_queue(id, Q->size, Q->total, p_mem);
+            printf("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            return TRUE;
+        }
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
+    }
+    printf("\ngki_alloc_free_queue out failed, id:%d\n", id);
+    return FALSE;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         gki_buffer_init
+**
+** Description      Called once internally by GKI at startup to initialize all
+**                  buffers and free buffer pools.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_buffer_init(void)
+{
+    UINT8   i, tt, mb;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* Initialize mailboxes */
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+        for (mb = 0; mb < NUM_TASK_MBOX; mb++)
+        {
+            p_cb->OSTaskQFirst[tt][mb] = NULL;
+            p_cb->OSTaskQLast [tt][mb] = NULL;
+        }
+    }
+
+    for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
+    {
+        p_cb->pool_start[tt] = NULL;
+        p_cb->pool_end[tt]   = NULL;
+        p_cb->pool_size[tt]  = 0;
+
+        p_cb->freeq[tt].p_first = 0;
+        p_cb->freeq[tt].p_last  = 0;
+        p_cb->freeq[tt].size    = 0;
+        p_cb->freeq[tt].total   = 0;
+        p_cb->freeq[tt].cur_cnt = 0;
+        p_cb->freeq[tt].max_cnt = 0;
+    }
+
+    /* Use default from target.h */
+    p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
+
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
+#endif
+
+#endif
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
+#endif
+
+    /* add pools to the pool_list which is arranged in the order of size */
+    for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
+    {
+        p_cb->pool_list[i] = i;
+    }
+
+    p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_init_q
+**
+** Description      Called by an application to initialize a buffer queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_q (BUFFER_Q *p_q)
+{
+    p_q->p_first = p_q->p_last = NULL;
+    p_q->count = 0;
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_getbuf
+**
+** Description      Called by an application to get a free buffer which
+**                  is of size greater or equal to the requested size.
+**
+**                  Note: This routine only takes buffers from public pools.
+**                        It will not use any buffers from pools
+**                        marked GKI_RESTRICTED_POOL.
+**
+** Parameters       size - (input) number of bytes needed.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
+#else
+void *GKI_getbuf (UINT16 size)
+#endif
+{
+    UINT8         i;
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+#if GKI_BUFFER_DEBUG
+    UINT8         x;
+#endif
+
+    if (size == 0)
+    {
+        GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
+        return (NULL);
+    }
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
+#endif
+    /* Find the first buffer pool that is public that can hold the desired size */
+    for (i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
+            break;
+    }
+
+    if(i == p_cb->curr_total_no_of_pools)
+    {
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
+        return (NULL);
+    }
+
+    /* Make sure the buffers aren't disturbed til finished with allocation */
+    GKI_disable();
+
+    /* search the public buffer pools that are big enough to hold the size
+     * until a free buffer is found */
+    for ( ; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
+        if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
+            continue;
+
+        Q = &p_cb->freeq[p_cb->pool_list[i]];
+        if(Q->cur_cnt < Q->total)
+        {
+        #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+            if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
+            {
+                GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
+                return NULL;
+            }
+        #endif
+            p_hdr = Q->p_first;
+            Q->p_first = p_hdr->p_next;
+
+            if (!Q->p_first)
+                Q->p_last = NULL;
+
+            if(++Q->cur_cnt > Q->max_cnt)
+                Q->max_cnt = Q->cur_cnt;
+
+            GKI_enable();
+
+            p_hdr->task_id = GKI_get_taskid();
+
+            p_hdr->status  = BUF_STATUS_UNLINKED;
+            p_hdr->p_next  = NULL;
+            p_hdr->Type    = 0;
+#if GKI_BUFFER_DEBUG
+            LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[i].total);
+
+            strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+            p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+            p_hdr->_line = _line_;
+#endif
+            return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+        }
+    }
+
+    GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
+    LOGD("******************** GKI Memory Pool Dump ********************");
+
+    p_cb = &gki_cb.com;
+
+    LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
+
+    for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
+
+        LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
+
+        for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
+        {
+            if (p_hdr->status != BUF_STATUS_FREE)
+            {
+                LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x, (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status, p_hdr->_function, p_hdr->_line);
+            }
+
+            p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
+        }
+    }
+    LOGD("**************************************************************");
+#endif
+
+    GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
+
+    GKI_enable();
+
+    return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_getpoolbuf
+**
+** Description      Called by an application to get a free buffer from
+**                  a specific buffer pool.
+**
+**                  Note: If there are no more buffers available from the pool,
+**                        the public buffers are searched for an available buffer.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
+#else
+void *GKI_getpoolbuf (UINT8 pool_id)
+#endif
+{
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (NULL);
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
+#endif
+    /* Make sure the buffers aren't disturbed til finished with allocation */
+    GKI_disable();
+
+    Q = &p_cb->freeq[pool_id];
+    if(Q->cur_cnt < Q->total)
+    {
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+        if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
+            return NULL;
+#endif
+        p_hdr = Q->p_first;
+        Q->p_first = p_hdr->p_next;
+
+        if (!Q->p_first)
+            Q->p_last = NULL;
+
+        if(++Q->cur_cnt > Q->max_cnt)
+            Q->max_cnt = Q->cur_cnt;
+
+        GKI_enable();
+
+
+        p_hdr->task_id = GKI_get_taskid();
+
+        p_hdr->status  = BUF_STATUS_UNLINKED;
+        p_hdr->p_next  = NULL;
+        p_hdr->Type    = 0;
+
+#if GKI_BUFFER_DEBUG
+        LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);
+
+        strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+        p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+        p_hdr->_line = _line_;
+#endif
+        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+    }
+
+    /* If here, no buffers in the specified pool */
+    GKI_enable();
+
+#if GKI_BUFFER_DEBUG
+    /* try for free buffers in public pools */
+    return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
+#else
+    /* try for free buffers in public pools */
+    return (GKI_getbuf(p_cb->freeq[pool_id].size));
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_freebuf
+**
+** Description      Called by an application to return a buffer to the free pool.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_freebuf (void *p_buf)
+{
+    FREE_QUEUE_T    *Q;
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (!p_buf || gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
+#endif
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
+        return;
+    }
+
+    if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
+        return;
+    }
+
+    GKI_disable();
+
+    /*
+    ** Release the buffer
+    */
+    Q  = &gki_cb.com.freeq[p_hdr->q_id];
+    if (Q->p_last)
+        Q->p_last->p_next = p_hdr;
+    else
+        Q->p_first = p_hdr;
+
+    Q->p_last      = p_hdr;
+    p_hdr->p_next  = NULL;
+    p_hdr->status  = BUF_STATUS_FREE;
+    p_hdr->task_id = GKI_INVALID_TASK;
+    if (Q->cur_cnt > 0)
+        Q->cur_cnt--;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_buf_size
+**
+** Description      Called by an application to get the size of a buffer.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          the size of the buffer
+**
+*******************************************************************************/
+UINT16 GKI_get_buf_size (void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if ((UINT32)p_hdr & 1)
+        return (0);
+
+    if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        return (gki_cb.com.freeq[p_hdr->q_id].size);
+    }
+
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         gki_chk_buf_damage
+**
+** Description      Called internally by OSS to check for buffer corruption.
+**
+** Returns          TRUE if there is a problem, else FALSE
+**
+*******************************************************************************/
+BOOLEAN gki_chk_buf_damage(void *p_buf)
+{
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+
+    UINT32 *magic;
+    magic  = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
+
+    if ((UINT32)magic & 1)
+        return (TRUE);
+
+    if (*magic == MAGIC_NO)
+        return (FALSE);
+
+    return (TRUE);
+
+#else
+
+    return (FALSE);
+
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_send_msg
+**
+** Description      Called by applications to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+    BUFFER_HDR_T    *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* If task non-existant or not started, drop buffer */
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+        GKI_freebuf (msg);
+        return;
+    }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(msg))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+        return;
+    }
+
+    GKI_disable();
+
+    if (p_cb->OSTaskQFirst[task_id][mbox])
+        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+    else
+        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+    p_hdr->task_id = task_id;
+
+
+    GKI_enable();
+
+    GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_read_mbox
+**
+** Description      Called by applications to read a buffer from one of
+**                  the task mailboxes.  A task can only read its own mailbox.
+**
+** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
+**
+** Returns          NULL if the mailbox was empty, else the address of a buffer
+**
+*******************************************************************************/
+void *GKI_read_mbox (UINT8 mbox)
+{
+    UINT8           task_id = GKI_get_taskid();
+    void            *p_buf = NULL;
+    BUFFER_HDR_T    *p_hdr;
+
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
+        return (NULL);
+
+    GKI_disable();
+
+    if (gki_cb.com.OSTaskQFirst[task_id][mbox])
+    {
+        p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
+        gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
+
+        p_hdr->p_next = NULL;
+        p_hdr->status = BUF_STATUS_UNLINKED;
+
+        p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
+    }
+
+    GKI_enable();
+
+    return (p_buf);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue
+**
+** Description      Enqueue a buffer at the tail of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
+        return;
+    }
+
+    GKI_disable();
+
+    /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
+    if (p_q->p_first)
+    {
+        BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
+        p_last_hdr->p_next = p_hdr;
+    }
+    else
+        p_q->p_first = p_buf;
+
+    p_q->p_last = p_buf;
+    p_q->count++;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue_head
+**
+** Description      Enqueue a buffer at the head of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
+        return;
+    }
+
+    GKI_disable();
+
+    if (p_q->p_first)
+    {
+        p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+        p_q->p_first = p_buf;
+    }
+    else
+    {
+        p_q->p_first = p_buf;
+        p_q->p_last  = p_buf;
+        p_hdr->p_next = NULL;
+    }
+    p_q->count++;
+
+    p_hdr->status = BUF_STATUS_QUEUED;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_dequeue
+**
+** Description      Dequeues a buffer from the head of a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_dequeue (BUFFER_Q *p_q)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    GKI_disable();
+
+    if (!p_q || !p_q->count)
+    {
+        GKI_enable();
+        return (NULL);
+    }
+
+    p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+    /* Keep buffers such that GKI header is invisible
+    */
+    if (p_hdr->p_next)
+        p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+    else
+    {
+        p_q->p_first = NULL;
+        p_q->p_last  = NULL;
+    }
+
+    p_q->count--;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_UNLINKED;
+
+    GKI_enable();
+
+    return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_queue
+**
+** Description      Dequeue a buffer from the middle of the queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_prev;
+    BUFFER_HDR_T    *p_buf_hdr;
+
+    GKI_disable();
+
+    if (p_buf == p_q->p_first)
+    {
+        GKI_enable();
+        return (GKI_dequeue (p_q));
+    }
+
+    p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+    p_prev    = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+    for ( ; p_prev; p_prev = p_prev->p_next)
+    {
+        /* If the previous points to this one, move the pointers around */
+        if (p_prev->p_next == p_buf_hdr)
+        {
+            p_prev->p_next = p_buf_hdr->p_next;
+
+            /* If we are removing the last guy in the queue, update p_last */
+            if (p_buf == p_q->p_last)
+                p_q->p_last = p_prev + 1;
+
+            /* One less in the queue */
+            p_q->count--;
+
+            /* The buffer is now unlinked */
+            p_buf_hdr->p_next = NULL;
+            p_buf_hdr->status = BUF_STATUS_UNLINKED;
+
+            GKI_enable();
+            return (p_buf);
+        }
+    }
+
+    GKI_enable();
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getfirst
+**
+** Description      Return a pointer to the first buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getfirst (BUFFER_Q *p_q)
+{
+    return (p_q->p_first);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getlast
+**
+** Description      Return a pointer to the last buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getlast (BUFFER_Q *p_q)
+{
+    return (p_q->p_last);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getnext
+**
+** Description      Return a pointer to the next buffer in a queue
+**
+** Parameters:      p_buf  - (input) pointer to the buffer to find the next one from.
+**
+** Returns          NULL if no more buffers in the queue, else next buffer address
+**
+*******************************************************************************/
+void *GKI_getnext (void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->p_next)
+        return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+    else
+        return (NULL);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         GKI_queue_is_empty
+**
+** Description      Check the status of a queue.
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          TRUE if queue is empty, else FALSE
+**
+*******************************************************************************/
+BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
+{
+    return ((BOOLEAN) (p_q->count == 0));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_find_buf_start
+**
+** Description      This function is called with an address inside a buffer,
+**                  and returns the start address ofthe buffer.
+**
+**                  The buffer should be one allocated from one of GKI's pools.
+**
+** Parameters:      p_user_area - (input) address of anywhere in a GKI buffer.
+**
+** Returns          void * - Address of the beginning of the specified buffer if successful,
+**                          otherwise NULL if unsuccessful
+**
+*******************************************************************************/
+void *GKI_find_buf_start (void *p_user_area)
+{
+    UINT16       xx, size;
+    UINT32       yy;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    UINT8       *p_ua = (UINT8 *)p_user_area;
+
+    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+    {
+        if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
+        {
+            yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
+
+            size = p_cb->pool_size[xx];
+
+            yy = (yy / size) * size;
+
+            return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
+        }
+    }
+
+    /* If here, invalid address - not in one of our buffers */
+    GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
+
+    return (NULL);
+}
+
+
+/********************************************************
+* The following functions are not needed for light stack
+*********************************************************/
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+
+/*******************************************************************************
+**
+** Function         GKI_set_pool_permission
+**
+** Description      This function is called to set or change the permissions for
+**                  the specified pool ID.
+**
+** Parameters       pool_id -       (input) pool ID to be set or changed
+**                  permission -    (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
+**
+** Returns          GKI_SUCCESS if successful
+**                  GKI_INVALID_POOL if unsuccessful
+**
+*******************************************************************************/
+UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
+{
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        if (permission == GKI_RESTRICTED_POOL)
+            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
+
+        else    /* mark the pool as public */
+            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
+
+        return (GKI_SUCCESS);
+    }
+    else
+        return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         gki_add_to_pool_list
+**
+** Description      Adds pool to the pool list which is arranged in the
+**                  order of size
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_add_to_pool_list(UINT8 pool_id)
+{
+
+    INT32 i, j;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+     /* Find the position where the specified pool should be inserted into the list */
+    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+
+        if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
+            break;
+    }
+
+    /* Insert the new buffer pool ID into the list of pools */
+    for(j = p_cb->curr_total_no_of_pools; j > i; j--)
+    {
+        p_cb->pool_list[j] = p_cb->pool_list[j-1];
+    }
+
+    p_cb->pool_list[i] = pool_id;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_remove_from_pool_list
+**
+** Description      Removes pool from the pool list. Called when a pool is deleted
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_remove_from_pool_list(UINT8 pool_id)
+{
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    UINT8 i;
+
+    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        if(pool_id == p_cb->pool_list[i])
+            break;
+    }
+
+    while (i < (p_cb->curr_total_no_of_pools - 1))
+    {
+        p_cb->pool_list[i] = p_cb->pool_list[i+1];
+        i++;
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_igetpoolbuf
+**
+** Description      Called by an interrupt service routine to get a free buffer from
+**                  a specific buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+void *GKI_igetpoolbuf (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (NULL);
+
+
+    Q = &gki_cb.com.freeq[pool_id];
+    if(Q->cur_cnt < Q->total)
+    {
+        p_hdr = Q->p_first;
+        Q->p_first = p_hdr->p_next;
+
+        if (!Q->p_first)
+            Q->p_last = NULL;
+
+        if(++Q->cur_cnt > Q->max_cnt)
+            Q->max_cnt = Q->cur_cnt;
+
+        p_hdr->task_id = GKI_get_taskid();
+
+        p_hdr->status  = BUF_STATUS_UNLINKED;
+        p_hdr->p_next  = NULL;
+        p_hdr->Type    = 0;
+
+        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+    }
+
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolcount
+**
+** Description      Called by an application to get the total number of buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the total number of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolcount (UINT8 pool_id)
+{
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (0);
+
+    return (gki_cb.com.freeq[pool_id].total);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolfreecount
+**
+** Description      Called by an application to get the number of free buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the number of free buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolfreecount (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (0);
+
+    Q  = &gki_cb.com.freeq[pool_id];
+
+    return ((UINT16)(Q->total - Q->cur_cnt));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_change_buf_owner
+**
+** Description      Called to change the task ownership of a buffer.
+**
+** Parameters:      p_buf   - (input) pointer to the buffer
+**                  task_id - (input) task id to change ownership to
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
+{
+    BUFFER_HDR_T    *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    p_hdr->task_id = task_id;
+
+    return;
+}
+
+#if (defined(GKI_SEND_MSG_FROM_ISR) &&  GKI_SEND_MSG_FROM_ISR == TRUE)
+/*******************************************************************************
+**
+** Function         GKI_isend_msg
+**
+** Description      Called from interrupt context to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+    BUFFER_HDR_T    *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* If task non-existant or not started, drop buffer */
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+        GKI_freebuf (msg);
+        return;
+    }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(msg))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+        return;
+    }
+#endif
+
+#if (GKI_ENABLE_OWNER_CHECK == TRUE)
+    if (gki_chk_buf_owner(msg))
+    {
+        GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+        return;
+    }
+
+    if (p_cb->OSTaskQFirst[task_id][mbox])
+        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+    else
+        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+    p_hdr->task_id = task_id;
+
+    GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+    return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_create_pool
+**
+** Description      Called by applications to create a buffer pool.
+**
+** Parameters:      size        - (input) length (in bytes) of each buffer in the pool
+**                  count       - (input) number of buffers to allocate for the pool
+**                  permission  - (input) restricted or public access?
+**                                        (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
+**                  p_mem_pool  - (input) pointer to an OS memory pool, NULL if not provided
+**
+** Returns          the buffer pool ID, which should be used in calls to
+**                  GKI_getpoolbuf(). If a pool could not be created, this
+**                  function returns 0xff.
+**
+*******************************************************************************/
+UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
+{
+    UINT8        xx;
+    UINT32       mem_needed;
+    INT32        tempsize = size;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* First make sure the size of each pool has a valid size with room for the header info */
+    if (size > MAX_USER_BUF_SIZE)
+        return (GKI_INVALID_POOL);
+
+    /* First, look for an unused pool */
+    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+    {
+        if (!p_cb->pool_start[xx])
+            break;
+    }
+
+    if (xx == GKI_NUM_TOTAL_BUF_POOLS)
+        return (GKI_INVALID_POOL);
+
+    /* Ensure an even number of longwords */
+    tempsize = (INT32)ALIGN_POOL(size);
+
+    mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
+
+    if (!p_mem_pool)
+        p_mem_pool = GKI_os_malloc(mem_needed);
+
+    if (p_mem_pool)
+    {
+        /* Initialize the new pool */
+        gki_init_free_queue (xx, size, count, p_mem_pool);
+        gki_add_to_pool_list(xx);
+        (void) GKI_set_pool_permission (xx, permission);
+        p_cb->curr_total_no_of_pools++;
+
+        return (xx);
+    }
+    else
+        return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_delete_pool
+**
+** Description      Called by applications to delete a buffer pool.  The function
+**                  calls the operating specific function to free the actual memory.
+**                  An exception is generated if an error is detected.
+**
+** Parameters:      pool_id - (input) Id of the poll being deleted.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_delete_pool (UINT8 pool_id)
+{
+    FREE_QUEUE_T    *Q;
+    tGKI_COM_CB     *p_cb = &gki_cb.com;
+
+    if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
+        return;
+
+    GKI_disable();
+    Q  = &p_cb->freeq[pool_id];
+
+    if (!Q->cur_cnt)
+    {
+        Q->size      = 0;
+        Q->total     = 0;
+        Q->cur_cnt   = 0;
+        Q->max_cnt   = 0;
+        Q->p_first   = NULL;
+        Q->p_last    = NULL;
+
+        GKI_os_free (p_cb->pool_start[pool_id]);
+
+        p_cb->pool_start[pool_id] = NULL;
+        p_cb->pool_end[pool_id]   = NULL;
+        p_cb->pool_size[pool_id]  = 0;
+
+        gki_remove_from_pool_list(pool_id);
+        p_cb->curr_total_no_of_pools--;
+    }
+    else
+        GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
+
+    GKI_enable();
+
+    return;
+}
+
+#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
+
+/*******************************************************************************
+**
+** Function         GKI_get_pool_bufsize
+**
+** Description      Called by an application to get the size of buffers in a pool
+**
+** Parameters       Pool ID.
+**
+** Returns          the size of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
+{
+    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+        return (gki_cb.com.freeq[pool_id].size);
+
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolutilization
+**
+** Description      Called by an application to get the buffer utilization
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          % of buffers used from 0 to 100
+**
+*******************************************************************************/
+UINT16 GKI_poolutilization (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (100);
+
+    Q  = &gki_cb.com.freeq[pool_id];
+
+    if (Q->total == 0)
+        return (100);
+
+    return ((Q->cur_cnt * 100) / Q->total);
+}
+
diff --git a/halimpl/bcm2079x/gki/common/gki_common.h b/halimpl/bcm2079x/gki/common/gki_common.h
new file mode 100644
index 0000000..2bd9f8f
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_common.h
@@ -0,0 +1,393 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_COMMON_H
+#define GKI_COMMON_H
+
+#include "gki.h"
+#include "dyn_mem.h"
+
+#ifndef GKI_DEBUG
+#define GKI_DEBUG	FALSE
+#endif
+
+/* Task States: (For OSRdyTbl) */
+#define TASK_DEAD       0   /* b0000 */
+#define TASK_READY      1   /* b0001 */
+#define TASK_WAIT       2   /* b0010 */
+#define TASK_DELAY      4   /* b0100 */
+#define TASK_SUSPEND    8   /* b1000 */
+
+
+/********************************************************************
+**  Internal Error codes
+*********************************************************************/
+#define GKI_ERROR_BUF_CORRUPTED         0xFFFF
+#define GKI_ERROR_NOT_BUF_OWNER         0xFFFE
+#define GKI_ERROR_FREEBUF_BAD_QID       0xFFFD
+#define GKI_ERROR_FREEBUF_BUF_LINKED    0xFFFC
+#define GKI_ERROR_SEND_MSG_BAD_DEST     0xFFFB
+#define GKI_ERROR_SEND_MSG_BUF_LINKED   0xFFFA
+#define GKI_ERROR_ENQUEUE_BUF_LINKED    0xFFF9
+#define GKI_ERROR_DELETE_POOL_BAD_QID   0xFFF8
+#define GKI_ERROR_BUF_SIZE_TOOBIG       0xFFF7
+#define GKI_ERROR_BUF_SIZE_ZERO         0xFFF6
+#define GKI_ERROR_ADDR_NOT_IN_BUF       0xFFF5
+
+
+/********************************************************************
+**  Misc constants
+*********************************************************************/
+
+#define GKI_MAX_INT32           (0x7fffffffL)
+#define GKI_MAX_TIMESTAMP       (0xffffffffL)
+
+/********************************************************************
+**  Buffer Management Data Structures
+*********************************************************************/
+
+typedef struct _buffer_hdr
+{
+    struct _buffer_hdr *p_next;   /* next buffer in the queue */
+    UINT8   q_id;                 /* id of the queue */
+    UINT8   task_id;              /* task which allocated the buffer*/
+    UINT8   status;               /* FREE, UNLINKED or QUEUED */
+    UINT8   Type;
+
+#if GKI_BUFFER_DEBUG
+    /* for tracking who allocated the buffer */
+    #define _GKI_MAX_FUNCTION_NAME_LEN   (50)
+    char    _function[_GKI_MAX_FUNCTION_NAME_LEN+1];
+    int     _line;
+#endif
+
+} BUFFER_HDR_T;
+
+typedef struct _free_queue
+{
+    BUFFER_HDR_T *p_first;      /* first buffer in the queue */
+    BUFFER_HDR_T *p_last;       /* last buffer in the queue */
+    UINT16          size;          /* size of the buffers in the pool */
+    UINT16          total;         /* toatal number of buffers */
+    UINT16          cur_cnt;       /* number of  buffers currently allocated */
+    UINT16          max_cnt;       /* maximum number of buffers allocated at any time */
+} FREE_QUEUE_T;
+
+
+/* Buffer related defines
+*/
+#define ALIGN_POOL(pl_size)  ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
+#define BUFFER_HDR_SIZE     (sizeof(BUFFER_HDR_T))                  /* Offset past header */
+#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
+#define MAX_USER_BUF_SIZE   ((UINT16)0xffff - BUFFER_PADDING_SIZE)  /* pool size must allow for header */
+#define MAGIC_NO            0xDDBADDBA
+
+#define BUF_STATUS_FREE     0
+#define BUF_STATUS_UNLINKED 1
+#define BUF_STATUS_QUEUED   2
+
+#define GKI_USE_DEFERED_ALLOC_BUF_POOLS
+
+/* Exception related structures (Used in debug mode only)
+*/
+#if (GKI_DEBUG == TRUE)
+typedef struct
+{
+    UINT16  type;
+    UINT8   taskid;
+    UINT8   msg[GKI_MAX_EXCEPTION_MSGLEN];
+} EXCEPTION_T;
+#endif
+
+
+/* Put all GKI variables into one control block
+*/
+typedef struct
+{
+    /* Task management variables
+    */
+    /* The stack and stack size are not used on Windows
+    */
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == FALSE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    UINT8 bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    UINT8 bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    UINT8 bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    UINT8 bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    UINT8 bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    UINT8 bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    UINT8 bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    UINT8 bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    UINT8 bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    UINT8 bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    UINT8 bufpool10[(ALIGN_POOL(GKI_BUF10_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    UINT8 bufpool11[(ALIGN_POOL(GKI_BUF11_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    UINT8 bufpool12[(ALIGN_POOL(GKI_BUF12_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    UINT8 bufpool13[(ALIGN_POOL(GKI_BUF13_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    UINT8 bufpool14[(ALIGN_POOL(GKI_BUF14_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    UINT8 bufpool15[(ALIGN_POOL(GKI_BUF15_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX];
+#endif
+
+#else
+/* Definitions for dynamic buffer use */
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    UINT8 *bufpool0;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    UINT8 *bufpool1;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    UINT8 *bufpool2;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    UINT8 *bufpool3;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    UINT8 *bufpool4;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    UINT8 *bufpool5;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    UINT8 *bufpool6;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    UINT8 *bufpool7;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    UINT8 *bufpool8;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    UINT8 *bufpool9;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    UINT8 *bufpool10;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    UINT8 *bufpool11;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    UINT8 *bufpool12;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    UINT8 *bufpool13;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    UINT8 *bufpool14;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    UINT8 *bufpool15;
+#endif
+
+#endif
+
+    UINT8  *OSStack[GKI_MAX_TASKS];         /* pointer to beginning of stack */
+    UINT16  OSStackSize[GKI_MAX_TASKS];     /* stack size available to each task */
+
+
+    INT8   *OSTName[GKI_MAX_TASKS];         /* name of the task */
+
+    UINT8   OSRdyTbl[GKI_MAX_TASKS];        /* current state of the task */
+    UINT16  OSWaitEvt[GKI_MAX_TASKS];       /* events that have to be processed by the task */
+    UINT16  OSWaitForEvt[GKI_MAX_TASKS];    /* events the task is waiting for*/
+
+    UINT32  OSTicks;                        /* system ticks from start */
+    UINT32  OSIdleCnt;                      /* idle counter */
+    INT16   OSDisableNesting;               /* counter to keep track of interrupt disable nesting */
+    INT16   OSLockNesting;                  /* counter to keep track of sched lock nesting */
+    INT16   OSIntNesting;                   /* counter to keep track of interrupt nesting */
+
+    /* Timer related variables
+    */
+    INT32   OSTicksTilExp;      /* Number of ticks till next timer expires */
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    UINT32  OSTicksTilStop;     /* inactivity delay timer; OS Ticks till stopping system tick */
+#endif
+    INT32   OSNumOrigTicks;     /* Number of ticks between last timer expiration to the next one */
+
+    INT32   OSWaitTmr   [GKI_MAX_TASKS];  /* ticks the task has to wait, for specific events */
+
+    /* Only take up space timers used in the system (GKI_NUM_TIMERS defined in target.h) */
+#if (GKI_NUM_TIMERS > 0)
+    INT32   OSTaskTmr0  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr0R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    INT32   OSTaskTmr1  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr1R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    INT32   OSTaskTmr2  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr2R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    INT32   OSTaskTmr3  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr3R [GKI_MAX_TASKS];
+#endif
+
+
+
+    /* Buffer related variables
+    */
+    BUFFER_HDR_T    *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
+    BUFFER_HDR_T    *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
+
+    /* Define the buffer pool management variables
+    */
+    FREE_QUEUE_T    freeq[GKI_NUM_TOTAL_BUF_POOLS];
+
+    UINT16   pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
+    UINT16   pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
+    UINT16   pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
+
+    /* Define the buffer pool start addresses
+    */
+    UINT8   *pool_start[GKI_NUM_TOTAL_BUF_POOLS];   /* array of pointers to the start of each buffer pool */
+    UINT8   *pool_end[GKI_NUM_TOTAL_BUF_POOLS];     /* array of pointers to the end of each buffer pool */
+    UINT16   pool_size[GKI_NUM_TOTAL_BUF_POOLS];    /* actual size of the buffers in a pool */
+
+    /* Define the buffer pool access control variables */
+    void        *p_user_mempool;                    /* User O/S memory pool */
+    UINT16      pool_access_mask;                   /* Bits are set if the corresponding buffer pool is a restricted pool */
+    UINT8       pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */
+    UINT8       curr_total_no_of_pools;             /* number of fixed buf pools + current number of dynamic pools */
+
+    BOOLEAN     timer_nesting;                      /* flag to prevent timer interrupt nesting */
+
+    /* Time queue arrays */
+    TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
+    /* System tick callback */
+    SYSTEM_TICK_CBACK *p_tick_cb;
+    BOOLEAN     system_tick_running;                /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
+
+#if (GKI_DEBUG == TRUE)
+    UINT16      ExceptionCnt;                       /* number of GKI exceptions that have happened */
+    EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
+#endif
+
+} tGKI_COM_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal GKI function prototypes
+*/
+GKI_API extern BOOLEAN   gki_chk_buf_damage(void *);
+extern BOOLEAN   gki_chk_buf_owner(void *);
+extern void      gki_buffer_init (void);
+extern void      gki_timers_init(void);
+extern void      gki_adjust_timer_count (INT32);
+
+extern void    OSStartRdy(void);
+extern void	   OSCtxSw(void);
+extern void	   OSIntCtxSw(void);
+extern void    OSSched(void);
+extern void    OSIntEnter(void);
+extern void    OSIntExit(void);
+
+
+/* Debug aids
+*/
+typedef void  (*FP_PRINT)(char *, ...);
+
+#if (GKI_DEBUG == TRUE)
+
+typedef void  (*PKT_PRINT)(UINT8 *, UINT16);
+
+extern void gki_print_task(FP_PRINT);
+extern void gki_print_exception(FP_PRINT);
+extern void gki_print_timer(FP_PRINT);
+extern void gki_print_stack(FP_PRINT);
+extern void gki_print_buffer(FP_PRINT);
+extern void gki_print_buffer_statistics(FP_PRINT, INT16);
+GKI_API extern void gki_print_used_bufs (FP_PRINT, UINT8);
+extern void gki_dump(UINT8 *, UINT16, FP_PRINT);
+extern void gki_dump2(UINT16 *, UINT16, FP_PRINT);
+extern void gki_dump4(UINT32 *, UINT16, FP_PRINT);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/halimpl/bcm2079x/gki/common/gki_debug.c b/halimpl/bcm2079x/gki/common/gki_debug.c
new file mode 100644
index 0000000..481ba16
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_debug.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#if (GKI_DEBUG == TRUE)
+
+const INT8 * const OSTaskStates[] =
+{
+    (INT8 *)"DEAD",  /* 0 */
+    (INT8 *)"REDY",  /* 1 */
+    (INT8 *)"WAIT",  /* 2 */
+    (INT8 *)"",
+    (INT8 *)"DELY",  /* 4 */
+    (INT8 *)"",
+    (INT8 *)"",
+    (INT8 *)"",
+    (INT8 *)"SUSP",  /* 8 */
+};
+
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBufferUsage
+**
+** Description      Displays Current Buffer Pool summary
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used)
+{
+    int i;
+    FREE_QUEUE_T    *p;
+    UINT8   num = gki_cb.com.curr_total_no_of_pools;
+    UINT16   cur[GKI_NUM_TOTAL_BUF_POOLS];
+
+    GKI_TRACE_0("");
+    GKI_TRACE_0("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
+
+    GKI_TRACE_0("POOL     SIZE  USED  MAXU  TOTAL");
+    GKI_TRACE_0("------------------------------");
+    for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++)
+    {
+        p = &gki_cb.com.freeq[i];
+        if ((1 << i) & gki_cb.com.pool_access_mask)
+        {
+            GKI_TRACE_5("%02d: (R), %4d, %3d, %3d, %3d",
+                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
+        }
+        else
+        {
+            GKI_TRACE_5("%02d: (P), %4d, %3d, %3d, %3d",
+                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
+        }
+        cur[i] = p->cur_cnt;
+    }
+    if (p_num_pools)
+        *p_num_pools = num;
+    if (p_cur_used)
+        memcpy(p_cur_used, cur, num*2);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBuffer
+**
+** Description      Called internally by OSS to print the buffer pools
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBuffer(void)
+{
+    UINT16 i;
+    for(i=0; i<GKI_NUM_TOTAL_BUF_POOLS; i++)
+    {
+        GKI_TRACE_5("pool:%4u free %4u cur %3u max %3u  total%3u", i, gki_cb.com.freeq[i].size,
+                    gki_cb.com.freeq[i].cur_cnt, gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         gki_calc_stack
+**
+** Description      This function tries to calculate the amount of
+**                  stack used by looking non magic num. Magic num is consider
+**                  the first byte in the stack.
+**
+** Returns          the number of unused byte on the stack. 4 in case of stack overrun
+**
+*******************************************************************************/
+UINT16 gki_calc_stack (UINT8 task)
+{
+    int    j, stacksize;
+    UINT32 MagicNum;
+    UINT32 *p;
+
+    stacksize = (int) gki_cb.com.OSStackSize[task];
+    p = (UINT32 *)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
+    MagicNum = *p;
+
+    for(j = 0; j < stacksize; j++)
+    {
+        if(*p++ != MagicNum) break;
+    }
+
+    return (j * sizeof(UINT32));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_print_task
+**
+** Description      Print task stack usage.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_print_task(void)
+{
+#ifdef _BT_WIN32
+	GKI_TRACE_0("Service not available under insight");
+#else
+    UINT8 TaskId;
+
+    GKI_TRACE_0("TID TASKNAME STATE FREE_STACK  STACK");
+    for(TaskId=0; TaskId < GKI_MAX_TASKS; TaskId++)
+    {
+        if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD)
+        {
+            GKI_TRACE_5("%2u   %-8s %-5s  0x%04X     0x%04X Bytes",
+                (UINT16)TaskId,  gki_cb.com.OSTName[TaskId],
+                OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
+                gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
+
+        }
+    }
+#endif
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_buffer_statistics
+**
+** Description      Called internally by OSS to print the buffer pools statistics
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_buffer_statistics(FP_PRINT print, INT16 pool)
+{
+    UINT16           i;
+    BUFFER_HDR_T    *hdr;
+    UINT16           size,act_size,maxbuffs;
+    UINT32           *magic;
+
+    if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0)
+    {
+        print("Not a valid Buffer pool\n");
+        return;
+    }
+
+    size = gki_cb.com.freeq[pool].size;
+    maxbuffs = gki_cb.com.freeq[pool].total;
+    act_size = size + BUFFER_PADDING_SIZE;
+    print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u  total=%u\n",
+        pool, gki_cb.com.freeq[pool].size,
+        gki_cb.com.freeq[pool].cur_cnt, gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
+
+    print("      Owner  State    Sanity\n");
+    print("----------------------------\n");
+    hdr = (BUFFER_HDR_T *)(gki_cb.com.pool_start[pool]);
+    for(i=0; i<maxbuffs; i++)
+    {
+        magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + size);
+        print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status, (*magic == MAGIC_NO)?"OK":"CORRUPTED");
+        hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+    }
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_used_bufs
+**
+** Description      Dumps used buffers in the particular pool
+**
+*******************************************************************************/
+GKI_API void gki_print_used_bufs (FP_PRINT print, UINT8 pool_id)
+{
+    UINT8        *p_start;
+    UINT16       buf_size;
+    UINT16       num_bufs;
+    BUFFER_HDR_T *p_hdr;
+    UINT16       i;
+    UINT32         *magic;
+    UINT16       *p;
+
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS && gki_cb.com.pool_start[pool_id] != 0)
+    {
+        print("Not a valid Buffer pool\n");
+        return;
+    }
+
+    p_start = gki_cb.com.pool_start[pool_id];
+    buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
+    num_bufs = gki_cb.com.freeq[pool_id].total;
+
+    for (i = 0; i < num_bufs; i++, p_start += buf_size)
+    {
+        p_hdr = (BUFFER_HDR_T *)p_start;
+        magic = (UINT32 *)((UINT8 *)p_hdr + buf_size - sizeof(UINT32));
+        p     = (UINT16 *) p_hdr;
+
+        if (p_hdr->status != BUF_STATUS_FREE)
+        {
+            print ("%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x %04x %04x\n",
+                i, p_hdr,
+                p_hdr->q_id,
+                GKI_map_taskname(p_hdr->task_id),
+                p_hdr->status,
+                (*magic == MAGIC_NO)? "OK" : "CORRUPTED",
+                p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_task
+**
+** Description      This function prints the task states.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_task (FP_PRINT print)
+{
+    UINT8 i;
+
+    print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
+    print("-------------------------------------------------\n");
+    for(i=0; i<GKI_MAX_TASKS; i++)
+    {
+        if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD)
+        {
+            print("%2u  %-8s %-5s %04X    %04X %7u %u/%u Bytes\n",
+                (UINT16)i,  gki_cb.com.OSTName[i],
+                OSTaskStates[gki_cb.com.OSRdyTbl[i]],
+                gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
+                gki_cb.com.OSWaitTmr[i], gki_calc_stack(i), gki_cb.com.OSStackSize[i]);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_exception
+**
+** Description      This function prints the exception information.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_exception(FP_PRINT print)
+{
+    UINT16 i;
+    EXCEPTION_T *pExp;
+
+    print ("GKI Exceptions:\n");
+    for (i = 0; i < gki_cb.com.ExceptionCnt; i++)
+    {
+        pExp =     &gki_cb.com.Exception[i];
+        print("%d: Type=%d, Task=%d: %s\n", i,
+            (INT32)pExp->type, (INT32)pExp->taskid, (INT8 *)pExp->msg);
+    }
+}
+
+
+/*****************************************************************************/
+void gki_dump (UINT8 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %02X, ", &s[i], s[i]);
+        else if(j == 7)
+            print("%02X,  ", s[i]);
+        else
+            print("%02X, ", s[i]);
+        if(++j == 16)
+            j=0;
+    }
+    print("\n");
+}
+
+void gki_dump2 (UINT16 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %04X, ", &s[i], s[i]);
+        else
+            print("%04X, ", s[i]);
+        if(++j == 8)
+            j=0;
+    }
+    print("\n");
+}
+
+void gki_dump4 (UINT32 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %08lX, ", &s[i], s[i]);
+        else
+            print("%08lX, ", s[i]);
+        if(++j == 4)
+            j=0;
+    }
+    print("\n");
+}
+
+
+#endif
diff --git a/halimpl/bcm2079x/gki/common/gki_inet.h b/halimpl/bcm2079x/gki/common/gki_inet.h
new file mode 100644
index 0000000..569c4fd
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_inet.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_INET_H
+#define GKI_INET_H
+
+#include "data_types.h"
+
+#define htons   ntohs
+#define htonl   ntohl
+
+#define htonets	nettohs
+#define htonetl	nettohl
+
+#if BIG_ENDIAN == TRUE
+#define ntohs(n) (n)
+#define ntohl(n) (n)
+#define ntoh6(n) (n)
+
+#define nettohs(n) (n)
+#define nettohl(n) (n)
+#else
+extern UINT16 ntohs(UINT16 n);
+extern UINT32 ntohl(UINT32 n);
+extern UINT8 *ntoh6(UINT8 *p);
+
+#define nettohs(n) ((UINT16)((((n) << 8) & 0xff00) | (((n) >> 8) & 0x00ff)))
+#define nettohl(n) ((((n) & 0x000000ff) << 24) | (((n) << 8) & 0x00ff0000) | \
+                   (((n) >> 8) & 0x0000ff00) | (((n) >> 24) & 0x000000ff))
+#endif
+
+#endif /* GKI_INET_H */
+
diff --git a/halimpl/bcm2079x/gki/common/gki_time.c b/halimpl/bcm2079x/gki/common/gki_time.c
new file mode 100644
index 0000000..10377f6
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_time.c
@@ -0,0 +1,1011 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#ifndef BT_ERROR_TRACE_0
+#define BT_ERROR_TRACE_0(l,m)
+#endif
+
+/* Make sure that this has been defined in target.h */
+#ifndef GKI_NUM_TIMERS
+#error  NO TIMERS: Must define at least 1 timer in the system!
+#endif
+
+
+#define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)   /* Largest signed positive timer count */
+#define GKI_UNUSED_LIST_ENTRY   (0x80000000L)   /* Marks an unused timer list entry (initial value) */
+#define GKI_MAX_INT32           (0x7fffffffL)
+
+/*******************************************************************************
+**
+** Function         gki_timers_init
+**
+** Description      This internal function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_timers_init(void)
+{
+    UINT8   tt;
+
+    gki_cb.com.OSTicksTilExp = 0;       /* Remaining time (of OSTimeCurTimeout) before next timer expires */
+    gki_cb.com.OSNumOrigTicks = 0;
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
+#endif
+
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+        gki_cb.com.OSWaitTmr   [tt] = 0;
+
+#if (GKI_NUM_TIMERS > 0)
+        gki_cb.com.OSTaskTmr0  [tt] = 0;
+        gki_cb.com.OSTaskTmr0R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        gki_cb.com.OSTaskTmr1  [tt] = 0;
+        gki_cb.com.OSTaskTmr1R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        gki_cb.com.OSTaskTmr2  [tt] = 0;
+        gki_cb.com.OSTaskTmr2R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        gki_cb.com.OSTaskTmr3  [tt] = 0;
+        gki_cb.com.OSTaskTmr3R [tt] = 0;
+#endif
+    }
+
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+    {
+        gki_cb.com.timer_queues[tt] = NULL;
+    }
+
+    gki_cb.com.p_tick_cb = NULL;
+    gki_cb.com.system_tick_running = FALSE;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_timers_is_timer_running
+**
+** Description      This internal function is called to test if any gki timer are running
+**
+**
+** Returns          TRUE if at least one time is running in the system, FALSE else.
+**
+*******************************************************************************/
+BOOLEAN gki_timers_is_timer_running(void)
+{
+    UINT8   tt;
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+
+#if (GKI_NUM_TIMERS > 0)
+        if(gki_cb.com.OSTaskTmr0  [tt])
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        if(gki_cb.com.OSTaskTmr1  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        if(gki_cb.com.OSTaskTmr2  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        if(gki_cb.com.OSTaskTmr3  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+    }
+
+    return FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_tick_count
+**
+** Description      This function returns the current system ticks
+**
+** Returns          The current number of system ticks
+**
+*******************************************************************************/
+UINT32  GKI_get_tick_count(void)
+{
+    return gki_cb.com.OSTicks;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_ready_to_sleep
+**
+** Description      This function returns the number of system ticks until the
+**                  next timer will expire.  It is typically called by a power
+**                  savings manager to find out how long it can have the system
+**                  sleep before it needs to service the next entry.
+**
+** Parameters:      None
+**
+** Returns          Number of ticks til the next timer expires
+**                  Note: the value is a signed  value.  This value should be
+**                      compared to x > 0, to avoid misinterpreting negative tick
+**                      values.
+**
+*******************************************************************************/
+INT32    GKI_ready_to_sleep (void)
+{
+    return (gki_cb.com.OSTicksTilExp);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_start_timer
+**
+** Description      An application can call this function to start one of
+**                  it's four general purpose timers. Any of the four timers
+**                  can be 1-shot or continuous. If a timer is already running,
+**                  it will be reset to the new parameters.
+**
+** Parameters       tnum            - (input) timer number to be started (TIMER_0,
+**                                              TIMER_1, TIMER_2, or TIMER_3)
+**                  ticks           - (input) the number of system ticks til the
+**                                              timer expires.
+**                  is_continuous   - (input) TRUE if timer restarts automatically,
+**                                              else FALSE if it is a 'one-shot'.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
+{
+    INT32   reload;
+    INT32   orig_ticks;
+    UINT8   task_id = GKI_get_taskid();
+    BOOLEAN bad_timer = FALSE;
+
+    if (ticks <= 0)
+        ticks = 1;
+
+    orig_ticks = ticks;     /* save the ticks in case adjustment is necessary */
+
+
+    /* If continuous timer, set reload, else set it to 0 */
+    if (is_continuous)
+        reload = ticks;
+    else
+        reload = 0;
+
+    GKI_disable();
+
+    if(gki_timers_is_timer_running() == FALSE)
+    {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+        /* if inactivity delay timer is not running, start system tick */
+        if(gki_cb.com.OSTicksTilStop == 0)
+        {
+#endif
+            if(gki_cb.com.p_tick_cb)
+            {
+                /* start system tick */
+                gki_cb.com.system_tick_running = TRUE;
+                (gki_cb.com.p_tick_cb) (TRUE);
+            }
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+        }
+        else
+        {
+            /* clear inactivity delay timer */
+            gki_cb.com.OSTicksTilStop = 0;
+        }
+#endif
+    }
+    /* Add the time since the last task timer update.
+    ** Note that this works when no timers are active since
+    ** both OSNumOrigTicks and OSTicksTilExp are 0.
+    */
+    if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
+    {
+        ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
+    }
+    else
+        ticks = GKI_MAX_INT32;
+
+    switch (tnum)
+    {
+#if (GKI_NUM_TIMERS > 0)
+        case TIMER_0:
+            gki_cb.com.OSTaskTmr0R[task_id] = reload;
+            gki_cb.com.OSTaskTmr0 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        case TIMER_1:
+            gki_cb.com.OSTaskTmr1R[task_id] = reload;
+            gki_cb.com.OSTaskTmr1 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        case TIMER_2:
+            gki_cb.com.OSTaskTmr2R[task_id] = reload;
+            gki_cb.com.OSTaskTmr2 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        case TIMER_3:
+            gki_cb.com.OSTaskTmr3R[task_id] = reload;
+            gki_cb.com.OSTaskTmr3 [task_id] = ticks;
+            break;
+#endif
+        default:
+            bad_timer = TRUE;       /* Timer number is bad, so do not use */
+    }
+
+    /* Update the expiration timeout if a legitimate timer */
+    if (!bad_timer)
+    {
+        /* Only update the timeout value if it is less than any other newly started timers */
+        gki_adjust_timer_count (orig_ticks);
+    }
+
+    GKI_enable();
+
+}
+
+/*******************************************************************************
+**
+** Function         GKI_stop_timer
+**
+** Description      An application can call this function to stop one of
+**                  it's four general purpose timers. There is no harm in
+**                  stopping a timer that is already stopped.
+**
+** Parameters       tnum            - (input) timer number to be started (TIMER_0,
+**                                              TIMER_1, TIMER_2, or TIMER_3)
+** Returns          void
+**
+*******************************************************************************/
+void GKI_stop_timer (UINT8 tnum)
+{
+    UINT8  task_id = GKI_get_taskid();
+
+    GKI_disable();
+
+    switch (tnum)
+    {
+#if (GKI_NUM_TIMERS > 0)
+        case TIMER_0:
+            gki_cb.com.OSTaskTmr0R[task_id] = 0;
+            gki_cb.com.OSTaskTmr0 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        case TIMER_1:
+            gki_cb.com.OSTaskTmr1R[task_id] = 0;
+            gki_cb.com.OSTaskTmr1 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        case TIMER_2:
+            gki_cb.com.OSTaskTmr2R[task_id] = 0;
+            gki_cb.com.OSTaskTmr2 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        case TIMER_3:
+            gki_cb.com.OSTaskTmr3R[task_id] = 0;
+            gki_cb.com.OSTaskTmr3 [task_id] = 0;
+            break;
+#endif
+    }
+
+    if (gki_timers_is_timer_running() == FALSE)
+    {
+        if (gki_cb.com.p_tick_cb)
+        {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+            /* if inactivity delay timer is not running */
+            if ((gki_cb.com.system_tick_running)&&(gki_cb.com.OSTicksTilStop == 0))
+            {
+                /* set inactivity delay timer */
+                /* when timer expires, system tick will be stopped */
+                gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
+            }
+#else
+            gki_cb.com.system_tick_running = FALSE;
+            gki_cb.com.p_tick_cb(FALSE); /* stop system tick */
+#endif
+        }
+    }
+
+    GKI_enable();
+
+
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_timer_update
+**
+** Description      This function is called by an OS to drive the GKI's timers.
+**                  It is typically called at every system tick to
+**                  update the timers for all tasks, and check for timeouts.
+**
+**                  Note: It has been designed to also allow for variable tick updates
+**                      so that systems with strict power savings requirements can
+**                      have the update occur at variable intervals.
+**
+** Parameters:      ticks_since_last_update - (input) This is the number of TICKS that have
+**                          occurred since the last time GKI_timer_update was called.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_timer_update (INT32 ticks_since_last_update)
+{
+    UINT8   task_id;
+    long    next_expiration;        /* Holds the next soonest expiration time after this update */
+
+    /* Increment the number of ticks used for time stamps */
+    gki_cb.com.OSTicks += ticks_since_last_update;
+
+    /* If any timers are running in any tasks, decrement the remaining time til
+     * the timer updates need to take place (next expiration occurs)
+     */
+    gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
+
+    /* Don't allow timer interrupt nesting */
+    if (gki_cb.com.timer_nesting)
+        return;
+
+    gki_cb.com.timer_nesting = 1;
+
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    /* if inactivity delay timer is set and expired */
+    if (gki_cb.com.OSTicksTilStop)
+    {
+        if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update )
+        {
+            if(gki_cb.com.p_tick_cb)
+            {
+                gki_cb.com.system_tick_running = FALSE;
+                (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */
+            }
+            gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
+            gki_cb.com.timer_nesting = 0;
+            return;
+        }
+        else
+            gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
+    }
+#endif
+
+    /* No need to update the ticks if no timeout has occurred */
+    if (gki_cb.com.OSTicksTilExp > 0)
+    {
+        gki_cb.com.timer_nesting = 0;
+        return;
+    }
+
+    GKI_disable();
+
+    next_expiration = GKI_NO_NEW_TMRS_STARTED;
+
+    /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
+       to account for the difference so timer updates below are decremented by the full number
+       of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
+       value only affects the timer updates below
+     */
+    gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
+
+    /* Check for OS Task Timers */
+    for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+    {
+        if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
+        {
+            gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
+            if (gki_cb.com.OSWaitTmr[task_id] <= 0)
+            {
+                /* Timer Expired */
+                gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+            }
+        }
+
+#if (GKI_NUM_TIMERS > 0)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr0[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
+            {
+                /* Set Timer 0 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_0_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_0_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr0[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr1[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
+            {
+                /* Set Timer 1 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_1_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_1_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr1[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr2[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
+            {
+                /* Set Timer 2 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_2_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_2_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr2[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr3[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
+            {
+                /* Set Timer 3 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_3_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_3_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr3[task_id];
+#endif
+
+    }
+
+    /* Set the next timer experation value if there is one to start */
+    if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
+    {
+        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
+    }
+    else
+    {
+        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
+    }
+
+    gki_cb.com.timer_nesting = 0;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_empty
+**
+** Description      This function is called by applications to see whether the timer
+**                  queue is empty
+**
+** Parameters
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN GKI_timer_queue_empty (void)
+{
+    UINT8 tt;
+
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+    {
+        if (gki_cb.com.timer_queues[tt])
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_register_callback
+**
+** Description      This function is called by applications to register system tick
+**                  start/stop callback for time queues
+**
+**
+** Parameters       p_callback - (input) pointer to the system tick callback
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+void GKI_timer_queue_register_callback (SYSTEM_TICK_CBACK *p_callback)
+{
+    gki_cb.com.p_tick_cb = p_callback;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list
+**
+** Description      This function is called by applications when they
+**                  want to initialize a timer list.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list (TIMER_LIST_Q *p_timer_listq)
+{
+    p_timer_listq->p_first    = NULL;
+    p_timer_listq->p_last     = NULL;
+    p_timer_listq->last_ticks = 0;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list_entry
+**
+** Description      This function is called by the applications when they
+**                  want to initialize a timer list entry. This must be
+**                  done prior to first use of the entry.
+**
+** Parameters       p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list_entry (TIMER_LIST_ENT  *p_tle)
+{
+    p_tle->p_next  = NULL;
+    p_tle->p_prev  = NULL;
+    p_tle->ticks   = GKI_UNUSED_LIST_ENTRY;
+    p_tle->in_use  = FALSE;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_update_timer_list
+**
+** Description      This function is called by the applications when they
+**                  want to update a timer list. This should be at every
+**                  timer list unit tick, e.g. once per sec, once per minute etc.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  num_units_since_last_update - (input) number of units since the last update
+**                                  (allows for variable unit update)
+**
+**      NOTE: The following timer list update routines should not be used for exact time
+**            critical purposes.  The timer tasks should be used when exact timing is needed.
+**
+** Returns          the number of timers that have expired
+**
+*******************************************************************************/
+UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
+{
+    TIMER_LIST_ENT  *p_tle;
+    UINT16           num_time_out = 0;
+    INT32            rem_ticks;
+    INT32            temp_ticks;
+
+    p_tle = p_timer_listq->p_first;
+
+    /* First, get the guys who have previously timed out */
+    /* Note that the tick value of the timers should always be '0' */
+    while ((p_tle) && (p_tle->ticks <= 0))
+    {
+        num_time_out++;
+        p_tle = p_tle->p_next;
+    }
+
+    /* Timer entriy tick values are relative to the preceeding entry */
+    rem_ticks = num_units_since_last_update;
+
+    /* Now, adjust remaining timer entries */
+    while ((p_tle != NULL) && (rem_ticks > 0))
+    {
+        temp_ticks = p_tle->ticks;
+        p_tle->ticks -= rem_ticks;
+
+        /* See if this timer has just timed out */
+        if (p_tle->ticks <= 0)
+        {
+            /* We set the number of ticks to '0' so that the legacy code
+             * that assumes a '0' or nonzero value will still work as coded. */
+            p_tle->ticks = 0;
+
+            num_time_out++;
+        }
+
+        rem_ticks -= temp_ticks;  /* Decrement the remaining ticks to process */
+        p_tle = p_tle->p_next;
+    }
+
+    if (p_timer_listq->last_ticks > 0)
+    {
+        p_timer_listq->last_ticks -= num_units_since_last_update;
+
+        /* If the last timer has expired set last_ticks to 0 so that other list update
+        * functions will calculate correctly
+        */
+        if (p_timer_listq->last_ticks < 0)
+            p_timer_listq->last_ticks = 0;
+    }
+
+    return (num_time_out);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_remaining_ticks
+**
+** Description      This function is called by an application to get remaining
+**                  ticks to expire
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_target_tle    - (input) pointer to a timer list queue entry
+**
+** Returns          0 if timer is not used or timer is not in the list
+**                  remaining ticks if success
+**
+*******************************************************************************/
+UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_target_tle)
+{
+    TIMER_LIST_ENT  *p_tle;
+    UINT32           rem_ticks = 0;
+
+    if (p_target_tle->in_use)
+    {
+        p_tle = p_timer_listq->p_first;
+
+        /* adding up all of ticks in previous entries */
+        while ((p_tle)&&(p_tle != p_target_tle))
+        {
+            rem_ticks += p_tle->ticks;
+            p_tle = p_tle->p_next;
+        }
+
+        /* if found target entry */
+        if (p_tle == p_target_tle)
+        {
+            rem_ticks += p_tle->ticks;
+        }
+        else
+        {
+            BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: No timer entry in the list");
+            return(0);
+        }
+    }
+    else
+    {
+        BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: timer entry is not active");
+    }
+
+    return (rem_ticks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_add_to_timer_list
+**
+** Description      This function is called by an application to add a timer
+**                  entry to a timer list.
+**
+**                  Note: A timer value of '0' will effectively insert an already
+**                      expired event.  Negative tick values will be ignored.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
+{
+    UINT32           nr_ticks_total;
+    UINT8 tt;
+    TIMER_LIST_ENT  *p_temp;
+    if (p_tle == NULL || p_timer_listq == NULL) {
+        GKI_TRACE_3("%s: invalid argument %x, %x****************************<<", __func__, p_timer_listq, p_tle);
+        return;
+    }
+
+
+    /* Only process valid tick values */
+    if (p_tle->ticks >= 0)
+    {
+        /* If this entry is the last in the list */
+        if (p_tle->ticks >= p_timer_listq->last_ticks)
+        {
+            /* If this entry is the only entry in the list */
+            if (p_timer_listq->p_first == NULL)
+                p_timer_listq->p_first = p_tle;
+            else
+            {
+                /* Insert the entry onto the end of the list */
+                if (p_timer_listq->p_last != NULL)
+                    p_timer_listq->p_last->p_next = p_tle;
+
+                p_tle->p_prev = p_timer_listq->p_last;
+            }
+
+            p_tle->p_next = NULL;
+            p_timer_listq->p_last = p_tle;
+            nr_ticks_total = p_tle->ticks;
+            p_tle->ticks -= p_timer_listq->last_ticks;
+
+            p_timer_listq->last_ticks = nr_ticks_total;
+        }
+        else    /* This entry needs to be inserted before the last entry */
+        {
+            /* Find the entry that the new one needs to be inserted in front of */
+            p_temp = p_timer_listq->p_first;
+            while (p_tle->ticks > p_temp->ticks)
+            {
+                /* Update the tick value if looking at an unexpired entry */
+                if (p_temp->ticks > 0)
+                    p_tle->ticks -= p_temp->ticks;
+
+                p_temp = p_temp->p_next;
+            }
+
+            /* The new entry is the first in the list */
+            if (p_temp == p_timer_listq->p_first)
+            {
+                p_tle->p_next = p_timer_listq->p_first;
+                p_timer_listq->p_first->p_prev = p_tle;
+                p_timer_listq->p_first = p_tle;
+            }
+            else
+            {
+                p_temp->p_prev->p_next = p_tle;
+                p_tle->p_prev = p_temp->p_prev;
+                p_temp->p_prev = p_tle;
+                p_tle->p_next = p_temp;
+            }
+            p_temp->ticks -= p_tle->ticks;
+        }
+
+        p_tle->in_use = TRUE;
+
+        /* if we already add this timer queue to the array */
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+             if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+                 return;
+        }
+        /* add this timer queue to the array */
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+             if (gki_cb.com.timer_queues[tt] == NULL)
+                 break;
+        }
+        if (tt < GKI_MAX_TIMER_QUEUES)
+        {
+            gki_cb.com.timer_queues[tt] = p_timer_listq;
+        }
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_timer_list
+**
+** Description      This function is called by an application to remove a timer
+**                  entry from a timer list.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
+{
+    UINT8 tt;
+
+    /* Verify that the entry is valid */
+    if (p_tle == NULL || p_tle->in_use == FALSE || p_timer_listq->p_first == NULL)
+    {
+        return;
+    }
+
+    /* Add the ticks remaining in this timer (if any) to the next guy in the list.
+    ** Note: Expired timers have a tick value of '0'.
+    */
+    if (p_tle->p_next != NULL)
+    {
+        p_tle->p_next->ticks += p_tle->ticks;
+    }
+    else
+    {
+        p_timer_listq->last_ticks -= p_tle->ticks;
+    }
+
+    /* Unlink timer from the list.
+    */
+    if (p_timer_listq->p_first == p_tle)
+    {
+        p_timer_listq->p_first = p_tle->p_next;
+
+        if (p_timer_listq->p_first != NULL)
+            p_timer_listq->p_first->p_prev = NULL;
+
+        if (p_timer_listq->p_last == p_tle)
+            p_timer_listq->p_last = NULL;
+    }
+    else
+    {
+        if (p_timer_listq->p_last == p_tle)
+        {
+            p_timer_listq->p_last = p_tle->p_prev;
+
+            if (p_timer_listq->p_last != NULL)
+                p_timer_listq->p_last->p_next = NULL;
+        }
+        else
+        {
+            if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
+                p_tle->p_next->p_prev = p_tle->p_prev;
+            else
+            {
+                /* Error case - chain messed up ?? */
+                return;
+            }
+
+            if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
+                p_tle->p_prev->p_next = p_tle->p_next;
+            else
+            {
+                /* Error case - chain messed up ?? */
+                return;
+            }
+        }
+    }
+
+    p_tle->p_next = p_tle->p_prev = NULL;
+    p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+    p_tle->in_use = FALSE;
+
+    /* if timer queue is empty */
+    if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL)
+    {
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+            if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+            {
+                gki_cb.com.timer_queues[tt] = NULL;
+                break;
+            }
+        }
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_adjust_timer_count
+**
+** Description      This function is called whenever a new timer or GKI_wait occurs
+**                  to adjust (if necessary) the current time til the first expiration.
+**                  This only needs to make an adjustment if the new timer (in ticks) is
+**                  less than the number of ticks remaining on the current timer.
+**
+** Parameters:      ticks - (input) number of system ticks of the new timer entry
+**
+**                  NOTE:  This routine MUST be called while interrupts are disabled to
+**                          avoid updates while adjusting the timer variables.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_adjust_timer_count (INT32 ticks)
+{
+    if (ticks > 0)
+    {
+        /* See if the new timer expires before the current first expiration */
+        if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
+        {
+            gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
+            gki_cb.com.OSTicksTilExp = ticks;
+        }
+    }
+
+    return;
+}
diff --git a/halimpl/bcm2079x/gki/ulinux/data_types.h b/halimpl/bcm2079x/gki/ulinux/data_types.h
new file mode 100644
index 0000000..0768494
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/data_types.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 DATA_TYPES_H
+#define DATA_TYPES_H
+
+#ifndef NULL
+#define NULL     0
+#endif
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+typedef unsigned char   UINT8;
+typedef unsigned short  UINT16;
+typedef unsigned long   UINT32;
+typedef unsigned long long int UINT64;
+typedef signed   long   INT32;
+typedef signed   char   INT8;
+typedef signed   short  INT16;
+typedef unsigned char   BOOLEAN;
+
+typedef UINT32          TIME_STAMP;
+
+#ifndef TRUE
+#define TRUE   (!FALSE)
+#endif
+
+typedef unsigned char   UBYTE;
+
+#ifdef __arm
+#define PACKED  __packed
+#define INLINE  __inline
+#else
+#define PACKED
+#define INLINE
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN FALSE
+#endif
+
+#define UINT16_LOW_BYTE(x)      ((x) & 0xff)
+#define UINT16_HI_BYTE(x)       ((x) >> 8)
+
+/* MACRO definitions for safe string functions */
+/* Replace standard string functions with safe functions if available */
+#define BCM_STRCAT_S(x1,x2,x3)      strcat((x1),(x3))
+#define BCM_STRNCAT_S(x1,x2,x3,x4)  strncat((x1),(x3),(x4))
+#define BCM_STRCPY_S(x1,x2,x3)      strcpy((x1),(x3))
+#define BCM_STRNCPY_S(x1,x2,x3,x4)  strncpy((x1),(x3),(x4))
+#define BCM_SPRINTF_S(x1,x2,x3,x4)  sprintf((x1),(x3),(x4))
+#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/ulinux/gki_int.h b/halimpl/bcm2079x/gki/ulinux/gki_int.h
new file mode 100644
index 0000000..c59ac32
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_int.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_INT_H
+#define GKI_INT_H
+
+#include "gki_common.h"
+#include <pthread.h>
+
+/**********************************************************************
+** OS specific definitions
+*/
+#ifdef ANDROID
+#include <sys/times.h>
+#endif
+
+typedef struct
+{
+    pthread_mutex_t     GKI_mutex;
+    pthread_t           thread_id[GKI_MAX_TASKS];
+    pthread_mutex_t     thread_evt_mutex[GKI_MAX_TASKS];
+    pthread_cond_t      thread_evt_cond[GKI_MAX_TASKS];
+    pthread_mutex_t     thread_timeout_mutex[GKI_MAX_TASKS];
+    pthread_cond_t      thread_timeout_cond[GKI_MAX_TASKS];
+    int                 no_timer_suspend;   /* 1: no suspend, 0 stop calling GKI_timer_update() */
+    pthread_mutex_t     gki_timer_mutex;
+    pthread_cond_t      gki_timer_cond;
+    int                 gki_timer_wake_lock_on;
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_t     GKI_trace_mutex;
+#endif
+} tGKI_OS;
+
+/* condition to exit or continue GKI_run() timer loop */
+#define GKI_TIMER_TICK_RUN_COND 1
+#define GKI_TIMER_TICK_STOP_COND 0
+#define GKI_TIMER_TICK_EXIT_COND 2
+
+extern void gki_system_tick_start_stop_cback(BOOLEAN start);
+
+/* Contains common control block as well as OS specific variables */
+typedef struct
+{
+    tGKI_OS     os;
+    tGKI_COM_CB com;
+} tGKI_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if GKI_DYNAMIC_MEMORY == FALSE
+GKI_API extern tGKI_CB  gki_cb;
+#else
+GKI_API extern tGKI_CB *gki_cb_ptr;
+#define gki_cb (*gki_cb_ptr)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
new file mode 100644
index 0000000..39eb3e1
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1313 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define GKI_DEBUG   FALSE
+
+#include <pthread.h>  /* must be 1st header defined  */
+#include <time.h>
+#include <hardware_legacy/power.h>  /* Android header */
+#include "gki_int.h"
+#include "gki_target.h"
+
+/* Temp android logging...move to android tgt config file */
+
+#ifndef LINUX_NATIVE
+#include <cutils/log.h>
+#else
+#define LOGV(format, ...)  fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+#define LOGE(format, ...)  fprintf (stderr, LOG_TAG format, ## __VA_ARGS__)
+#define LOGI(format, ...)  fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#define pthread_cond_timedwait_monotonic pthread_cond_timedwait
+
+#endif
+
+/* Define the structure that holds the GKI variables
+*/
+#if GKI_DYNAMIC_MEMORY == FALSE
+tGKI_CB   gki_cb;
+#endif
+
+#define NANOSEC_PER_MILLISEC (1000000)
+#define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
+
+/* works only for 1ms to 1000ms heart beat ranges */
+#define LINUX_SEC (1000/TICKS_PER_SEC)
+// #define GKI_TICK_TIMER_DEBUG
+
+#define LOCK(m)  pthread_mutex_lock(&m)
+#define UNLOCK(m) pthread_mutex_unlock(&m)
+#define INIT(m) pthread_mutex_init(&m, NULL)
+
+
+/* this kind of mutex go into tGKI_OS control block!!!! */
+/* static pthread_mutex_t GKI_sched_mutex; */
+/*static pthread_mutex_t thread_delay_mutex;
+static pthread_cond_t thread_delay_cond;
+static pthread_mutex_t gki_timer_update_mutex;
+static pthread_cond_t   gki_timer_update_cond;
+*/
+#ifdef NO_GKI_RUN_RETURN
+static pthread_t            timer_thread_id = 0;
+#endif
+
+
+/* For Android */
+
+#ifndef GKI_SHUTDOWN_EVT
+#define GKI_SHUTDOWN_EVT    APPL_EVT_7
+#endif
+
+typedef struct
+{
+    UINT8 task_id;          /* GKI task id */
+    TASKPTR task_entry;     /* Task entry function*/
+    UINT32 params;          /* Extra params to pass to task entry function */
+    pthread_cond_t* pCond;	/* for android*/
+    pthread_mutex_t* pMutex;  /* for android*/
+} gki_pthread_info_t;
+gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
+
+static void* GKI_run_worker_thread (void*);
+
+/*******************************************************************************
+**
+** Function         gki_task_entry
+**
+** Description      entry point of GKI created tasks
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_task_entry(UINT32 params)
+{
+    pthread_t thread_id = pthread_self();
+    gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
+    GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x", p_pthread_info->task_id,
+                gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
+                p_pthread_info->pCond, p_pthread_info->pMutex);
+
+    gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
+    /* Call the actual thread entry point */
+    (p_pthread_info->task_entry)(p_pthread_info->params);
+
+    GKI_TRACE_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
+    gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
+
+    pthread_exit(0);    /* GKI tasks have no return value */
+}
+/* end android */
+
+#ifndef ANDROID
+void GKI_TRACE(char *fmt, ...)
+{
+    LOCK(gki_cb.os.GKI_trace_mutex);
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+
+    va_end(ap);
+    UNLOCK(gki_cb.os.GKI_trace_mutex);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_init
+**
+** Description      This function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_init(void)
+{
+    pthread_mutexattr_t attr;
+    tGKI_OS             *p_os;
+
+    memset (&gki_cb, 0, sizeof (gki_cb));
+
+    gki_buffer_init();
+    gki_timers_init();
+    gki_cb.com.OSTicks = (UINT32) times(0);
+
+    pthread_mutexattr_init(&attr);
+
+#ifndef __CYGWIN__
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+    p_os = &gki_cb.os;
+    pthread_mutex_init(&p_os->GKI_mutex, &attr);
+    /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
+#endif
+    /* pthread_mutex_init(&thread_delay_mutex, NULL); */  /* used in GKI_delay */
+    /* pthread_cond_init (&thread_delay_cond, NULL); */
+
+    /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
+     * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
+    p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
+    pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
+    pthread_cond_init(&p_os->gki_timer_cond, NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_os_tick_count
+**
+** Description      This function is called to retrieve the native OS system tick.
+**
+** Returns          Tick count of native OS.
+**
+*******************************************************************************/
+UINT32 GKI_get_os_tick_count(void)
+{
+
+    /* TODO - add any OS specific code here
+    **/
+    return (gki_cb.com.OSTicks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_create_task
+**
+** Description      This function is called to create a new OSS task.
+**
+** Parameters:      task_entry  - (input) pointer to the entry function of the task
+**                  task_id     - (input) Task id is mapped to priority
+**                  taskname    - (input) name given to the task
+**                  stack       - (input) pointer to the top of the stack (highest memory location)
+**                  stacksize   - (input) size of the stack allocated for the task
+**
+** Returns          GKI_SUCCESS if all OK, GKI_FAILURE if any problem
+**
+** NOTE             This function take some parameters that may not be needed
+**                  by your particular OS. They are here for compatability
+**                  of the function prototype.
+**
+*******************************************************************************/
+UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize, void* pCondVar, void* pMutex)
+{
+    UINT16  i;
+    UINT8   *p;
+    struct sched_param param;
+    int policy, ret = 0;
+    pthread_attr_t attr1;
+
+    GKI_TRACE_5 ("GKI_create_task func=0x%x  id=%d  name=%s  stack=0x%x  stackSize=%d", task_entry, task_id, taskname, stack, stacksize);
+
+    if (task_id >= GKI_MAX_TASKS)
+    {
+        GKI_TRACE_0("Error! task ID > max task allowed");
+        return (GKI_FAILURE);
+    }
+
+
+    gki_cb.com.OSRdyTbl[task_id]    = TASK_READY;
+    gki_cb.com.OSTName[task_id]     = taskname;
+    gki_cb.com.OSWaitTmr[task_id]   = 0;
+    gki_cb.com.OSWaitEvt[task_id]   = 0;
+
+    /* Initialize mutex and condition variable objects for events and timeouts */
+    pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], NULL);
+    pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], NULL);
+
+    pthread_attr_init(&attr1);
+    /* by default, pthread creates a joinable thread */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
+
+    GKI_TRACE_3("GKI creating task %i, pCond/pMutex=%x/%x", task_id, pCondVar, pMutex);
+#else
+    GKI_TRACE_1("GKI creating JOINABLE task %i", task_id);
+#endif
+
+    /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
+    /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
+    gki_pthread_info[task_id].task_id = task_id;
+    gki_pthread_info[task_id].task_entry = task_entry;
+    gki_pthread_info[task_id].params = 0;
+    gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
+    gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
+
+    ret = pthread_create( &gki_cb.os.thread_id[task_id],
+              &attr1,
+              (void *)gki_task_entry,
+              &gki_pthread_info[task_id]);
+
+    if (ret != 0)
+    {
+         GKI_TRACE_2("pthread_create failed(%d), %s!", ret, taskname);
+         return GKI_FAILURE;
+    }
+
+    if(pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param)==0)
+    {
+#if defined(PBS_SQL_TASK)
+         if (task_id == PBS_SQL_TASK)
+         {
+             GKI_TRACE_0("PBS SQL lowest priority task");
+             policy = SCHED_NORMAL;
+         }
+         else
+#endif
+         {
+             policy = SCHED_RR;
+             param.sched_priority = 30 - task_id - 2;
+         }
+         pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
+     }
+
+    GKI_TRACE_6( "Leaving GKI_create_task %x %d %x %s %x %d",
+              task_entry,
+              task_id,
+              gki_cb.os.thread_id[task_id],
+              taskname,
+              stack,
+              stacksize);
+
+    return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shutdown
+**
+** Description      shutdowns the GKI tasks/threads in from max task id to 0 and frees
+**                  pthread resources!
+**                  IMPORTANT: in case of join method, GKI_shutdown must be called outside
+**                  a GKI thread context!
+**
+** Returns          void
+**
+*******************************************************************************/
+#define WAKE_LOCK_ID "brcm_nfca"
+
+void GKI_shutdown(void)
+{
+    UINT8 task_id;
+    volatile int    *p_run_cond = &gki_cb.os.no_timer_suspend;
+    int     oldCOnd = 0;
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    int i = 0;
+#else
+    int result;
+#endif
+
+    /* release threads and set as TASK_DEAD. going from low to high priority fixes
+     * GKI_exception problem due to btu->hci sleep request events  */
+    for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
+    {
+        if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
+        {
+            gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
+
+            /* paranoi settings, make sure that we do not execute any mailbox events */
+            gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
+                                                TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
+            GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+            i = 0;
+
+            while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
+                usleep(100 * 1000);
+#else
+            /* wait for proper Arnold Schwarzenegger task state */
+            result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
+            if ( result < 0 )
+            {
+                GKI_TRACE_1( "pthread_join() FAILED: result: %d", result );
+            }
+#endif
+            GKI_TRACE_1( "GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
+            GKI_exit_task(task_id - 1);
+        }
+    }
+
+    /* Destroy mutex and condition variable objects */
+    pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
+    /*    pthread_mutex_destroy(&GKI_sched_mutex); */
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
+#endif
+    /*    pthread_mutex_destroy(&thread_delay_mutex);
+     pthread_cond_destroy (&thread_delay_cond); */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    i = 0;
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+    shutdown_timer = 1;
+#endif
+    if (gki_cb.os.gki_timer_wake_lock_on)
+    {
+        GKI_TRACE_0("GKI_shutdown :  release_wake_lock(brcm_btld)");
+        release_wake_lock(WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 0;
+    }
+    oldCOnd = *p_run_cond;
+    *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
+    if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
+        pthread_cond_signal( &gki_cb.os.gki_timer_cond );
+
+}
+
+/*******************************************************************************
+ **
+ ** Function        GKI_run
+ **
+ ** Description     This function runs a task
+ **
+ ** Parameters:     start: TRUE start system tick (again), FALSE stop
+ **
+ ** Returns         void
+ **
+ *********************************************************************************/
+void gki_system_tick_start_stop_cback(BOOLEAN start)
+{
+    tGKI_OS         *p_os = &gki_cb.os;
+    volatile int    *p_run_cond = &p_os->no_timer_suspend;
+    volatile static int wake_lock_count;
+    if ( FALSE == start )
+    {
+        /* this can lead to a race condition. however as we only read this variable in the timer loop
+         * we should be fine with this approach. otherwise uncomment below mutexes.
+         */
+        /* GKI_disable(); */
+        *p_run_cond = GKI_TIMER_TICK_STOP_COND;
+        /* GKI_enable(); */
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count);
+#endif
+        release_wake_lock(WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 0;
+    }
+    else
+    {
+        /* restart GKI_timer_update() loop */
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 1;
+        *p_run_cond = GKI_TIMER_TICK_RUN_COND;
+        pthread_mutex_lock( &p_os->gki_timer_mutex );
+        pthread_cond_signal( &p_os->gki_timer_cond );
+        pthread_mutex_unlock( &p_os->gki_timer_mutex );
+
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count );
+#endif
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         timer_thread
+**
+** Description      Timer thread
+**
+** Parameters:      id  - (input) timer ID
+**
+** Returns          void
+**
+*********************************************************************************/
+#ifdef NO_GKI_RUN_RETURN
+void timer_thread(signed long id)
+{
+    GKI_TRACE_1("%s enter", __func__);
+    struct timespec delay;
+    int timeout = 1000;  /* 10  ms per system tick  */
+    int err;
+
+    while(!shutdown_timer)
+    {
+        delay.tv_sec = timeout / 1000;
+        delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+        /* [u]sleep can't be used because it uses SIGALRM */
+
+        do
+        {
+            err = nanosleep(&delay, &delay);
+        } while (err < 0 && errno ==EINTR);
+
+        GKI_timer_update(1);
+    }
+    GKI_TRACE_1("%s exit", __func__);
+    pthread_exit(NULL);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_run
+**
+** Description      This function runs a task
+**
+** Parameters:      p_task_id  - (input) pointer to task id
+**
+** Returns          void
+**
+** NOTE             This function is only needed for operating systems where
+**                  starting a task is a 2-step process. Most OS's do it in
+**                  one step, If your OS does it in one step, this function
+**                  should be empty.
+*********************************************************************************/
+void GKI_run (void *p_task_id)
+{
+    GKI_TRACE_1("%s enter", __func__);
+    int retval = EACCES;
+    static pthread_t workerThreadId = NULL;
+
+    retval = pthread_create (&workerThreadId, NULL, GKI_run_worker_thread, NULL);
+    if (retval != 0)
+    {
+        GKI_TRACE_ERROR_2 ("%s: fail create thread %d", __func__, retval);
+    }
+    GKI_TRACE_1("%s exit", __func__);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_run_worker_thread
+**
+** Description      This function runs a task
+**
+** Parameters:      None
+**
+** Returns:         error code
+*********************************************************************************/
+void* GKI_run_worker_thread (void* dummy)
+{
+    GKI_TRACE_1("%s: enter", __func__);
+    struct timespec delay;
+    int err = 0;
+    volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;
+
+#ifndef GKI_NO_TICK_STOP
+    /* register start stop function which disable timer loop in GKI_run() when no timers are
+     * in any GKI/BTA/BTU this should save power when BTLD is idle! */
+    GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
+    GKI_TRACE_1( "%s: Start/Stop GKI_timer_update_registered!", __func__ );
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+    GKI_TRACE_1("%s: GKI_run == NO_GKI_RUN_RETURN", __func__);
+    pthread_attr_t timer_attr;
+
+    shutdown_timer = 0;
+
+    pthread_attr_init(&timer_attr);
+    pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
+    if (pthread_create( &timer_thread_id,
+              &timer_attr,
+              timer_thread,
+              NULL) != 0 )
+    {
+        GKI_TRACE_1("%s: pthread_create failed to create timer_thread!", __func__);
+        return NULL;
+    }
+#else
+    GKI_TRACE_3("%s: run_cond(%x)=%d ", __func__, p_run_cond, *p_run_cond);
+    for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;)
+    {
+        do
+        {
+            /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
+             * 1-1000ms heart beat units! */
+            delay.tv_sec = LINUX_SEC / 1000;
+            delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
+
+            /* [u]sleep can't be used because it uses SIGALRM */
+            do
+            {
+                err = nanosleep(&delay, &delay);
+            } while (err < 0 && errno == EINTR);
+
+            /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick
+             * e.g. power saving you may want to provide more ticks
+             */
+            GKI_timer_update( 1 );
+            /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
+        } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond);
+
+        /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND
+         * block timer main thread till re-armed by  */
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_0( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> SUSPENDED GKI_timer_update()" );
+#endif
+        if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
+            GKI_TRACE_1("%s: waiting timer mutex", __func__);
+            pthread_mutex_lock( &gki_cb.os.gki_timer_mutex );
+            pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex );
+            pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
+            GKI_TRACE_1("%s: exited timer mutex", __func__);
+        }
+        /* potentially we need to adjust os gki_cb.com.OSTicks */
+
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> RESTARTED GKI_timer_update(): run_cond: %d",
+                    *p_run_cond );
+#endif
+    } /* for */
+#endif
+    GKI_TRACE_1("%s: exit", __func__);
+    return NULL;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_stop
+**
+** Description      This function is called to stop
+**                  the tasks and timers when the system is being stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here.
+**
+*******************************************************************************/
+void GKI_stop (void)
+{
+    UINT8 task_id;
+
+    /*  gki_queue_timer_cback(FALSE); */
+    /* TODO - add code here if needed*/
+
+    for(task_id = 0; task_id<GKI_MAX_TASKS; task_id++)
+    {
+        if(gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
+        {
+            GKI_exit_task(task_id);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_wait
+**
+** Description      This function is called by tasks to wait for a specific
+**                  event or set of events. The task may specify the duration
+**                  that it wants to wait for, or 0 if infinite.
+**
+** Parameters:      flag -    (input) the event or set of events to wait for
+**                  timeout - (input) the duration that the task wants to wait
+**                                    for the specific events (in system ticks)
+**
+**
+** Returns          the event mask of received events or zero if timeout
+**
+*******************************************************************************/
+UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
+{
+    UINT16 evt;
+    UINT8 rtask;
+    struct timespec abstime = { 0, 0 };
+    int sec;
+    int nano_sec;
+
+    rtask = GKI_get_taskid();
+    GKI_TRACE_3("GKI_wait %d %x %d", rtask, flag, timeout);
+    if (rtask >= GKI_MAX_TASKS) {
+        pthread_exit(NULL);
+        return 0;
+    }
+
+    gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
+    if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
+        int ret;
+        GKI_TRACE_3("GKI_wait task=%i, pCond/pMutex = %x/%x", rtask, p_pthread_info->pCond, p_pthread_info->pMutex);
+        ret = pthread_mutex_lock(p_pthread_info->pMutex);
+        ret = pthread_cond_signal(p_pthread_info->pCond);
+        ret = pthread_mutex_unlock(p_pthread_info->pMutex);
+        p_pthread_info->pMutex = NULL;
+        p_pthread_info->pCond = NULL;
+    }
+    gki_cb.com.OSWaitForEvt[rtask] = flag;
+
+    /* protect OSWaitEvt[rtask] from modification from an other thread */
+    pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
+
+#if 0 /* for clean scheduling we probably should always call pthread_cond_wait() */
+    /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
+     has been modified. however this should only result in addtional call to  pthread_cond_wait() but as
+     the cond is met, it will exit immediately (depending on schedulling) */
+    if (gki_cb.com.OSTaskQFirst[rtask][0])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][1])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][2])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][3])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+#endif
+
+    if (!(gki_cb.com.OSWaitEvt[rtask] & flag))
+    {
+        if (timeout)
+        {
+            //            timeout = GKI_MS_TO_TICKS(timeout);     /* convert from milliseconds to ticks */
+
+            /* get current system time */
+            //            clock_gettime(CLOCK_MONOTONIC, &currSysTime);
+            //            abstime.tv_sec = currSysTime.time;
+            //            abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+            clock_gettime(CLOCK_MONOTONIC, &abstime);
+
+            /* add timeout */
+            sec = timeout / 1000;
+            nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
+            abstime.tv_nsec += nano_sec;
+            if (abstime.tv_nsec > NSEC_PER_SEC)
+            {
+                abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
+                abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
+            }
+            abstime.tv_sec += sec;
+
+            pthread_cond_timedwait_monotonic(&gki_cb.os.thread_evt_cond[rtask],
+                    &gki_cb.os.thread_evt_mutex[rtask], &abstime);
+
+        }
+        else
+        {
+            pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
+        }
+
+        /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
+         e.g. it looks like it is implemented as a counter in which case multiple cond_signal
+         should NOT be lost! */
+        // we are waking up after waiting for some events, so refresh variables
+        // no need to call GKI_disable() here as we know that we will have some events as we've been waking up after condition pending or timeout
+        if (gki_cb.com.OSTaskQFirst[rtask][0])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][1])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][2])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][3])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+
+        if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+        {
+            gki_cb.com.OSWaitEvt[rtask] = 0;
+            /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
+            pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+            GKI_TRACE_1("GKI TASK_DEAD received. exit thread %d...", rtask );
+
+            gki_cb.os.thread_id[rtask] = 0;
+            pthread_exit(NULL);
+            return (EVENT_MASK(GKI_SHUTDOWN_EVT));
+        }
+    }
+
+    /* Clear the wait for event mask */
+    gki_cb.com.OSWaitForEvt[rtask] = 0;
+
+    /* Return only those bits which user wants... */
+    evt = gki_cb.com.OSWaitEvt[rtask] & flag;
+
+    /* Clear only those bits which user wants... */
+    gki_cb.com.OSWaitEvt[rtask] &= ~flag;
+
+    /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
+    pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+    GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
+
+    return (evt);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_delay
+**
+** Description      This function is called by tasks to sleep unconditionally
+**                  for a specified amount of time. The duration is in milliseconds
+**
+** Parameters:      timeout -    (input) the duration in milliseconds
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_delay (UINT32 timeout)
+{
+    UINT8 rtask = GKI_get_taskid();
+    struct timespec delay;
+    int err;
+
+    GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
+
+    delay.tv_sec = timeout / 1000;
+    delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+    /* [u]sleep can't be used because it uses SIGALRM */
+
+    do {
+        err = nanosleep(&delay, &delay);
+    } while (err < 0 && errno ==EINTR);
+
+    /* Check if task was killed while sleeping */
+    /* NOTE
+    **      if you do not implement task killing, you do not
+    **      need this check.
+    */
+    if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+    {
+    }
+
+    GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_send_event
+**
+** Description      This function is called by tasks to send events to other
+**                  tasks. Tasks can also send events to themselves.
+**
+** Parameters:      task_id -  (input) The id of the task to which the event has to
+**                  be sent
+**                  event   -  (input) The event that has to be sent
+**
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+*******************************************************************************/
+UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
+{
+    GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
+
+    /* use efficient coding to avoid pipeline stalls */
+    if (task_id < GKI_MAX_TASKS)
+    {
+        /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
+        pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+        /* Set the event bit */
+        gki_cb.com.OSWaitEvt[task_id] |= event;
+
+        pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
+
+        pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+        GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
+        return ( GKI_SUCCESS );
+    }
+    return (GKI_FAILURE);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_isend_event
+**
+** Description      This function is called from ISRs to send events to other
+**                  tasks. The only difference between this function and GKI_send_event
+**                  is that this function assumes interrupts are already disabled.
+**
+** Parameters:      task_id -  (input) The destination task Id for the event.
+**                  event   -  (input) The event flag
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put your code here, otherwise you can delete the entire
+**                  body of the function.
+**
+*******************************************************************************/
+UINT8 GKI_isend_event (UINT8 task_id, UINT16 event)
+{
+
+    GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
+    GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
+    return    GKI_send_event(task_id, event);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_taskid
+**
+** Description      This function gets the currently running task ID.
+**
+** Returns          task ID
+**
+** NOTE             The Widcomm upper stack and profiles may run as a single task.
+**                  If you only have one GKI task, then you can hard-code this
+**                  function to return a '1'. Otherwise, you should have some
+**                  OS-specific method to determine the current task.
+**
+*******************************************************************************/
+UINT8 GKI_get_taskid (void)
+{
+    int i;
+
+    pthread_t thread_id = pthread_self( );
+    for (i = 0; i < GKI_MAX_TASKS; i++) {
+        if (gki_cb.os.thread_id[i] == thread_id) {
+            GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
+            return(i);
+        }
+    }
+
+    GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
+
+    return(-1);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_map_taskname
+**
+** Description      This function gets the task name of the taskid passed as arg.
+**                  If GKI_MAX_TASKS is passed as arg the currently running task
+**                  name is returned
+**
+** Parameters:      task_id -  (input) The id of the task whose name is being
+**                  sought. GKI_MAX_TASKS is passed to get the name of the
+**                  currently running task.
+**
+** Returns          pointer to task name
+**
+** NOTE             this function needs no customization
+**
+*******************************************************************************/
+UINT8 *GKI_map_taskname (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_map_taskname %d", task_id);
+
+    if (task_id < GKI_MAX_TASKS)
+    {
+        GKI_TRACE_2("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
+         return (gki_cb.com.OSTName[task_id]);
+    }
+    else if (task_id == GKI_MAX_TASKS )
+    {
+        return (gki_cb.com.OSTName[GKI_get_taskid()]);
+    }
+    else
+    {
+        return (UINT8*) "BAD";
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_enable
+**
+** Description      This function enables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enable (void)
+{
+    GKI_TRACE_0("GKI_enable");
+    pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
+/* 	pthread_mutex_xx is nesting save, no need for this: already_disabled = 0; */
+    GKI_TRACE_0("Leaving GKI_enable");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_disable
+**
+** Description      This function disables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_disable (void)
+{
+    //GKI_TRACE_0("GKI_disable");
+
+/*	pthread_mutex_xx is nesting save, no need for this: if (!already_disabled) {
+    already_disabled = 1; */
+    		pthread_mutex_lock(&gki_cb.os.GKI_mutex);
+/*  } */
+    //GKI_TRACE_0("Leaving GKI_disable");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_exception
+**
+** Description      This function throws an exception.
+**                  This is normally only called for a nonrecoverable error.
+**
+** Parameters:      code    -  (input) The code for the error
+**                  msg     -  (input) The message that has to be logged
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_exception (UINT16 code, char *msg)
+{
+    UINT8 task_id;
+    int i = 0;
+
+    GKI_TRACE_ERROR_0( "GKI_exception(): Task State Table");
+
+    for(task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+    {
+        GKI_TRACE_ERROR_3( "TASK ID [%d] task name [%s] state [%d]",
+                         task_id,
+                         gki_cb.com.OSTName[task_id],
+                         gki_cb.com.OSRdyTbl[task_id]);
+    }
+
+    GKI_TRACE_ERROR_2("GKI_exception %d %s", code, msg);
+    GKI_TRACE_ERROR_0( "********************************************************************");
+    GKI_TRACE_ERROR_2( "* GKI_exception(): %d %s", code, msg);
+    GKI_TRACE_ERROR_0( "********************************************************************");
+
+#if (GKI_DEBUG == TRUE)
+    GKI_disable();
+
+    if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION)
+    {
+        EXCEPTION_T *pExp;
+
+        pExp =  &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
+        pExp->type = code;
+        pExp->taskid = GKI_get_taskid();
+        strncpy((char *)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
+    }
+
+    GKI_enable();
+#endif
+
+    GKI_TRACE_ERROR_2("GKI_exception %d %s done", code, msg);
+
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_time_stamp
+**
+** Description      This function formats the time into a user area
+**
+** Parameters:      tbuf -  (output) the address to the memory containing the
+**                  formatted time
+**
+** Returns          the address of the user area containing the formatted time
+**                  The format of the time is ????
+**
+** NOTE             This function is only called by OBEX.
+**
+*******************************************************************************/
+INT8 *GKI_get_time_stamp (INT8 *tbuf)
+{
+    UINT32 ms_time;
+    UINT32 s_time;
+    UINT32 m_time;
+    UINT32 h_time;
+    INT8   *p_out = tbuf;
+
+    gki_cb.com.OSTicks = times(0);
+    ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
+    s_time  = ms_time/100;   /* 100 Ticks per second */
+    m_time  = s_time/60;
+    h_time  = m_time/60;
+
+    ms_time -= s_time*100;
+    s_time  -= m_time*60;
+    m_time  -= h_time*60;
+
+    *p_out++ = (INT8)((h_time / 10) + '0');
+    *p_out++ = (INT8)((h_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((m_time / 10) + '0');
+    *p_out++ = (INT8)((m_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((s_time / 10) + '0');
+    *p_out++ = (INT8)((s_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((ms_time / 10) + '0');
+    *p_out++ = (INT8)((ms_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out   = 0;
+
+    return (tbuf);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_register_mempool
+**
+** Description      This function registers a specific memory pool.
+**
+** Parameters:      p_mem -  (input) pointer to the memory pool
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If your OS has different memory pools, you
+**                  can tell GKI the pool to use by calling this function.
+**
+*******************************************************************************/
+void GKI_register_mempool (void *p_mem)
+{
+    gki_cb.com.p_user_mempool = p_mem;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_malloc
+**
+** Description      This function allocates memory
+**
+** Parameters:      size -  (input) The size of the memory that has to be
+**                  allocated
+**
+** Returns          the address of the memory allocated, or NULL if failed
+**
+** NOTE             This function is called by the Widcomm stack when
+**                  dynamic memory allocation is used. (see dyn_mem.h)
+**
+*******************************************************************************/
+void *GKI_os_malloc (UINT32 size)
+{
+    return (malloc(size));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_free
+**
+** Description      This function frees memory
+**
+** Parameters:      size -  (input) The address of the memory that has to be
+**                  freed
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. It is only called from within GKI if dynamic
+**
+*******************************************************************************/
+void GKI_os_free (void *p_mem)
+{
+    if(p_mem != NULL)
+		free(p_mem);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_suspend_task()
+**
+** Description      This function suspends the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to suspended
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension capability,
+**                  put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_suspend_task (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_suspend_task %d - NOT implemented", task_id);
+
+
+    GKI_TRACE_1("GKI_suspend_task %d done", task_id);
+
+    return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_resume_task()
+**
+** Description      This function resumes the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to resumed
+**
+** Returns          GKI_SUCCESS if all OK
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension capability,
+**                  put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_resume_task (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_resume_task %d - NOT implemented", task_id);
+
+
+    GKI_TRACE_1("GKI_resume_task %d done", task_id);
+
+    return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_exit_task
+**
+** Description      This function is called to stop a GKI task.
+**
+** Parameters:      task_id  - (input) the id of the task that has to be stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here to kill a task.
+**
+*******************************************************************************/
+void GKI_exit_task (UINT8 task_id)
+{
+    GKI_disable();
+    gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
+
+    /* Destroy mutex and condition variable objects */
+    pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
+    pthread_cond_destroy (&gki_cb.os.thread_evt_cond[task_id]);
+    pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
+    pthread_cond_destroy (&gki_cb.os.thread_timeout_cond[task_id]);
+
+    GKI_enable();
+
+	//GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+    GKI_TRACE_1("GKI_exit_task %d done", task_id);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_sched_lock
+**
+** Description      This function is called by tasks to disable scheduler
+**                  task context switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to disable context switching.
+**
+*******************************************************************************/
+void GKI_sched_lock(void)
+{
+    GKI_TRACE_0("GKI_sched_lock");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_sched_unlock
+**
+** Description      This function is called by tasks to enable scheduler switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to re-enable context switching.
+**
+*******************************************************************************/
+void GKI_sched_unlock(void)
+{
+    GKI_TRACE_0("GKI_sched_unlock");
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftdown
+**
+** Description      shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount)
+{
+    register UINT8 *ps = p_mem + len - 1;
+    register UINT8 *pd = ps + shift_amount;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftup
+**
+** Description      shift memory up (to delete a record)
+**
+*******************************************************************************/
+void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len)
+{
+    register UINT8 *ps = p_src;
+    register UINT8 *pd = p_dest;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd++ = *ps++;
+}
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_api.c b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
new file mode 100644
index 0000000..06c970c
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
@@ -0,0 +1,288 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFC Hardware Abstraction Layer API: Implementation for Broadcom NFC
+ *  controllers
+ *
+ ******************************************************************************/
+#include "gki.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+/*******************************************************************************
+** NFC_HAL_TASK declarations
+*******************************************************************************/
+#define NFC_HAL_TASK_STR            ((INT8 *) "NFC_HAL_TASK")
+#define NFC_HAL_TASK_STACK_SIZE     0x400
+UINT32 nfc_hal_task_stack[(NFC_HAL_TASK_STACK_SIZE+3)/4];
+
+/*******************************************************************************
+**
+** Function         HAL_NfcInitialize
+**
+** Description      Called when HAL library is loaded.
+**
+**                  Initialize GKI and start the HCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcInitialize (void)
+{
+    NCI_TRACE_API0 ("HAL_NfcInitialize ()");
+
+    /* Initialize HAL control block */
+    nfc_hal_main_init ();
+
+    /* Initialize OS */
+    GKI_init ();
+
+    /* Enable interrupts */
+    GKI_enable ();
+
+    /* Create the NCI transport task */
+    GKI_create_task ((TASKPTR)nfc_hal_main_task,
+                     NFC_HAL_TASK,
+                     NFC_HAL_TASK_STR,
+                     (UINT16 *) ((UINT8 *)nfc_hal_task_stack + NFC_HAL_TASK_STACK_SIZE),
+                     sizeof(nfc_hal_task_stack), NULL, NULL);
+
+    /* Start tasks */
+    GKI_run (0);
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcTerminate
+**
+** Description      Called to terminate NFC HAL
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcTerminate(void)
+{
+    NCI_TRACE_API0 ("HAL_NfcTerminate ()");
+}
+
+
+/*******************************************************************************
+**
+** Function         HAL_NfcOpen
+**
+** Description      Open transport and intialize the NFCC, and
+**                  Register callback for HAL event notifications,
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback)
+{
+    NCI_TRACE_API0 ("HAL_NfcOpen ()");
+
+    /* Only handle if HAL is not opened (stack cback is NULL) */
+    if (p_hal_cback)
+    {
+        nfc_hal_dm_init ();
+        nfc_hal_cb.p_stack_cback = p_hal_cback;
+        nfc_hal_cb.p_data_cback  = p_data_cback;
+
+        /* Send startup event to NFC_HAL_TASK */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_INITIALIZE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcClose
+**
+** Description      Prepare for shutdown. A HAL_CLOSE_DONE_EVENT will be
+**                  reported when complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcClose (void)
+{
+    NCI_TRACE_API0 ("HAL_NfcClose ()");
+
+    /* Only handle if HAL is opened (stack cback is not-NULL) */
+    if (nfc_hal_cb.p_stack_cback)
+    {
+        /* Send shutdown event to NFC_HAL_TASK */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcCoreInitialized
+**
+** Description      Called after the CORE_INIT_RSP is received from the NFCC.
+**                  At this time, the HAL can do any chip-specific configuration,
+**                  and when finished signal the libnfc-nci with event
+**                  HAL_POST_INIT_DONE.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcCoreInitialized (UINT8 *p_core_init_rsp_params)
+{
+    NFC_HDR *p_msg;
+    UINT16  size;
+
+    NCI_TRACE_API0 ("HAL_NfcCoreInitialized ()");
+
+    /* NCI payload len + NCI header size */
+    size = p_core_init_rsp_params[2] + NCI_MSG_HDR_SIZE;
+
+    /* Send message to NFC_HAL_TASK */
+    if ((p_msg = (NFC_HDR *)GKI_getbuf ((UINT16)(size + NFC_HDR_SIZE))) != NULL)
+    {
+        p_msg->event  = NFC_HAL_EVT_POST_CORE_RESET;
+        p_msg->offset = 0;
+        p_msg->len    = size;
+        p_msg->layer_specific = 0;
+        memcpy ((UINT8 *)(p_msg + 1) + p_msg->offset, p_core_init_rsp_params, size);
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcWrite
+**
+** Description      Send an NCI control message or data packet to the
+**                  transport. If an NCI command message exceeds the transport
+**                  size, HAL is responsible for fragmenting it, Data packets
+**                  must be of the correct size.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcWrite (UINT16 data_len, UINT8 *p_data)
+{
+    NFC_HDR *p_msg;
+    UINT8 mt;
+
+    NCI_TRACE_API0 ("HAL_NfcWrite ()");
+
+    if (data_len > (NCI_MAX_CTRL_SIZE + NCI_MSG_HDR_SIZE))
+    {
+        NCI_TRACE_ERROR1 ("HAL_NfcWrite (): too many bytes (%d)", data_len);
+        return;
+    }
+
+    /* Send message to NFC_HAL_TASK */
+    if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        p_msg->event  = NFC_HAL_EVT_TO_NFC_NCI;
+        p_msg->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+        p_msg->len    = data_len;
+        memcpy ((UINT8 *)(p_msg+1) + p_msg->offset, p_data, data_len);
+
+        /* Check if message is a command or data */
+        mt = (*(p_data) & NCI_MT_MASK) >> NCI_MT_SHIFT;
+        p_msg->layer_specific = (mt == NCI_MT_CMD) ? NFC_HAL_WAIT_RSP_CMD : 0;
+
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreDiscover
+**
+** Description      Perform any vendor-specific pre-discovery actions (if needed)
+**                  If any actions were performed TRUE will be returned, and
+**                  HAL_PRE_DISCOVER_DONE_EVENT will notify when actions are
+**                  completed.
+**
+** Returns          TRUE if vendor-specific pre-discovery actions initialized
+**                  FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPreDiscover (void)
+{
+    BOOLEAN status = FALSE;
+
+    NCI_TRACE_API1 ("HAL_NfcPreDiscover status:%d", status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcControlGranted
+**
+** Description      Grant control to HAL control for sending NCI commands.
+**
+**                  Call in response to HAL_REQUEST_CONTROL_EVENT.
+**
+**                  Must only be called when there are no NCI commands pending.
+**
+**                  HAL_RELEASE_CONTROL_EVENT will notify when HAL no longer
+**                  needs control of NCI.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcControlGranted (void)
+{
+    NFC_HDR *p_msg;
+    NCI_TRACE_API0 ("HAL_NfcControlGranted ()");
+
+    /* Send message to NFC_HAL_TASK */
+    if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        p_msg->event  = NFC_HAL_EVT_CONTROL_GRANTED;
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPowerCycle
+**
+** Description      Restart NFCC by power cyle
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPowerCycle (void)
+{
+    NCI_TRACE_API0 ("HAL_NfcPowerCycle ()");
+
+    /* Only handle if HAL is opened (stack cback is not-NULL) */
+    if (nfc_hal_cb.p_stack_cback)
+    {
+        /* Send power cycle event to NFC_HAL_TASK */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_POWER_CYCLE);
+    }
+}
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
new file mode 100644
index 0000000..d52119a
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
@@ -0,0 +1,29 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains function of the NFC unit to receive/process NFC VS
+ *  commands.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
new file mode 100644
index 0000000..c4d4a3f
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
@@ -0,0 +1,1092 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Vendor-specific handler for DM events
+ *
+ ******************************************************************************/
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "upio.h"
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+
+#define NFC_HAL_I93_RW_CFG_LEN              (5)
+#define NFC_HAL_I93_RW_CFG_PARAM_LEN        (3)
+#define NFC_HAL_I93_AFI                     (0)
+#define NFC_HAL_I93_ENABLE_SMART_POLL       (1)
+
+static UINT8 nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] =
+{
+    NCI_PARAM_ID_I93_DATARATE,
+    NFC_HAL_I93_RW_CFG_PARAM_LEN,
+    NFC_HAL_I93_FLAG_DATA_RATE,    /* Bit0:Sub carrier, Bit1:Data rate, Bit4:Enable/Disable AFI */
+    NFC_HAL_I93_AFI,               /* AFI if Bit 4 is set in the flag byte */
+    NFC_HAL_I93_ENABLE_SMART_POLL  /* Bit0:Enable/Disable smart poll */
+};
+
+static UINT8 nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_SET_FWFSM,
+    0x01,
+    0x00,
+};
+#define NCI_SET_FWFSM_OFFSET_ENABLE      3
+
+const UINT8 nfc_hal_dm_core_reset_cmd[NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET] =
+{
+    NCI_MTS_CMD|NCI_GID_CORE,
+    NCI_MSG_CORE_RESET,
+    NCI_CORE_PARAM_SIZE_RESET,
+    NCI_RESET_TYPE_RESET_CFG
+};
+
+#define NCI_PROP_PARAM_SIZE_XTAL_INDEX      3       /* length of parameters in XTAL_INDEX CMD */
+
+const UINT8 nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_GET_BUILD_INFO,
+    0x00
+};
+#define NCI_BUILD_INFO_OFFSET_HWID  25  /* HW ID offset in build info RSP */
+
+const UINT8 nfc_hal_dm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_GET_PATCH_VERSION,
+    0x00
+};
+#define NCI_PATCH_INFO_OFFSET_NVMTYPE  35  /* NVM Type offset in patch info RSP */
+
+/*****************************************************************************
+** Extern function prototypes
+*****************************************************************************/
+extern UINT8 *p_nfc_hal_dm_lptd_cfg;
+extern UINT8 *p_nfc_hal_dm_pll_325_cfg;
+extern UINT8 *p_nfc_hal_dm_start_up_cfg;
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg;
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_config
+**
+** Description      Send NCI config items to NFCC
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size,
+                                       UINT8 *p_param_tlvs,
+                                       tNFC_HAL_NCI_CBACK *p_cback)
+{
+    UINT8  *p_buff, *p;
+    UINT8  num_param = 0, param_len, rem_len, *p_tlv;
+    UINT16 cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+    tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+
+    if ((tlv_size == 0)||(p_param_tlvs == NULL))
+    {
+        return status;
+    }
+
+    if ((p_buff = (UINT8 *) GKI_getbuf ((UINT16)(NCI_MSG_HDR_SIZE + tlv_size))) != NULL)
+    {
+        p = p_buff;
+
+        NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE);
+        NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_SET_CONFIG);
+        UINT8_TO_STREAM  (p, (UINT8) (tlv_size + 1));
+
+        rem_len = tlv_size;
+        p_tlv   = p_param_tlvs;
+        while (rem_len > 1)
+        {
+            num_param++;                /* number of params */
+
+            p_tlv ++;                   /* param type   */
+            param_len = *p_tlv++;       /* param length */
+
+            rem_len -= 2;               /* param type and length */
+            if (rem_len >= param_len)
+            {
+                rem_len -= param_len;
+                p_tlv   += param_len;   /* next param_type */
+
+                if (rem_len == 0)
+                {
+                    status = HAL_NFC_STATUS_OK;
+                    break;
+                }
+            }
+            else
+            {
+                /* error found */
+                break;
+            }
+        }
+
+        if (status == HAL_NFC_STATUS_OK)
+        {
+            UINT8_TO_STREAM (p, num_param);
+            ARRAY_TO_STREAM (p, p_param_tlvs, tlv_size);
+
+            nfc_hal_dm_send_nci_cmd (p_buff, cmd_len, p_cback);
+        }
+        else
+        {
+            NCI_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV");
+        }
+
+        GKI_freebuf (p_buff);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_get_xtal_index
+**
+** Description      Convert xtal frequency to index
+**
+** Returns          xtal index
+**
+*******************************************************************************/
+static tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index (UINT16 xtal_freq)
+{
+    tNFC_HAL_XTAL_INDEX xtal_index;
+
+    switch (xtal_freq)
+    {
+    case  9600: xtal_index = NFC_HAL_XTAL_INDEX_9600;  break;
+    case 13000: xtal_index = NFC_HAL_XTAL_INDEX_13000; break;
+    case 16200: xtal_index = NFC_HAL_XTAL_INDEX_16200; break;
+    case 19200: xtal_index = NFC_HAL_XTAL_INDEX_19200; break;
+    case 24000: xtal_index = NFC_HAL_XTAL_INDEX_24000; break;
+    case 26000: xtal_index = NFC_HAL_XTAL_INDEX_26000; break;
+    case 38400: xtal_index = NFC_HAL_XTAL_INDEX_38400; break;
+    case 52000: xtal_index = NFC_HAL_XTAL_INDEX_52000; break;
+    case 37400: xtal_index = NFC_HAL_XTAL_INDEX_37400; break;
+    default :   xtal_index = NFC_HAL_XTAL_INDEX_MAX;
+                NCI_TRACE_DEBUG1 ("nfc_hal_dm_get_xtal_index ():No matched index for %d", xtal_freq);
+                break;
+    }
+
+    return xtal_index;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_fw_fsm
+**
+** Description      Enable or disable FW FSM
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_fw_fsm (BOOLEAN enable, tNFC_HAL_NCI_CBACK *p_cback)
+{
+    if (enable)
+        nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x01; /* Enable, default is disabled */
+    else
+        nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */
+
+    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1, p_cback);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_config_nfcc_cback
+**
+** Description      Callback for NCI vendor specific command complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_config_nfcc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE)
+    {
+        nfc_hal_hci_enable ();
+    }
+    else
+    {
+        nfc_hal_dm_config_nfcc ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_startup_vsc
+**
+** Description      Send VS command before NFA start-up
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_dm_send_startup_vsc (void)
+{
+    UINT8  *p, *p_end;
+    UINT16 len;
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_dm_send_startup_vsc ()");
+
+    /* VSC must have NCI header at least */
+    if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <= *p_nfc_hal_dm_start_up_vsc_cfg)
+    {
+        p     = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc;
+        len   = *(p + 2);
+        p_end = p + NCI_MSG_HDR_SIZE - 1 + len;
+
+        if (p_end <= p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
+        {
+            /* move to next VSC */
+            nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len;
+
+            /* if this is last VSC */
+            if (p_end == p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
+                nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
+
+            nfc_hal_dm_send_nci_cmd (p, (UINT16)(NCI_MSG_HDR_SIZE + len), nfc_hal_dm_config_nfcc_cback);
+            return;
+        }
+    }
+
+    NCI_TRACE_ERROR0 ("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC");
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+    nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_config_nfcc
+**
+** Description      Send VS config before NFA start-up
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_config_nfcc (void)
+{
+    UINT8   *p;
+    UINT8   xtal_index;
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_config_nfcc (): next_dm_config = %d", nfc_hal_cb.dev_cb.next_dm_config);
+
+    if ((p_nfc_hal_dm_lptd_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD))
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325;
+
+        if (nfc_hal_dm_set_config (p_nfc_hal_dm_lptd_cfg[0],
+                                   &p_nfc_hal_dm_lptd_cfg[1],
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+    if ((p_nfc_hal_dm_pll_325_cfg) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325))
+    {
+        xtal_index = nfc_hal_dm_get_xtal_index (nfc_post_reset_cb.dev_init_config.xtal_freq);
+        if (xtal_index < NFC_HAL_XTAL_INDEX_MAX)
+        {
+            nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP;
+            p = p_nfc_hal_dm_pll_325_cfg + (xtal_index * NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN);
+            if (nfc_hal_dm_set_config (NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN,
+                                       p,
+                                       nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+            {
+                return;
+            }
+            else
+            {
+                NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+                nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+                return;
+            }
+        }
+    }
+
+    if ((p_nfc_hal_dm_start_up_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP))
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE;
+        if (nfc_hal_dm_set_config (p_nfc_hal_dm_start_up_cfg[0],
+                                   &p_nfc_hal_dm_start_up_cfg[1],
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+#if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH)
+    if (nfc_hal_cb.dev_cb.next_dm_config  <= NFC_HAL_DM_CONFIG_I93_DATA_RATE)
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM;
+        if (nfc_hal_dm_set_config (NFC_HAL_I93_RW_CFG_LEN,
+                                   nfc_hal_dm_i93_rw_cfg,
+                                   nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+        {
+            return;
+        }
+        else
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+            return;
+        }
+    }
+#endif
+
+    /* FW FSM is disabled as default in NFCC */
+    if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM)
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC;
+        nfc_hal_dm_set_fw_fsm (NFC_HAL_DM_MULTI_TECH_RESP, nfc_hal_dm_config_nfcc_cback);
+        return;
+    }
+
+    if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC)
+    {
+        if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg)
+        {
+            nfc_hal_dm_send_startup_vsc ();
+            return;
+        }
+    }
+
+    /* nothing to config */
+    nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
+    nfc_hal_dm_config_nfcc_cback (0, 0, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_xtal_freq_index
+**
+** Description      Set crystal frequency index
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_xtal_freq_index (void)
+{
+    UINT8 nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_SIZE_XTAL_INDEX];
+    UINT8 *p;
+    tNFC_HAL_XTAL_INDEX xtal_index;
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_set_xtal_freq_index (): xtal_freq = %d", nfc_post_reset_cb.dev_init_config.xtal_freq);
+
+    xtal_index = nfc_hal_dm_get_xtal_index (nfc_post_reset_cb.dev_init_config.xtal_freq);
+
+    switch (xtal_index)
+    {
+    case NFC_HAL_XTAL_INDEX_9600:
+    case NFC_HAL_XTAL_INDEX_13000:
+    case NFC_HAL_XTAL_INDEX_19200:
+    case NFC_HAL_XTAL_INDEX_26000:
+    case NFC_HAL_XTAL_INDEX_38400:
+    case NFC_HAL_XTAL_INDEX_52000:
+
+        {
+            /* no need to set xtal index for these frequency */
+            NCI_TRACE_DEBUG0 ("nfc_hal_dm_set_xtal_freq_index (): no need to set xtal index");
+
+            nfc_post_reset_cb.dev_init_config.flags &= ~NFC_HAL_DEV_INIT_FLAGS_SET_XTAL_FREQ;
+            nfc_hal_dm_send_reset_cmd ();
+            return;
+        }
+        break;
+    }
+
+    p = nci_brcm_xtal_index_cmd;
+    UINT8_TO_STREAM  (p, (NCI_MTS_CMD|NCI_GID_PROP));
+    UINT8_TO_STREAM  (p, NCI_MSG_GET_XTAL_INDEX_FROM_DH);
+    UINT8_TO_STREAM  (p, NCI_PROP_PARAM_SIZE_XTAL_INDEX);
+    UINT8_TO_STREAM  (p, xtal_index);
+    UINT16_TO_STREAM (p, nfc_post_reset_cb.dev_init_config.xtal_freq);
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_XTAL_SET);
+
+    nfc_hal_dm_send_nci_cmd (nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_SIZE_XTAL_INDEX, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_reset_cmd
+**
+** Description      Send CORE RESET CMD
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_reset_cmd (void)
+{
+    /* Proceed with start up sequence: send CORE_RESET_CMD */
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_RESET);
+
+    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_core_reset_cmd, NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_proc_msg_during_init
+**
+** Description      Process NCI message while initializing NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg)
+{
+    UINT8 *p;
+    UINT8 reset_reason, reset_type;
+    UINT8 mt, pbf, gid, op_code;
+    UINT8 *p_old, old_gid, old_oid, old_mt;
+    tNFC_HAL_NCI_CBACK *p_cback = NULL;
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_init(): init state:%d", nfc_hal_cb.dev_cb.initializing_state);
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+    NCI_MSG_PRS_HDR1 (p, op_code);
+
+    /* check if waiting for this response */
+    if (  (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD)
+        ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC)  )
+    {
+        if (mt == NCI_MT_RSP)
+        {
+            p_old = nfc_hal_cb.ncit_cb.last_hdr;
+            NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid);
+            old_oid = ((*p_old) & NCI_OID_MASK);
+            /* make sure this is the RSP we are waiting for before updating the command window */
+            if ((old_gid == gid) && (old_oid == op_code))
+            {
+                nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+                p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
+                nfc_hal_cb.ncit_cb.p_vsc_cback  = NULL;
+                nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+            }
+        }
+    }
+
+    if (gid == NCI_GID_CORE)
+    {
+        if (op_code == NCI_MSG_CORE_RESET)
+        {
+            if (mt == NCI_MT_RSP)
+            {
+                if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_RE_INIT)
+                {
+                    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE);
+                    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_cb.p_reinit_cback);
+                }
+                else
+                {
+                    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_BUILD_INFO);
+
+                    /* get build information to find out HW */
+                    nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE, NULL);
+                }
+            }
+            else
+            {
+                /* Call reset notification callback */
+                p++;                                /* Skip over param len */
+                STREAM_TO_UINT8 (reset_reason, p);
+                STREAM_TO_UINT8 (reset_type, p);
+                nfc_hal_prm_spd_reset_ntf (reset_reason, reset_type);
+            }
+        }
+        else if (p_cback)
+        {
+            (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code),
+                        p_msg->len,
+                        (UINT8 *) (p_msg + 1) + p_msg->offset);
+        }
+    }
+    else if (gid == NCI_GID_PROP) /* this is for download patch */
+    {
+        if (mt == NCI_MT_NTF)
+            op_code |= NCI_NTF_BIT;
+        else
+            op_code |= NCI_RSP_BIT;
+
+        if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_XTAL_SET)
+        {
+            if (op_code == (NCI_RSP_BIT|NCI_MSG_GET_XTAL_INDEX_FROM_DH))
+            {
+                /* wait for crystal setting in NFCC */
+                GKI_delay (100);
+
+                /* Crytal frequency configured. Proceed with start up sequence: send CORE_RESET_CMD */
+                nfc_hal_dm_send_reset_cmd ();
+            }
+        }
+        else if (  (op_code == NFC_VS_GET_BUILD_INFO_EVT)
+                 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO)  )
+        {
+            p += NCI_BUILD_INFO_OFFSET_HWID;
+
+            STREAM_TO_UINT32 (nfc_hal_cb.dev_cb.brcm_hw_id, p);
+
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO);
+
+            nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL);
+        }
+        else if (  (op_code == NFC_VS_GET_PATCH_VERSION_EVT)
+                 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO)  )
+        {
+            p += NCI_PATCH_INFO_OFFSET_NVMTYPE;
+
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE);
+
+            /* let platform update baudrate or download patch */
+            nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, *p);
+        }
+        else if (p_cback)
+        {
+            (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code),
+                        p_msg->len,
+                        (UINT8 *) (p_msg + 1) + p_msg->offset);
+        }
+        else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT)
+        {
+            NCI_TRACE_DEBUG0 ("signature!!");
+            nfc_hal_prm_nci_command_complete_cback ((tNFC_HAL_NCI_EVT) (op_code),
+                                                    p_msg->len,
+                                                    (UINT8 *) (p_msg + 1) + p_msg->offset);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_nci_cmd
+**
+** Description      Send NCI command to NFCC while initializing BRCM NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback)
+{
+    NFC_HDR *p_buf;
+    UINT8  *ps;
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+    {
+        NCI_TRACE_ERROR0 ("nfc_hal_dm_send_nci_cmd(): no command window");
+        return;
+    }
+
+    if ((p_buf = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC;
+
+        p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+        p_buf->event  = NFC_HAL_EVT_TO_NFC_NCI;
+        p_buf->len    = len;
+
+        memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len);
+
+        /* Keep a copy of the command and send to NCI transport */
+
+        /* save the message header to double check the response */
+        ps   = (UINT8 *)(p_buf + 1) + p_buf->offset;
+        memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE);
+        memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_HAL_SAVED_CMD_SIZE);
+
+        /* save the callback for NCI VSCs */
+        nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback;
+
+        nfc_hal_nci_send_cmd (p_buf);
+
+        /* start NFC command-timeout timer */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
+                                        ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_pend_cmd
+**
+** Description      Send a command to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_pend_cmd (void)
+{
+    NFC_HDR *p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd;
+    UINT8  *p;
+
+    if (p_buf == NULL)
+        return;
+
+    /* check low power mode state */
+    if (!nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT))
+    {
+        return;
+    }
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
+    {
+#if (NFC_HAL_TRACE_PROTOCOL == TRUE)
+        DispHciCmd (p_buf);
+#endif
+
+        /* save the message header to double check the response */
+        p = (UINT8 *)(p_buf + 1) + p_buf->offset;
+        memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE);
+
+        /* add packet type for BT message */
+        p_buf->offset--;
+        p_buf->len++;
+
+        p  = (UINT8 *) (p_buf + 1) + p_buf->offset;
+        *p = HCIT_TYPE_COMMAND;
+
+        USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+        GKI_freebuf (p_buf);
+        nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
+
+        /* start NFC command-timeout timer */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
+                                        ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_bt_cmd
+**
+** Description      Send BT message to NFCC while initializing BRCM NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback)
+{
+    NFC_HDR *p_buf;
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+    {
+        NCI_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window");
+        return;
+    }
+
+    if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP;
+
+        p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+        p_buf->len    = len;
+
+        memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len);
+
+        /* save the callback for NCI VSCs)  */
+        nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback;
+
+        nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf;
+        if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
+        {
+            NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK);
+            return;
+        }
+
+        nfc_hal_dm_send_pend_cmd();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_nfc_wake
+**
+** Description      Set NFC_WAKE line
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_nfc_wake (UINT8 cmd)
+{
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_set_nfc_wake () %s",
+                      (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT"));
+
+    /*
+    **  nfc_wake_active_mode             cmd              result of voltage on NFC_WAKE
+    **
+    **  NFC_HAL_LP_ACTIVE_LOW (0)    NFC_HAL_ASSERT_NFC_WAKE (0)    pull down NFC_WAKE (GND)
+    **  NFC_HAL_LP_ACTIVE_LOW (0)    NFC_HAL_DEASSERT_NFC_WAKE (1)  pull up NFC_WAKE (VCC)
+    **  NFC_HAL_LP_ACTIVE_HIGH (1)   NFC_HAL_ASSERT_NFC_WAKE (0)    pull up NFC_WAKE (VCC)
+    **  NFC_HAL_LP_ACTIVE_HIGH (1)   NFC_HAL_DEASSERT_NFC_WAKE (1)  pull down NFC_WAKE (GND)
+    */
+
+    if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode)
+        UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_OFF); /* pull down NFC_WAKE */
+    else
+        UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_ON);  /* pull up NFC_WAKE */
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_power_mode_execute
+**
+** Description      If snooze mode is enabled in full power mode,
+**                     Assert NFC_WAKE before sending data
+**                     Deassert NFC_WAKE when idle timer expires
+**
+** Returns          TRUE if DH can send data to NFCC
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event)
+{
+    BOOLEAN send_to_nfcc = FALSE;
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_dm_power_mode_execute () event = %d", event);
+
+    if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+    {
+        if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+        {
+            /* if any transport activity */
+            if (  (event == NFC_HAL_LP_TX_DATA_EVT)
+                ||(event == NFC_HAL_LP_RX_DATA_EVT)  )
+            {
+                /* if idle timer is not running */
+                if (nfc_hal_cb.dev_cb.lp_timer.in_use == FALSE)
+                {
+                    nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+                }
+
+                /* start or extend idle timer */
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00,
+                                                ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+            }
+            else if (event == NFC_HAL_LP_TIMEOUT_EVT)
+            {
+                /* let NFCC go to snooze mode */
+                nfc_hal_dm_set_nfc_wake (NFC_HAL_DEASSERT_NFC_WAKE);
+            }
+        }
+
+        send_to_nfcc = TRUE;
+    }
+
+    return (send_to_nfcc);
+}
+
+/*******************************************************************************
+**
+** Function         nci_brcm_lp_timeout_cback
+**
+** Description      callback function for low power timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nci_brcm_lp_timeout_cback (void *p_tle)
+{
+    NCI_TRACE_DEBUG0 ("nci_brcm_lp_timeout_cback ()");
+
+    nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TIMEOUT_EVT);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_pre_init_nfcc
+**
+** Description      This function initializes Broadcom specific control blocks for
+**                  NCI transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_pre_init_nfcc (void)
+{
+    NCI_TRACE_DEBUG0 ("nfc_hal_dm_pre_init_nfcc ()");
+
+    if (nfc_post_reset_cb.dev_init_config.flags & NFC_HAL_DEV_INIT_FLAGS_SET_XTAL_FREQ)
+    {
+        nfc_hal_dm_set_xtal_freq_index ();
+    }
+    else
+    {
+        /* Send RESET CMD if application registered callback for device initialization */
+        nfc_hal_dm_send_reset_cmd ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_shutting_down_nfcc
+**
+** Description      This function initializes Broadcom specific control blocks for
+**                  NCI transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_shutting_down_nfcc (void)
+{
+    NCI_TRACE_DEBUG0 ("nfc_hal_dm_shutting_down_nfcc ()");
+
+    nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING;
+
+    /* reset low power mode variables */
+    if (  (nfc_hal_cb.dev_cb.power_mode  == NFC_HAL_POWER_MODE_FULL)
+        &&(nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)  )
+    {
+        nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+    }
+
+    nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+    nfc_hal_cb.hci_cb.b_check_clear_all_pipe_cmd = FALSE;
+
+    nfc_hal_cb.dev_cb.power_mode  = NFC_HAL_POWER_MODE_FULL;
+    nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE;
+
+    /* Stop all timers */
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_init
+**
+** Description      This function initializes Broadcom specific control blocks for
+**                  NCI transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_init (void)
+{
+    NCI_TRACE_DEBUG0 ("nfc_hal_dm_init ()");
+
+    nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback;
+
+    nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback;
+
+    nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback;
+
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcDevInitDone
+**
+** Description      Notify that pre-initialization of NFCC is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status)
+{
+    NCI_TRACE_DEBUG1 ("HAL_NfcPreInitDone () status=%d", status);
+
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+    {
+        NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+
+        nfc_hal_main_pre_init_done (status);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcReInit
+**
+** Description      This function is called to send an RESET and GET_PATCH_VERSION
+**                  command to NFCC.
+**
+**                  p_cback         - The callback function to receive the command
+**                                    status
+**
+** Note             This function should be called only during the HAL init process
+**
+** Returns          HAL_NFC_STATUS_OK if successfully initiated
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcReInit (tNFC_HAL_NCI_CBACK *p_cback)
+{
+    tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+    NCI_TRACE_DEBUG1 ("HAL_NfcReInit () init st=0x%x", nfc_hal_cb.dev_cb.initializing_state);
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+    {
+        /* Proceed with start up sequence: send CORE_RESET_CMD */
+        NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_RE_INIT);
+        nfc_hal_cb.p_reinit_cback = p_cback;
+
+        nfc_hal_dm_send_nci_cmd (nfc_hal_dm_core_reset_cmd, NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET, NULL);
+        status = HAL_NFC_STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_snooze_mode_cback
+**
+** Description      This is baud rate update complete callback.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_dm_set_snooze_mode_cback (tNFC_HAL_BTVSC_CPLT *pData)
+{
+    UINT8             status = pData->p_param_buf[0];
+    tHAL_NFC_STATUS   hal_status;
+    tHAL_NFC_STATUS_CBACK *p_cback;
+
+    /* if it is completed */
+    if (status == HCI_SUCCESS)
+    {
+        /* update snooze mode */
+        nfc_hal_cb.dev_cb.snooze_mode = nfc_hal_cb.dev_cb.new_snooze_mode;
+
+        nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+
+        if ( nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+        {
+            /* start idle timer */
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00,
+                                            ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+        }
+        else
+        {
+            nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer);
+        }
+        hal_status = HAL_NFC_STATUS_OK;
+    }
+    else
+    {
+        hal_status = HAL_NFC_STATUS_FAILED;
+    }
+
+    if (nfc_hal_cb.dev_cb.p_prop_cback)
+    {
+        p_cback = nfc_hal_cb.dev_cb.p_prop_cback;
+        nfc_hal_cb.dev_cb.p_prop_cback = NULL;
+        (*p_cback) (hal_status);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetSnoozeMode
+**
+** Description      Set snooze mode
+**                  snooze_mode
+**                      NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
+**                      NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
+**                      NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
+**
+**                  idle_threshold_dh/idle_threshold_nfcc
+**                      Idle Threshold Host in 100ms unit
+**
+**                  nfc_wake_active_mode/dh_wake_active_mode
+**                      NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
+**                      NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting
+**
+**                  p_snooze_cback
+**                      Notify status of operation
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode,
+                                      UINT8 idle_threshold_dh,
+                                      UINT8 idle_threshold_nfcc,
+                                      UINT8 nfc_wake_active_mode,
+                                      UINT8 dh_wake_active_mode,
+                                      tHAL_NFC_STATUS_CBACK *p_snooze_cback)
+{
+    UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH];
+    UINT8 *p;
+
+    NCI_TRACE_API1 ("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode);
+
+    nfc_hal_cb.dev_cb.new_snooze_mode      = snooze_mode;
+    nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode;
+    nfc_hal_cb.dev_cb.p_prop_cback         = p_snooze_cback;
+
+    p = cmd;
+
+    /* Add the HCI command */
+    UINT16_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE);
+    UINT8_TO_STREAM  (p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
+
+    memset (p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
+
+    UINT8_TO_STREAM  (p, snooze_mode);          /* Sleep Mode               */
+
+    UINT8_TO_STREAM  (p, idle_threshold_dh);    /* Idle Threshold Host      */
+    UINT8_TO_STREAM  (p, idle_threshold_nfcc);  /* Idle Threshold HC        */
+    UINT8_TO_STREAM  (p, nfc_wake_active_mode); /* BT Wake Active Mode      */
+    UINT8_TO_STREAM  (p, dh_wake_active_mode);  /* Host Wake Active Mode    */
+
+    nfc_hal_dm_send_bt_cmd (cmd,
+                            NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
+                            nfc_hal_dm_set_snooze_mode_cback);
+    return (NCI_STATUS_OK);
+}
+
+
+
+
+
+
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
new file mode 100644
index 0000000..f16aae7
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
@@ -0,0 +1,133 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for BRCM HAL
+ *  modules
+ *
+ ******************************************************************************/
+#include "nfc_hal_int.h"
+#include "nci_defs.h"
+#include "nfc_brcm_defs.h"
+
+/* the SetConfig at start up*/
+UINT8 nfc_hal_start_up_cfg[] = {
+    /* TLV len */   28,
+    /* B0 */        NCI_PARAM_ID_EMVCO_ENABLE,
+    /* B1 */        1,
+    /* B2 */        1,     /* (1 = enable emvco mode, 0 = disable emvco mode) Default = 0.*/
+    /* B3 */        NCI_PARAM_ID_CONTINUE_MODE, /* NFCC will restart discovery after deactivated */
+    /* B4 */        1,
+    /* B5 */        1,     /* (1 = enable, 0 = disable) Default = 0.*/
+    /* B6 */        NCI_PARAM_ID_RFU_CONFIG,
+    /* B7 */        0x14,
+    /* B8 */        0x00,
+    /* B9 */        0x00,
+    /* B10*/        0x00,
+    /* B11*/        0x00,
+    /* B12*/        0x02,
+    /* B13*/        0xE8,
+    /* B14*/        0x03,
+    /* B15*/        0x00,
+    /* B16*/        0x00,
+    /* B17*/        0x00,
+    /* B18*/        0x00,
+    /* B19*/        0x00,
+    /* B20*/        0x00,
+    /* B21*/        0x00,
+    /* B22*/        0x00,
+    /* B23*/        0x00,
+    /* B24*/        0x00,
+    /* B25*/        0x00,
+    /* B26*/        0x00,
+    /* B27*/        0x00
+};
+
+UINT8 *p_nfc_hal_dm_start_up_cfg = (UINT8 *) nfc_hal_start_up_cfg;
+
+/* the VSCs at start up:
+ * The VSCs are specified in TLV format similar to nfa_start_up_cfg[]
+ * first byte is the TLV total len.
+ * B0 is the first T; i.e. the opcode for the VSC
+ * B1 is the len of the VSC parameters/payload
+ * */
+UINT8 nfc_hal_dm_start_up_vsc_cfg[] = {
+    /* TLV len */   5,
+    /* B0 */        NCI_MTS_CMD|NCI_GID_PROP,
+    /* B1 */        NCI_MSG_FRAME_LOG,
+    /* B2 */        2,
+    /* B3 */        0,  /* 1 to enable RF frames */
+    /* B4 */        1   /* 1 to enable SWP frames */
+};
+
+UINT8 *p_nfc_hal_dm_start_up_vsc_cfg = NULL;
+
+/* LPTD parameters (LowPowerTagDetection)
+ * This is typical values for 20791B2
+ * The timing and threshold parameters used for a customer handset/hardware may vary
+ * depending on antenna and should be verified during a customer testing phase.
+ * the data fields without comments are too complicated. Please see ""
+ * */
+const UINT8 nfc_hal_dm_lptd_cfg[] =
+{
+    21,             /* total TLV length excluding itself */
+    NCI_PARAM_ID_TAGSNIFF_CFG,  /* type */
+    19,             /* length */
+    0x01,           /* B0 enable: 0/disable, 1/enable*/
+    0x02,           /* B1 poll count: number of full power poll before starting lptd poll */
+    0xFF,           /* B2 sniff count lsb: number of lptd poll before switching to full power poll */
+    0xFF,           /* B3 sniff count msb */
+    0x80,           /* B4 threshold: Bigger thresholds give a smaller LPTD range but more immunity to false detections. Smaller thresholds increase LPTD range at the cost of greater likelihood of false detections. */
+    0x40,           /* B5 delay lsb: delay (us) to sampling power */
+    0x00,           /* B6 delay msb */
+    0x40,           /* B7 carrier threshold lsb */
+    0x00,           /* B8 carrier threshold msb */
+    0x80,           /* B9 mode: Bitwise variable used to enable various algorithm modes.*/
+    0x80,           /* B10 0-offset lsb */
+    0x00,           /* B11 0-offset msb */
+    0x10,           /* B12 field sense time lsb */
+    0x00,           /* B13 field sense time msb */
+    0x00,           /* B14 false detect threshold lsb: 0x00 to disable LPTD NTF. The number of false tag detections to resport LPTD NTF. */
+    0x00,           /* B15 false detect threshold msb. A false tag detect - full poll results in no tag being detected.*/
+    0x75,           /* B16 mode1; Bitwise variable used to enable various algorithm modes. */
+    0x0D,           /* B17 lptd ant cfg rx */
+    0x30,           /* B18 lptd rdr cfg ve */
+};
+
+UINT8 *p_nfc_hal_dm_lptd_cfg = (UINT8 *) &nfc_hal_dm_lptd_cfg[0];
+
+/* This must be configured before setting reader mode for 20791. No need to configure for 43341. */
+const UINT8 nfc_hal_dm_pll_325_cfg[NFC_HAL_XTAL_INDEX_MAX][NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN] =
+{
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0x9A, 0x99, 0x99, 0x99, 0xD7, 0x03, 0x00, 0x87, 0x04, 0x1C, 0x0F, 0x00, 0x0B, FALSE}, /*  9.6 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0xEF, 0x90, 0xA8, 0x22, 0xD0, 0x03, 0x00, 0x64, 0x06, 0x26, 0x0F, 0x00, 0x08, FALSE}, /* 13.0 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0x5B, 0xB0, 0x05, 0x5B, 0xD8, 0x03, 0x00, 0x50, 0x07, 0x30, 0x0F, 0x00, 0x06, FALSE}, /* 16.2 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0xCD, 0xCC, 0xCC, 0xCC, 0xD7, 0x03, 0x00, 0x43, 0x09, 0x39, 0x0F, 0x00, 0x04, FALSE}, /* 19.2 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0xD7, 0xA3, 0x70, 0x3D, 0xD0, 0x03, 0x00, 0x36, 0x0B, 0x47, 0x0F, 0x00, 0x03, FALSE}, /* 24.0 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0x78, 0x48, 0x54, 0x11, 0xD0, 0x03, 0x00, 0x32, 0x0C, 0x4D, 0x0F, 0x00, 0x02, FALSE}, /* 26.0 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0xCD, 0xCC, 0xCC, 0xCC, 0xD7, 0x03, 0x00, 0x43, 0x09, 0x39, 0x0F, 0x00, 0x04, TRUE},  /* 38.4 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0x78, 0x48, 0x54, 0x11, 0xD0, 0x03, 0x00, 0x32, 0x0C, 0x4D, 0x0F, 0x00, 0x02, TRUE},  /* 52.0 MHz */
+    {NCI_PARAM_ID_PLL325_CFG_PARAM, NCI_PARAM_LEN_PLL325_CFG_PARAM, 0x29, 0xB4, 0xE2, 0x9C, 0xCF, 0x03, 0x00, 0x45, 0x08, 0x37, 0x0F, 0x00, 0x04, TRUE}   /* 37.4 MHz */
+};
+
+UINT8 *p_nfc_hal_dm_pll_325_cfg = (UINT8 *) nfc_hal_dm_pll_325_cfg;
+
+
+/* set nfc_hal_prm_nvm_required to TRUE, if the platform wants to abort PRM process without NVM */
+BOOLEAN nfc_hal_prm_nvm_required = FALSE;
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
new file mode 100644
index 0000000..1504c94
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
@@ -0,0 +1,441 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Vendor-specific handler for HCI events
+ *
+ ******************************************************************************/
+#include "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+#include <string.h>
+#include "nfc_hal_nv_co.h"
+
+#ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
+#define NFC_HAL_HCI_NV_READ_TIMEOUT    1000
+#endif
+
+#ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
+#define NFC_HAL_HCI_NFCC_RSP_TIMEOUT   3000
+#endif
+
+static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
+static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
+static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
+static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_evt_hdlr
+**
+** Description      Processing event for NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data)
+{
+    switch (p_evt_data->hdr.event)
+    {
+    case NFC_HAL_HCI_RSP_NV_READ_EVT:
+        nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
+        break;
+
+    case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
+        /* NV Ram write completed - nothing to do... */
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_enable
+**
+** Description      Program nv data on to controller
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_hci_enable (void)
+{
+
+    UINT8 *p_hci_netwk_cmd;
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
+    }
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
+    }
+
+    if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
+    {
+        NCI_TRACE_ERROR0 ("nfc_hal_hci_enable: unable to allocate buffer for reading hci network info from nvram");
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+    }
+    else
+    {
+        nfc_hal_cb.hci_cb.p_hci_netwk_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
+        nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
+        memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+        nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F3_NV_BLOCK);
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hci_netwk_info
+**
+** Description      Handler function for HCI Network Notification
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data)
+{
+    UINT8  *p = p_data;
+    UINT16 data_len;
+    UINT8  target_handle;
+    UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_hci_handle_hci_netwk_info()");
+
+    /* skip NCI header byte0 (MT,GID), byte1 (OID) */
+    p += 2;
+
+    STREAM_TO_UINT8 (data_len, p);
+    target_handle = *(UINT8 *) p;
+
+    if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE)
+        nfc_hal_nv_co_write (p, data_len,HC_DH_NV_BLOCK);
+
+    else if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
+    {
+        if (p[12] & 0x80)
+        {
+            /* HCI Network notification received for UICC 0, Update nv data */
+            nfc_hal_nv_co_write (p, data_len,HC_F3_NV_BLOCK);
+        }
+        else
+        {
+            NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[15]);
+            hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+            memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+            nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
+        }
+    }
+    else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
+    {
+        if (p[12] & 0x80)
+        {
+            /* HCI Network notification received for UICC 1, Update nv data */
+            nfc_hal_nv_co_write (p, data_len,HC_F4_NV_BLOCK);
+        }
+        else
+        {
+            NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[15]);
+            hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+            /* Reset Session ID */
+            memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+            nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hcp_pkt
+**
+** Description      Handle HCP Packet
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hcp_pkt (UINT8 *p_data)
+{
+    UINT8   chaining_bit;
+    UINT8   pipe;
+    UINT8   type;
+    UINT8   inst;
+    UINT8   hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+    UINT8   source_host;
+
+    chaining_bit = ((*p_data) >> 0x07) & 0x01;
+    pipe = (*p_data++) & 0x7F;
+
+    if (  (chaining_bit)
+        &&(pipe == NFC_HAL_HCI_ADMIN_PIPE)  )
+    {
+        type  = ((*p_data) >> 0x06) & 0x03;
+
+        if (type == NFC_HAL_HCI_COMMAND_TYPE)
+        {
+            inst  = (*p_data++ & 0x3F);
+
+            if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
+            {
+
+                STREAM_TO_UINT8 (source_host, p_data);
+
+                NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Received Clear All pipe command for UICC: 0x%02x", source_host);
+                if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
+                {
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+                    /* Reset Session ID */
+                    memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+                    nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
+                    NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Sent command to reset nv file for block: 0x%02x", HC_F3_NV_BLOCK);
+                }
+                else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
+                {
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+                    /* Reset Session ID */
+                    memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+                    nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
+                    NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Sent command to reset nv file for block: 0x%02x", HC_F4_NV_BLOCK);
+                }
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_nv_read
+**
+** Description      handler function for nv read complete event
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size)
+{
+    NFC_HDR *p_data = NULL;
+    UINT8   *p;
+    UINT8   *p_hci_netwk_info = NULL;
+
+    /* Stop timer as NVDATA Read Completed */
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+
+    switch (block)
+    {
+    case HC_F3_NV_BLOCK:
+    case HC_F4_NV_BLOCK:
+        if (  (status != HAL_NFC_STATUS_OK)
+            ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE)  )
+        {
+            NCI_TRACE_DEBUG0 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration!");
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+            nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = (block == HC_F3_NV_BLOCK) ? NFC_HAL_HCI_UICC0_TARGET_HANDLE : NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+            memset (&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+            size = NFC_HAL_HCI_NETWK_INFO_SIZE;
+        }
+
+        p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
+        break;
+
+    case HC_DH_NV_BLOCK:
+        if (  (status == HAL_NFC_STATUS_OK)
+            &&(size <= NFC_HAL_HCI_DH_NETWK_INFO_SIZE)  )
+        {
+            p_hci_netwk_info = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+        }
+        else
+        {
+            NCI_TRACE_ERROR0 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Skip DH Configuration!");
+        }
+        break;
+
+    default:
+        return;
+    }
+
+    if (p_hci_netwk_info)
+    {
+        p = p_hci_netwk_info;
+        /* Send HCI Network ntf command using nv data */
+        NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_PROP);
+        NCI_MSG_BLD_HDR1 (p, NCI_MSG_HCI_NETWK);
+        UINT8_TO_STREAM (p, (UINT8) size);
+
+        nfc_hal_dm_send_nci_cmd (p_hci_netwk_info, (UINT16) (NCI_MSG_HDR_SIZE + size), nfc_hal_hci_vsc_cback);
+
+        nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
+    }
+    else
+    {
+        /* Set next HCI Network configuration */
+        nfc_hal_hci_set_next_hci_netwk_config (block);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_init_complete
+**
+** Description      Notify VSC initialization is complete
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status)
+{
+    UINT8 *p_hci_netwk_cmd;
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
+    }
+
+    if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+    {
+        p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
+        GKI_freebuf (p_hci_netwk_cmd);
+        nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
+    }
+
+    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+    nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_set_next_hci_netwk_config
+**
+** Description      set next hci network configuration
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block)
+{
+    UINT8 *p_hci_netwk_cmd;
+
+    switch (block)
+    {
+    case HC_F3_NV_BLOCK:
+        /* Send command to read nvram data for 0xF4 */
+        memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+        nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F4_NV_BLOCK);
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+        break;
+
+    case HC_F4_NV_BLOCK:
+        if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
+        {
+            NCI_TRACE_ERROR0 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer for reading hci network info from nvram");
+            nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        }
+        else
+        {
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf   = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
+            /* Send command to read nvram data for 0xF2 */
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
+            nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, NFC_HAL_HCI_DH_NETWK_INFO_SIZE, HC_DH_NV_BLOCK);
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+        }
+        break;
+
+    case HC_DH_NV_BLOCK:
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+        break;
+
+    default:
+        NCI_TRACE_ERROR1 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to send VSC 0x%02x", block);
+        /* Brcm initialization failed */
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_vsc_cback
+**
+** Description      process VS callback event from stack
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    UINT8 *p_ret = NULL;
+    UINT8 status;
+
+    p_ret  = p_data + NCI_MSG_HDR_SIZE;
+    status = *p_ret;
+
+    if (event  != NFC_VS_HCI_NETWK_RSP)
+        return;
+
+    if (status != HAL_NFC_STATUS_OK)
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+
+    switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
+    {
+    case HC_F3_NV_BLOCK:
+    case HC_F4_NV_BLOCK:
+    case HC_DH_NV_BLOCK:
+        nfc_hal_hci_set_next_hci_netwk_config (nfc_hal_cb.hci_cb.hci_netwk_config_block);
+        break;
+
+    default:
+        /* Ignore the event */
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_cmd_timeout_cback
+**
+** Description      callback function for timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_hci_timeout_cback (void *p_tle)
+{
+    TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
+
+    if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
+    {
+        NCI_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+    }
+}
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
new file mode 100644
index 0000000..d9e999e
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the call-in functions for NFC HAL HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_read
+**
+** Description      call-in function for non volatile memory read acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_read (UINT16 num_bytes_read, tNFC_HAL_NV_CO_STATUS status, UINT8 block)
+{
+    tNFC_HAL_HCI_EVENT_DATA *p_msg;
+
+    /* Send message to NCIT task */
+    if ((p_msg = (tNFC_HAL_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFC_HAL_HCI_EVENT_DATA))) != NULL)
+    {
+        p_msg->nv_read.hdr.event  = NFC_HAL_HCI_RSP_NV_READ_EVT;
+        p_msg->hdr.offset         = 0;
+        p_msg->hdr.len            = sizeof (tNFC_HAL_HCI_RSP_NV_READ_EVT);
+        p_msg->hdr.layer_specific = 0;
+
+        if (  (status == NFC_HAL_NV_CO_OK)
+            &&(num_bytes_read != 0) )
+            p_msg->nv_read.status = HAL_NFC_STATUS_OK;
+        else
+            p_msg->nv_read.status = HAL_NFC_STATUS_FAILED;
+
+        p_msg->nv_read.size  = num_bytes_read;
+        p_msg->nv_read.block = block;
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_write
+**
+** Description      call-in function for non volatile memory write acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_write (tNFC_HAL_NV_CO_STATUS status)
+{
+    tNFC_HAL_HCI_EVENT_DATA *p_msg;
+
+    if ((p_msg = (tNFC_HAL_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFC_HAL_HCI_EVENT_DATA))) != NULL)
+    {
+        p_msg->nv_write.hdr.event          = NFC_HAL_HCI_RSP_NV_WRITE_EVT;
+        p_msg->nv_write.hdr.offset         = 0;
+        p_msg->nv_write.hdr.len            = sizeof (tNFC_HAL_HCI_RSP_NV_READ_EVT);
+        p_msg->nv_write.hdr.layer_specific = 0;
+        p_msg->nv_write.status             = HAL_NFC_STATUS_OK;
+
+        GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+    }
+}
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_main.c b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
new file mode 100644
index 0000000..82e696f
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
@@ -0,0 +1,596 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Functions for handling NFC HAL NCI Transport events
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "userial.h"
+#include "upio.h"
+
+/****************************************************************************
+** Definitions
+****************************************************************************/
+
+/* Default NFC HAL NCI port configuration  */
+NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg =
+{
+    NFC_HAL_SHARED_TRANSPORT_ENABLED,   /* bSharedTransport */
+    USERIAL_BAUD_115200,                /* Baud rate */
+    USERIAL_FC_HW                       /* Flow control */
+};
+
+/* Control block for NFC HAL NCI transport */
+#if NFC_DYNAMIC_MEMORY == FALSE
+tNFC_HAL_CB nfc_hal_cb;
+#endif
+
+/****************************************************************************
+** Internal function prototypes
+****************************************************************************/
+static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data);
+static void nfc_hal_main_handle_terminate (void);
+
+
+#if (NFC_HAL_DEBUG == TRUE)
+const char * const nfc_hal_init_state_str[] =
+{
+    "IDLE",             /* Initialization is done                */
+    "W4_XTAL_SET",      /* Waiting for crystal setting rsp       */
+    "W4_RESET",         /* Waiting for reset rsp                 */
+    "W4_BUILD_INFO",    /* Waiting for build info rsp            */
+    "W4_PATCH_INFO",    /* Waiting for patch info rsp            */
+    "W4_APP_COMPL",     /* Waiting for complete from application */
+    "W4_POST_INIT",     /* Waiting for complete of post init     */
+    "W4_CONTROL",       /* Waiting for control release           */
+    "W4_PREDISC",       /* Waiting for complete of prediscover   */
+    "W4_RE_INIT",       /* Waiting for reset rsp on ReInit       */
+    "CLOSING"           /* Shutting down                         */
+};
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_init
+**
+** Description      This function initializes control block for NFC HAL
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_hal_main_init (void)
+{
+    /* Clear control block */
+    memset (&nfc_hal_cb, 0, sizeof (tNFC_HAL_CB));
+
+    nfc_hal_cb.ncit_cb.nci_ctrl_size   = NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE;
+    nfc_hal_cb.trace_level             = NFC_HAL_INITIAL_TRACE_LEVEL;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_open_transport
+**
+** Description      Open transport and prepare for new incoming message;
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_open_transport (void)
+{
+    tUSERIAL_OPEN_CFG open_cfg;
+
+    /* Initialize control block */
+    nfc_hal_cb.ncit_cb.rcv_state = NFC_HAL_RCV_IDLE_ST; /* to process packet type */
+
+    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
+        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+    }
+
+    /* open transport */
+    open_cfg.fmt    = (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
+    open_cfg.baud   = nfc_hal_trans_cfg.userial_baud;
+    open_cfg.fc     = nfc_hal_trans_cfg.userial_fc;
+    open_cfg.buf    = USERIAL_BUF_BYTE;
+
+    USERIAL_Open (USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);
+
+    /* notify transport openned */
+    nfc_hal_dm_pre_init_nfcc ();
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_send_error
+**
+** Description      send an Error event to NFC stack
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_hal_main_send_error (tHAL_NFC_STATUS status)
+{
+    /* Notify stack */
+    nfc_hal_cb.p_stack_cback(HAL_NFC_ERROR_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_userial_cback
+**
+** Description      USERIAL callback for NCI transport
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data)
+{
+    if (evt == USERIAL_RX_READY_EVT)
+    {
+        /* Notify transport task of serial port event */
+        GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_DATA_RDY);
+    }
+    else if (evt == USERIAL_TX_DONE_EVT)
+    {
+        /* Serial driver has finshed sending data from USERIAL_Write */
+        /* Currently, no action is needed for this event */
+    }
+    else if (evt == USERIAL_ERR_EVT)
+    {
+        NCI_TRACE_ERROR0 ("nfc_hal_main_userial_cback: USERIAL_ERR_EVT. Notifying NFC_TASK of transport error");
+        if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+        {
+            nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+            nfc_hal_nci_cmd_timeout_cback ((void *)&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+        }
+        else
+        {
+            nfc_hal_main_send_error (HAL_NFC_STATUS_ERR_TRANSPORT);
+        }
+    }
+    else if (evt == USERIAL_WAKEUP_EVT)
+    {
+        NCI_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d", p_data->sigs);
+    }
+    else
+    {
+        NCI_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: unhandled userial evt: %i", evt);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_pre_init_done
+**
+** Description      notify complete of pre-initialization
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_hal_main_pre_init_done (tHAL_NFC_STATUS status)
+{
+    NCI_TRACE_DEBUG1 ("nfc_hal_main_pre_init_done () status = %d", status);
+
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        nfc_hal_main_handle_terminate ();
+
+        /* Close uart */
+        USERIAL_Close (USERIAL_NFC_PORT);
+    }
+
+    /* Notify NFC Task the status of initialization */
+    nfc_hal_cb.p_stack_cback (HAL_NFC_OPEN_CPLT_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_timeout_cback
+**
+** Description      callback function for timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_main_timeout_cback (void *p_tle)
+{
+    TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *) p_tle;
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_main_timeout_cback ()");
+
+    switch (p_tlent->event)
+    {
+    case NFC_HAL_TTYPE_POWER_CYCLE:
+        nfc_hal_main_open_transport ();
+        break;
+
+    default:
+        NCI_TRACE_DEBUG1 ("nfc_hal_main_timeout_cback: unhandled timer event (0x%04x)", p_tlent->event);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_handle_terminate
+**
+** Description      Handle NFI transport shutdown
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_handle_terminate (void)
+{
+    NFC_HDR *p_msg;
+
+    /* dequeue and free buffer */
+    if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_pend_cmd);
+        nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
+    }
+
+    /* Free unsent nfc rx buffer */
+    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
+        nfc_hal_cb.ncit_cb.p_rcv_msg  = NULL;
+    }
+
+    /* Free buffer for pending fragmented response/notification */
+    if (nfc_hal_cb.ncit_cb.p_frag_msg)
+    {
+        GKI_freebuf (nfc_hal_cb.ncit_cb.p_frag_msg);
+        nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
+    }
+
+    /* Free buffers in the tx mbox */
+    while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
+    {
+        GKI_freebuf (p_msg);
+    }
+
+    /* notify closing transport */
+    nfc_hal_dm_shutting_down_nfcc ();
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_start_quick_timer
+**
+** Description      Start a timer for the specified amount of time.
+**                  NOTE: The timeout resolution depends on including modules.
+**                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
+**                  time to ticks.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
+{
+    NFC_HDR *p_msg;
+
+    /* if timer list is currently empty, start periodic GKI timer */
+    if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+    {
+        /* if timer starts on other than NCIT task (script wrapper) */
+        if(GKI_get_taskid () != NFC_HAL_TASK)
+        {
+            /* post event to start timer in NCIT task */
+            if ((p_msg = (NFC_HDR *) GKI_getbuf (NFC_HDR_SIZE)) != NULL)
+            {
+                p_msg->event = NFC_HAL_EVT_TO_START_QUICK_TIMER;
+                GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+            }
+        }
+        else
+        {
+            GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+        }
+    }
+
+    GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+    p_tle->event = type;
+    p_tle->ticks = timeout; /* Save the number of ticks for the timer */
+
+    GKI_add_to_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_stop_quick_timer
+**
+** Description      Stop a timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle)
+{
+    GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_process_quick_timer_evt
+**
+** Description      Process quick timer event
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_main_process_quick_timer_evt (void)
+{
+    TIMER_LIST_ENT  *p_tle;
+
+    GKI_update_timer_list (&nfc_hal_cb.quick_timer_queue, 1);
+
+    while ((nfc_hal_cb.quick_timer_queue.p_first) && (!nfc_hal_cb.quick_timer_queue.p_first->ticks))
+    {
+        p_tle = nfc_hal_cb.quick_timer_queue.p_first;
+        GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+        if (p_tle->p_cback)
+        {
+            (*p_tle->p_cback) (p_tle);
+        }
+    }
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_send_message
+**
+** Description      This function is calledto send an NCI message.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_main_send_message (NFC_HDR *p_msg)
+{
+    UINT8   *ps;
+    UINT16  len = p_msg->len;
+#ifdef DISP_NCI
+    UINT8   delta;
+#endif
+
+    NCI_TRACE_DEBUG1 ("nfc_hal_main_send_message() ls:0x%x", p_msg->layer_specific);
+    if (  (p_msg->layer_specific == NFC_HAL_WAIT_RSP_CMD)
+        ||(p_msg->layer_specific == NFC_HAL_WAIT_RSP_VSC)  )
+    {
+        nfc_hal_nci_send_cmd (p_msg);
+    }
+    else
+    {
+        /* NFC task has fragmented the data packet to the appropriate size
+         * and data credit is available; just send it */
+
+        /* add NCI packet type in front of message */
+        nfc_hal_nci_add_nfc_pkt_type (p_msg);
+
+        /* send this packet to transport */
+        ps = (UINT8 *) (p_msg + 1) + p_msg->offset;
+#ifdef DISP_NCI
+        delta = p_msg->len - len;
+        DISP_NCI (ps + delta, (UINT16) (p_msg->len - delta), FALSE);
+#endif
+        USERIAL_Write (USERIAL_NFC_PORT, ps, p_msg->len);
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_main_task
+**
+** Description      NFC HAL NCI transport event processing task
+**
+** Returns          0
+**
+*******************************************************************************/
+UINT32 nfc_hal_main_task (UINT32 param)
+{
+    UINT16   event;
+    UINT8    byte;
+    UINT8    num_interfaces;
+    UINT8    *p;
+    NFC_HDR  *p_msg;
+    BOOLEAN  free_msg;
+
+    NCI_TRACE_DEBUG0 ("NFC_HAL_TASK started");
+
+    /* Main loop */
+    while (TRUE)
+    {
+        event = GKI_wait (0xFFFF, 0);
+
+        /* Handle NFC_HAL_TASK_EVT_INITIALIZE (for initializing NCI transport) */
+        if (event & NFC_HAL_TASK_EVT_INITIALIZE)
+        {
+            NCI_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_INITIALIZE signal. Opening NFC transport...");
+
+            nfc_hal_main_open_transport ();
+        }
+
+        /* Check for terminate event */
+        if (event & NFC_HAL_TASK_EVT_TERMINATE)
+        {
+            NCI_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
+            nfc_hal_main_handle_terminate ();
+
+            /* Close uart */
+            USERIAL_Close (USERIAL_NFC_PORT);
+
+            nfc_hal_cb.p_stack_cback (HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
+            nfc_hal_cb.p_stack_cback = NULL;
+            continue;
+        }
+
+        /* Check for power cycle event */
+        if (event & NFC_HAL_TASK_EVT_POWER_CYCLE)
+        {
+            NCI_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_POWER_CYCLE");
+            nfc_hal_main_handle_terminate ();
+
+            /* Close uart */
+            USERIAL_Close (USERIAL_NFC_PORT);
+
+            /* power cycle timeout */
+            nfc_hal_cb.timer.p_cback = nfc_hal_main_timeout_cback;
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_POWER_CYCLE,
+                                            (NFC_HAL_POWER_CYCLE_DELAY*QUICK_TIMER_TICKS_PER_SEC)/1000);
+            continue;
+        }
+
+        /* NCI message ready to be sent to NFCC */
+        if (event & NFC_HAL_TASK_EVT_MBOX)
+        {
+            while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
+            {
+                free_msg = TRUE;
+                switch (p_msg->event & NFC_EVT_MASK)
+                {
+                case NFC_HAL_EVT_TO_NFC_NCI:
+                    nfc_hal_main_send_message (p_msg);
+                    /* do not free buffer. NCI VS code may keep it for processing later */
+                    free_msg = FALSE;
+                    break;
+
+                case NFC_HAL_EVT_POST_CORE_RESET:
+                    NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_POST_INIT_DONE);
+
+                    /* set NCI Control packet size from CORE_INIT_RSP */
+                    p = (UINT8 *) (p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
+                    p += 5;
+                    STREAM_TO_UINT8 (num_interfaces, p);
+                    p += (num_interfaces + 3);
+                    nfc_hal_cb.ncit_cb.nci_ctrl_size = *p;
+
+                    /* start post initialization */
+                    nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_LPTD;
+                    nfc_hal_cb.dev_cb.next_startup_vsc = 1;
+
+                    nfc_hal_dm_config_nfcc ();
+                    break;
+
+                case NFC_HAL_EVT_TO_START_QUICK_TIMER:
+                    GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+                    break;
+
+                case NFC_HAL_EVT_HCI:
+                    nfc_hal_hci_evt_hdlr ((tNFC_HAL_HCI_EVENT_DATA *) p_msg);
+                    break;
+
+
+                case NFC_HAL_EVT_CONTROL_GRANTED:
+                    nfc_hal_dm_send_pend_cmd ();
+                    break;
+
+                default:
+                    break;
+                }
+
+                if (free_msg)
+                    GKI_freebuf (p_msg);
+            }
+        }
+
+        /* Data waiting to be read from serial port */
+        if (event & NFC_HAL_TASK_EVT_DATA_RDY)
+        {
+            while (TRUE)
+            {
+                /* Read one byte to see if there is anything waiting to be read */
+                if (USERIAL_Read (USERIAL_NFC_PORT, &byte, 1) == 0)
+                {
+                    break;
+                }
+
+                if (nfc_hal_nci_receive_msg (byte))
+                {
+                    /* complete of receiving NCI message */
+                    nfc_hal_nci_assemble_nci_msg ();
+                    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+                    {
+                        if (nfc_hal_nci_preproc_rx_nci_msg (nfc_hal_cb.ncit_cb.p_rcv_msg))
+                        {
+                            /* Send NCI message to the stack */
+                            nfc_hal_cb.p_data_cback(nfc_hal_cb.ncit_cb.p_rcv_msg->len, (UINT8 *)((nfc_hal_cb.ncit_cb.p_rcv_msg + 1)
+                                                             + nfc_hal_cb.ncit_cb.p_rcv_msg->offset));
+
+                        }
+                    }
+
+                    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+                    {
+                        GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
+                        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+                    }
+                }
+            } /* while (TRUE) */
+        }
+
+        /* Process quick timer tick */
+        if (event & NFC_HAL_QUICK_TIMER_EVT_MASK)
+        {
+            nfc_hal_main_process_quick_timer_evt ();
+        }
+    }
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_main_task terminated");
+
+    GKI_exit_task (GKI_get_taskid ());
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetTraceLevel
+**
+** Description      This function sets the trace level for HAL.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 HAL_NfcSetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        nfc_hal_cb.trace_level = new_level;
+
+    return (nfc_hal_cb.trace_level);
+}
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
new file mode 100644
index 0000000..977d7a4
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
@@ -0,0 +1,871 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains function of the NFC unit to receive/process NCI/VS
+ *  commands/responses.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "nci_defs.h"
+
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_assemble_nci_msg
+**
+** Description      This function is called to reassemble the received NCI
+**                  response/notification packet, if required.
+**                  (The data packets are posted to NFC task for reassembly)
+**
+** Returns          void.
+**
+*******************************************************************************/
+void nfc_hal_nci_assemble_nci_msg (void)
+{
+    NFC_HDR *p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg;
+    UINT8 u8;
+    UINT8 *p, *pp;
+    UINT8 hdr[2];
+    UINT8   *ps, *pd;
+    UINT16  size, needed;
+    BOOLEAN disp_again = FALSE;
+
+    if ((p_msg == NULL) || (p_msg->len < NCI_MSG_HDR_SIZE))
+        return;
+
+#ifdef DISP_NCI
+    DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
+#endif
+
+    p       = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    u8      = *p++;
+    /* remove the PBF bit for potential reassembly later */
+    hdr[0]  = u8 & ~NCI_PBF_MASK;
+    if ((u8 & NCI_MT_MASK) == NCI_MT_DATA)
+    {
+        /* clear the RFU in octet1 */
+        *(p) = 0;
+        /* data packet reassembly is performed in NFC task */
+        return;
+    }
+    else
+    {
+        *(p) &= NCI_OID_MASK;
+    }
+
+    hdr[1]  = *p;
+    pp = hdr;
+    /* save octet0 and octet1 of an NCI header in layer_specific for the received packet */
+    STREAM_TO_UINT16 (p_msg->layer_specific, pp);
+
+    if (nfc_hal_cb.ncit_cb.p_frag_msg)
+    {
+        if (nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific != p_msg->layer_specific)
+        {
+            /* check if these fragments are of the same NCI message */
+            NCI_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() - different messages 0x%x, 0x%x!!", nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific, p_msg->layer_specific);
+            nfc_hal_cb.ncit_cb.nci_ras  |= NFC_HAL_NCI_RAS_ERROR;
+        }
+        else if (nfc_hal_cb.ncit_cb.nci_ras == 0)
+        {
+            disp_again = TRUE;
+            /* if not previous reassembly error, append the new fragment */
+            p_msg->offset   += NCI_MSG_HDR_SIZE;
+            p_msg->len      -= NCI_MSG_HDR_SIZE;
+            size    = GKI_get_buf_size (nfc_hal_cb.ncit_cb.p_frag_msg);
+            needed  = (NFC_HDR_SIZE + nfc_hal_cb.ncit_cb.p_frag_msg->len + nfc_hal_cb.ncit_cb.p_frag_msg->offset + p_msg->len);
+            if (size >= needed)
+            {
+                /* the buffer for reassembly is big enough to append the new fragment */
+                ps   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+                pd   = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + nfc_hal_cb.ncit_cb.p_frag_msg->len;
+                memcpy (pd, ps, p_msg->len);
+                nfc_hal_cb.ncit_cb.p_frag_msg->len  += p_msg->len;
+                /* adjust the NCI packet length */
+                pd   = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + 2;
+                *pd  = (UINT8) (nfc_hal_cb.ncit_cb.p_frag_msg->len - NCI_MSG_HDR_SIZE);
+            }
+            else
+            {
+                nfc_hal_cb.ncit_cb.nci_ras  |= NFC_HAL_NCI_RAS_TOO_BIG;
+                NCI_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() buffer overrun (%d + %d)!!", nfc_hal_cb.ncit_cb.p_frag_msg->len, p_msg->len);
+            }
+        }
+        /* we are done with this new fragment, free it */
+        GKI_freebuf (p_msg);
+    }
+    else
+    {
+        nfc_hal_cb.ncit_cb.p_frag_msg = p_msg;
+    }
+
+
+    if ((u8 & NCI_PBF_MASK) == NCI_PBF_NO_OR_LAST)
+    {
+        /* last fragment */
+        p_msg               = nfc_hal_cb.ncit_cb.p_frag_msg;
+        p                   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        *p                  = u8; /* this should make the PBF flag as Last Fragment */
+        nfc_hal_cb.ncit_cb.p_frag_msg  = NULL;
+
+        p_msg->layer_specific = nfc_hal_cb.ncit_cb.nci_ras;
+        /* still report the data packet, if the incoming packet is too big */
+        if (nfc_hal_cb.ncit_cb.nci_ras & NFC_HAL_NCI_RAS_ERROR)
+        {
+            /* NFCC reported NCI fragments for different NCI messages and this is the last fragment - drop it */
+            NCI_TRACE_ERROR0 ("nfc_hal_nci_assemble_nci_msg() clearing NCI_RAS_ERROR");
+            GKI_freebuf (p_msg);
+            p_msg = NULL;
+        }
+#ifdef DISP_NCI
+        if ((nfc_hal_cb.ncit_cb.nci_ras == 0) && (disp_again))
+        {
+            DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
+        }
+#endif
+        /* clear the error flags, so the next NCI packet is clean */
+        nfc_hal_cb.ncit_cb.nci_ras = 0;
+    }
+    else
+    {
+        /* still reassembling */
+        p_msg = NULL;
+    }
+
+    nfc_hal_cb.ncit_cb.p_rcv_msg = p_msg;
+}
+
+/*****************************************************************************
+**
+** Function         nfc_hal_nci_receive_nci_msg
+**
+** Description
+**      Handle incoming data (NCI events) from the serial port.
+**
+**      If there is data waiting from the serial port, this funciton reads the
+**      data and parses it. Once an entire NCI message has been read, it sends
+**      the message the the NFC_TASK for processing
+**
+*****************************************************************************/
+static BOOLEAN nfc_hal_nci_receive_nci_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
+{
+    UINT16      len;
+    BOOLEAN     msg_received = FALSE;
+
+    switch (p_cb->rcv_state)
+    {
+    case NFC_HAL_RCV_NCI_MSG_ST:
+
+        /* Initialize rx parameters */
+        p_cb->rcv_state = NFC_HAL_RCV_NCI_HDR_ST;
+        p_cb->rcv_len   = NCI_MSG_HDR_SIZE;
+
+        /* Start of new message. Allocate a buffer for message */
+        if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+        {
+            /* Initialize NFC_HDR */
+            p_cb->p_rcv_msg->len    = 0;
+            p_cb->p_rcv_msg->event  = 0;
+            p_cb->p_rcv_msg->offset = 0;
+
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+        else
+        {
+            NCI_TRACE_ERROR0 ("Unable to allocate buffer for incoming NCI message.");
+        }
+        p_cb->rcv_len--;
+        break;
+
+    case NFC_HAL_RCV_NCI_HDR_ST:
+
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+
+        p_cb->rcv_len--;
+
+        /* Check if we read in entire NFC message header yet */
+        if (p_cb->rcv_len == 0)
+        {
+            p_cb->rcv_len       = byte;
+
+            /* If non-zero payload, then go to receive-data state */
+            if (byte > 0)
+            {
+                p_cb->rcv_state = NFC_HAL_RCV_NCI_PAYLOAD_ST;
+            }
+            else
+            {
+                msg_received    = TRUE;
+                p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
+            }
+        }
+        break;
+
+    case NFC_HAL_RCV_NCI_PAYLOAD_ST:
+
+        p_cb->rcv_len--;
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+
+            if (p_cb->rcv_len > 0)
+            {
+                /* Read in the rest of the message */
+                len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len),  p_cb->rcv_len);
+                p_cb->p_rcv_msg->len    += len;
+                p_cb->rcv_len           -= len;
+            }
+        }
+
+        /* Check if we read in entire message yet */
+        if (p_cb->rcv_len == 0)
+        {
+            msg_received    = TRUE;
+            p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
+        }
+        break;
+    }
+
+    return (msg_received);
+}
+
+/*****************************************************************************
+**
+** Function         nfc_hal_nci_receive_bt_msg
+**
+** Description
+**      Handle incoming BRCM specific data from the serial port.
+**
+**      If there is data waiting from the serial port, this funciton reads the
+**      data and parses it. Once an entire message has been read, it returns
+**      TRUE.
+**
+*****************************************************************************/
+static BOOLEAN nfc_hal_nci_receive_bt_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
+{
+    UINT16  len;
+    BOOLEAN msg_received = FALSE;
+
+    switch (p_cb->rcv_state)
+    {
+    case NFC_HAL_RCV_BT_MSG_ST:
+
+        /* Initialize rx parameters */
+        p_cb->rcv_state = NFC_HAL_RCV_BT_HDR_ST;
+        p_cb->rcv_len   = HCIE_PREAMBLE_SIZE;
+
+        if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+        {
+            /* Initialize NFC_HDR */
+            p_cb->p_rcv_msg->len    = 0;
+            p_cb->p_rcv_msg->event  = 0;
+            p_cb->p_rcv_msg->offset = 0;
+
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+        else
+        {
+            NCI_TRACE_ERROR0 ("[nfc] Unable to allocate buffer for incoming NCI message.");
+        }
+        p_cb->rcv_len--;
+        break;
+
+    case NFC_HAL_RCV_BT_HDR_ST:
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+        }
+        p_cb->rcv_len--;
+
+        /* Check if we received entire preamble yet */
+        if (p_cb->rcv_len == 0)
+        {
+            /* Received entire preamble. Length is in the last byte(s) of the preamble */
+            p_cb->rcv_len = byte;
+
+            /* Verify that buffer is big enough to fit message */
+            if ((sizeof (NFC_HDR) + HCIE_PREAMBLE_SIZE + byte) > GKI_get_buf_size (p_cb->p_rcv_msg))
+            {
+                /* Message cannot fit into buffer */
+                GKI_freebuf (p_cb->p_rcv_msg);
+                p_cb->p_rcv_msg     = NULL;
+
+                NCI_TRACE_ERROR0 ("Invalid length for incoming BT HCI message.");
+            }
+
+            /* Message length is valid */
+            if (byte)
+            {
+                /* Read rest of message */
+                p_cb->rcv_state = NFC_HAL_RCV_BT_PAYLOAD_ST;
+            }
+            else
+            {
+                /* Message has no additional parameters. (Entire message has been received) */
+                msg_received    = TRUE;
+                p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;  /* Next, wait for packet type of next message */
+            }
+        }
+        break;
+
+    case NFC_HAL_RCV_BT_PAYLOAD_ST:
+        p_cb->rcv_len--;
+        if (p_cb->p_rcv_msg)
+        {
+            *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+
+            if (p_cb->rcv_len > 0)
+            {
+                /* Read in the rest of the message */
+                len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len),  p_cb->rcv_len);
+                p_cb->p_rcv_msg->len    += len;
+                p_cb->rcv_len           -= len;
+            }
+        }
+
+        /* Check if we read in entire message yet */
+        if (p_cb->rcv_len == 0)
+        {
+            msg_received        = TRUE;
+            p_cb->rcv_state     = NFC_HAL_RCV_IDLE_ST;      /* Next, wait for packet type of next message */
+        }
+        break;
+    }
+
+    /* If we received entire message */
+    if (msg_received)
+    {
+        /* Display protocol trace message */
+#if (NFC_HAL_TRACE_PROTOCOL == TRUE)
+        DispHciEvt (p_cb->p_rcv_msg);
+#endif
+    }
+
+    return (msg_received);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_proc_rx_bt_msg
+**
+** Description      Received BT message from NFCC
+**
+**                  Notify command complete if initializing NFCC
+**                  Forward BT message to NFC task
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_nci_proc_rx_bt_msg (void)
+{
+    UINT8   *p;
+    NFC_HDR *p_msg;
+    UINT16  opcode, old_opcode;
+    tNFC_HAL_BTVSC_CPLT       vcs_cplt_params;
+    tNFC_HAL_BTVSC_CPLT_CBACK *p_cback = NULL;
+
+    /* if complete BT message is received successfully */
+    if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+    {
+        p_msg   = nfc_hal_cb.ncit_cb.p_rcv_msg;
+        NCI_TRACE_DEBUG1 ("nfc_hal_nci_proc_rx_bt_msg (): GOT an BT msgs init_sta:%d", nfc_hal_cb.dev_cb.initializing_state);
+        NCI_TRACE_DEBUG2 ("event: 0x%x, wait_rsp:0x%x", p_msg->event, nfc_hal_cb.ncit_cb.nci_wait_rsp);
+        /* increase the cmd window here */
+        if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
+        {
+            p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+            if (*p == HCI_COMMAND_COMPLETE_EVT)
+            {
+                p  += 3; /* code, len, cmd window */
+                STREAM_TO_UINT16 (opcode, p);
+                p   = nfc_hal_cb.ncit_cb.last_hdr;
+                STREAM_TO_UINT16 (old_opcode, p);
+                if (opcode == old_opcode)
+                {
+                    nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+                    p_cback = (tNFC_HAL_BTVSC_CPLT_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
+                    nfc_hal_cb.ncit_cb.p_vsc_cback  = NULL;
+                    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+                }
+            }
+        }
+
+        /* if initializing BRCM NFCC */
+        if ((nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) ||
+            (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE))
+        {
+            /* this is command complete event for baud rate update or download patch */
+            p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+            p += 1;    /* skip opcode */
+            STREAM_TO_UINT8  (vcs_cplt_params.param_len, p);
+
+            p += 1;    /* skip num command packets */
+            STREAM_TO_UINT16 (vcs_cplt_params.opcode, p);
+
+            vcs_cplt_params.param_len -= 3;
+            vcs_cplt_params.p_param_buf = p;
+
+            if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
+            {
+                NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+                nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK);
+            }
+            if (p_cback)
+            {
+                nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
+                (*p_cback) (&vcs_cplt_params);
+            }
+
+            /* do not BT send message to NFC task */
+            GKI_freebuf (p_msg);
+        }
+        else
+        {
+            /* do not BT send message to NFC task */
+            GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
+        }
+        nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+    }
+}
+
+/*****************************************************************************
+**
+** Function         nfc_hal_nci_receive_msg
+**
+** Description
+**      Handle incoming data (NCI events) from the serial port.
+**
+**      If there is data waiting from the serial port, this funciton reads the
+**      data and parses it. Once an entire NCI message has been read, it sends
+**      the message the the NFC_TASK for processing
+**
+*****************************************************************************/
+BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte)
+{
+    tNFC_HAL_NCIT_CB *p_cb = &(nfc_hal_cb.ncit_cb);
+    BOOLEAN msg_received = FALSE;
+
+    if (p_cb->rcv_state == NFC_HAL_RCV_IDLE_ST)
+    {
+        /* if this is NCI message */
+        if (byte == HCIT_TYPE_NFC)
+        {
+            p_cb->rcv_state = NFC_HAL_RCV_NCI_MSG_ST;
+        }
+        /* if this is BT message */
+        else if (byte == HCIT_TYPE_EVENT)
+        {
+            p_cb->rcv_state = NFC_HAL_RCV_BT_MSG_ST;
+        }
+        else
+        {
+            NCI_TRACE_ERROR1 ("Unknown packet type drop this byte 0x%x", byte);
+        }
+    }
+    else if (p_cb->rcv_state <= NFC_HAL_RCV_NCI_PAYLOAD_ST)
+    {
+        msg_received = nfc_hal_nci_receive_nci_msg (p_cb, byte);
+    }
+    else
+    {
+        if (nfc_hal_nci_receive_bt_msg (p_cb, byte))
+        {
+            /* received BT message */
+            nfc_hal_nci_proc_rx_bt_msg ();
+        }
+    }
+
+    return (msg_received);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_preproc_rx_nci_msg
+**
+** Description      NFCC sends NCI message to DH while initializing NFCC
+**                  processing low power mode
+**
+** Returns          TRUE, if NFC task need to receive NCI message
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg)
+{
+    UINT8 *p, *pp, cid;
+    UINT8 mt, pbf, gid, op_code;
+    UINT8 payload_len;
+    UINT16 data_len;
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_nci_preproc_rx_nci_msg()");
+
+    /* if initializing BRCM NFCC */
+    if (nfc_hal_cb.dev_cb.initializing_state != NFC_HAL_INIT_STATE_IDLE)
+    {
+        nfc_hal_dm_proc_msg_during_init (p_msg);
+        /* do not send message to NFC task while initializing NFCC */
+        return (FALSE);
+    }
+    else
+    {
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        pp = p;
+        NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+        NCI_MSG_PRS_HDR1 (p, op_code);
+        payload_len = *p++;
+
+        if (mt == NCI_MT_DATA)
+        {
+            if (nfc_hal_cb.hci_cb.b_check_clear_all_pipe_cmd)
+            {
+                NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
+                if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
+                {
+                    nfc_hal_hci_handle_hcp_pkt (pp);
+                }
+
+            }
+        }
+
+        if (gid == NCI_GID_PROP) /* this is for hci netwk ntf */
+        {
+            if (mt == NCI_MT_NTF)
+            {
+                if (op_code == NCI_MSG_HCI_NETWK)
+                {
+                    nfc_hal_hci_handle_hci_netwk_info ((UINT8 *) (p_msg + 1) + p_msg->offset);
+                }
+            }
+        }
+        else if (gid == NCI_GID_RF_MANAGE)
+        {
+            if (mt == NCI_MT_NTF)
+            {
+                if (op_code == NCI_MSG_RF_INTF_ACTIVATED)
+                {
+                    if ((nfc_hal_cb.max_rf_credits) && (payload_len > 5))
+                    {
+                        /* API used wants to limit the RF data credits */
+                        p += 5; /* skip RF disc id, interface, protocol, tech&mode, payload size */
+                        if (*p > nfc_hal_cb.max_rf_credits)
+                        {
+                            NCI_TRACE_DEBUG2 ("RfDataCredits %d->%d", *p, nfc_hal_cb.max_rf_credits);
+                            *p = nfc_hal_cb.max_rf_credits;
+                        }
+                    }
+                }
+            }
+        }
+        else if (gid == NCI_GID_CORE)
+        {
+            if (mt == NCI_MT_RSP)
+            {
+                if (op_code == NCI_MSG_CORE_CONN_CREATE)
+                {
+                    if (nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp)
+                    {
+                        p++; /* skip status byte */
+                        nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
+                        p++; /* skip buff size */
+                        p++; /* num of buffers */
+                        nfc_hal_cb.hci_cb.hcp_conn_id = *p;
+                        nfc_hal_cb.hci_cb.b_check_clear_all_pipe_cmd = TRUE;
+                    }
+                }
+            }
+        }
+    }
+
+    if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+    {
+        if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+        {
+            /* extend idle timer */
+            nfc_hal_dm_power_mode_execute (NFC_HAL_LP_RX_DATA_EVT);
+        }
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_add_nfc_pkt_type
+**
+** Description      Add packet type (HCIT_TYPE_NFC)
+**
+** Returns          TRUE, if NFCC can receive NCI message
+**
+*******************************************************************************/
+void nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg)
+{
+    UINT8   *p;
+    BOOLEAN send_to_nfcc = TRUE;
+    UINT8   hcit;
+
+    /* add packet type in front of NCI header */
+    if (p_msg->offset > 0)
+    {
+        p_msg->offset--;
+        p_msg->len++;
+
+        p  = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        *p = HCIT_TYPE_NFC;
+    }
+    else
+    {
+        NCI_TRACE_ERROR0 ("nfc_hal_nci_add_nfc_pkt_type () : No space for packet type");
+        hcit = HCIT_TYPE_NFC;
+        USERIAL_Write (USERIAL_NFC_PORT, &hcit, 1);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nci_brcm_check_cmd_create_hcp_connection
+**
+** Description      Check if this is command to create HCP connection
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nci_brcm_check_cmd_create_hcp_connection (NFC_HDR *p_msg)
+{
+    UINT8 *p;
+    UINT8 mt, pbf, gid, op_code;
+
+    nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
+    {
+        NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+        NCI_MSG_PRS_HDR1 (p, op_code);
+
+        if (gid == NCI_GID_CORE)
+        {
+            if (mt == NCI_MT_CMD)
+            {
+                if (op_code == NCI_MSG_CORE_CONN_CREATE)
+                {
+                    if (  ((NCI_CORE_PARAM_SIZE_CON_CREATE + 4) == *p++)
+                        &&(NCI_DEST_TYPE_NFCEE == *p++)
+                        &&(1 == *p++)
+                        &&(NCI_CON_CREATE_TAG_NFCEE_VAL == *p++)
+                        &&(2 == *p++)  )
+                    {
+                        p++;
+                        if (NCI_NFCEE_INTERFACE_HCI_ACCESS == *p)
+                        {
+                            nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = TRUE;
+                            return;
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_send_cmd
+**
+** Description      Send NCI command to the transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nci_send_cmd (NFC_HDR *p_buf)
+{
+    BOOLEAN continue_to_process = TRUE;
+    UINT8   *ps, *pd;
+    UINT16  max_len;
+    UINT16  buf_len, offset;
+    UINT8   *p;
+    UINT8   hdr[NCI_MSG_HDR_SIZE];
+    UINT8   nci_ctrl_size = nfc_hal_cb.ncit_cb.nci_ctrl_size;
+    UINT8   delta = 0;
+
+    nci_brcm_check_cmd_create_hcp_connection ((NFC_HDR*) p_buf);
+
+    /* check low power mode state */
+    continue_to_process = nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT);
+
+    if (!continue_to_process)
+    {
+        /* save the command to be sent until NFCC is free. */
+        nfc_hal_cb.ncit_cb.p_pend_cmd   = p_buf;
+        return;
+    }
+
+    max_len = nci_ctrl_size + NCI_MSG_HDR_SIZE;
+    buf_len = p_buf->len;
+    offset  = p_buf->offset;
+#ifdef DISP_NCI
+    if (buf_len > max_len)
+    {
+        /* this command needs to be fragmented. display the complete packet first */
+        DISP_NCI ((UINT8 *) (p_buf + 1) + p_buf->offset, p_buf->len, FALSE);
+    }
+#endif
+    ps      = (UINT8 *) (p_buf + 1) + p_buf->offset;
+    memcpy (hdr, ps, NCI_MSG_HDR_SIZE);
+    while (buf_len > max_len)
+    {
+        NCI_TRACE_DEBUG2 ("buf_len (%d) > max_len (%d)", buf_len, max_len);
+        /* the NCI command is bigger than the NFCC Max Control Packet Payload Length
+         * fragment the command */
+
+        p_buf->len  = max_len;
+        ps   = (UINT8 *) (p_buf + 1) + p_buf->offset;
+        /* mark the control packet as fragmented */
+        *ps |= NCI_PBF_ST_CONT;
+        /* adjust the length of this fragment */
+        ps  += 2;
+        *ps  = nci_ctrl_size;
+
+        /* add NCI packet type in front of message */
+        nfc_hal_nci_add_nfc_pkt_type (p_buf);
+
+        /* send this fragment to transport */
+        p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+#ifdef DISP_NCI
+        delta = p_buf->len - max_len;
+        DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
+#endif
+        USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+        /* adjust the len and offset to reflect that part of the command is already sent */
+        buf_len -= nci_ctrl_size;
+        offset  += nci_ctrl_size;
+        NCI_TRACE_DEBUG2 ("p_buf->len: %d buf_len (%d)", p_buf->len, buf_len);
+        p_buf->len      = buf_len;
+        p_buf->offset   = offset;
+        pd   = (UINT8 *) (p_buf + 1) + p_buf->offset;
+        /* restore the NCI header */
+        memcpy (pd, hdr, NCI_MSG_HDR_SIZE);
+        pd  += 2;
+        *pd  = (UINT8) (p_buf->len - NCI_MSG_HDR_SIZE);
+    }
+
+    NCI_TRACE_DEBUG1 ("p_buf->len: %d", p_buf->len);
+
+    /* add NCI packet type in front of message */
+    nfc_hal_nci_add_nfc_pkt_type (p_buf);
+
+    /* send this fragment to transport */
+    p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+#ifdef DISP_NCI
+    delta = p_buf->len - buf_len;
+    DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
+#endif
+    USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+    GKI_freebuf (p_buf);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nci_cmd_timeout_cback
+**
+** Description      callback function for timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nci_cmd_timeout_cback (void *p_tle)
+{
+    TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
+
+    NCI_TRACE_DEBUG0 ("nfc_hal_nci_cmd_timeout_cback ()");
+
+    nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+
+    if (p_tlent->event == NFC_HAL_TTYPE_NCI_WAIT_RSP)
+    {
+        if (nfc_hal_cb.dev_cb.initializing_state <= NFC_HAL_INIT_STATE_W4_PATCH_INFO)
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+        {
+            if (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_IDLE)
+            {
+                nfc_hal_prm_process_timeout (NULL);
+            }
+            else
+            {
+                NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+                nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+            }
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_POST_INIT_DONE)
+        {
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
+        {
+            NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+        else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE)
+        {
+            NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+            nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetMaxRfDataCredits
+**
+** Description      This function sets the maximum RF data credit for HAL.
+**                  If 0, use the value reported from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits)
+{
+    NCI_TRACE_DEBUG2 ("HAL_NfcSetMaxRfDataCredits %d->%d", nfc_hal_cb.max_rf_credits, max_credits);
+    nfc_hal_cb.max_rf_credits   = max_credits;
+}
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
new file mode 100644
index 0000000..7fa9236
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
@@ -0,0 +1,1119 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "userial.h"
+
+/*****************************************************************************
+* Definitions
+*****************************************************************************/
+
+/* Internal flags */
+#define NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF  0x01    /* Application provided patchram in a single buffer */
+#define NFC_HAL_PRM_FLAGS_RFU               0x02    /* Reserved for future use */
+#define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT    0x04    /* Signature sent to NFCC */
+#define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED  0x08    /* PreI2C patch required */
+#define NFC_HAL_PRM_FLAGS_NO_NVM            0x10    /* Not NVM available (patch downloaded to SRAM) */
+#define NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF 0x20    /* Support RESET_NTF from NFCC after sending signature */
+#define NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED 0x40    /* FPM patch in NVM failed CRC check */
+#define NFC_HAL_PRM_FLAGS_NVM_LPM_CORRUPTED 0x80    /* LPM patch in NVM failed CRC check */
+
+/* Secure patch download definitions */
+#define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN  7       /* PRJID + MAJORVER + MINORVER + COUNT */
+#define NFC_HAL_PRM_NCD_PATCH_VERSION_LEN  16
+
+#define NFC_HAL_PRM_SPD_PRE_DOWNLOAD_DELAY (500)   /* Delay before starting to patch download (in ms) */
+
+/* Enumeration of power modes IDs */
+#define NFC_HAL_PRM_SPD_POWER_MODE_LPM     0
+#define NFC_HAL_PRM_SPD_POWER_MODE_FPM     1
+
+/* Version string for BCM20791B3 */
+const UINT8 NFC_HAL_PRM_BCM20791B3_STR[]   = "20791B3";
+#define NFC_HAL_PRM_BCM20791B3_STR_LEN     (sizeof (NFC_HAL_PRM_BCM20791B3_STR)-1)
+
+#define NFC_HAL_PRM_SPD_TOUT                   (6000)  /* timeout for SPD events (in ms)   */
+#define NFC_HAL_PRM_END_DELAY                  (250)   /* delay before sending any new command (ms)*/
+
+/* command to get currently downloaded patch version */
+static UINT8 nfc_hal_prm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+{
+    NCI_MTS_CMD|NCI_GID_PROP,
+    NCI_MSG_GET_PATCH_VERSION,
+    0x00
+};
+
+#if (NFC_HAL_PRM_DEBUG == TRUE)
+#define NFC_HAL_PRM_STATE(str)  NCI_TRACE_DEBUG2 ("%s st: %d", str, nfc_hal_cb.prm.state)
+#else
+#define NFC_HAL_PRM_STATE(str)
+#endif
+
+void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status);
+
+/*****************************************************************************
+** Extern variable from nfc_hal_dm_cfg.c
+*****************************************************************************/
+extern BOOLEAN nfc_hal_prm_nvm_required;
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_handle_download_complete
+**
+** Description      Patch download complete (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_handle_download_complete (UINT8 event)
+{
+    nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_IDLE;
+
+    /* Notify application now */
+    if (nfc_hal_cb.prm.p_cback)
+        (nfc_hal_cb.prm.p_cback) (event);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_send_next_segment
+**
+** Description      Send next patch segment (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_send_next_segment (void)
+{
+    UINT8   *p_src;
+    UINT16  len, offset = nfc_hal_cb.prm.cur_patch_offset;
+    UINT8   hcit, oid, hdr0, type;
+    UINT8   chipverlen;
+    UINT8   chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
+    UINT8   patch_hdr_size = NCI_MSG_HDR_SIZE + 1; /* 1 is for HCIT */
+
+    /* Validate that segment is at least big enought to have NCI_MSG_HDR_SIZE + 1 (hcit) */
+    if (nfc_hal_cb.prm.cur_patch_len_remaining < patch_hdr_size)
+    {
+        NCI_TRACE_ERROR0 ("Unexpected end of patch.");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+        return;
+    }
+
+    /* Parse NCI command header */
+    p_src = (UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset);
+    STREAM_TO_UINT8 (hcit, p_src);
+    STREAM_TO_UINT8 (hdr0, p_src);
+    STREAM_TO_UINT8 (oid,  p_src);
+    STREAM_TO_UINT8 (len,  p_src);
+    STREAM_TO_UINT8 (type, p_src);
+
+
+    /* Update number of bytes comsumed */
+    nfc_hal_cb.prm.cur_patch_offset += (len + patch_hdr_size);
+    nfc_hal_cb.prm.cur_patch_len_remaining -=  (len + patch_hdr_size);
+
+    /* Check if sending signature byte */
+    if (  (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
+        &&(type == NCI_SPD_TYPE_SIGNATURE)  )
+    {
+        nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+    }
+    /* Check for header */
+    else if (  (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
+             &&(type == NCI_SPD_TYPE_HEADER)  )
+    {
+        /* Check if patch is for BCM20791B3 */
+        p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN;
+        STREAM_TO_UINT8 (chipverlen, p_src);
+        STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN);
+
+        if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0)
+        {
+            /* Patch is for BCM2079B3 - do not wait for RESET_NTF after patch download */
+            nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF;
+        }
+        else
+        {
+            /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF;
+        }
+    }
+
+    /* Send the command (not including HCIT here) */
+    nfc_hal_dm_send_nci_cmd ((UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset + 1), (UINT8) (len + NCI_MSG_HDR_SIZE),
+                             nfc_hal_prm_nci_command_complete_cback);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_handle_next_patch_start
+**
+** Description      Handle start of next patch (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_handle_next_patch_start (void)
+{
+    UINT32  cur_patch_mask;
+    UINT32  cur_patch_len;
+    BOOLEAN found_patch_to_download = FALSE;
+
+    while (!found_patch_to_download)
+    {
+        /* Get length of current patch */
+        cur_patch_len = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
+
+        /* Check if this is a patch we need to download */
+        cur_patch_mask = ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+        if (nfc_hal_cb.prm.spd_patch_needed_mask & cur_patch_mask)
+        {
+            found_patch_to_download = TRUE;
+        }
+        else
+        {
+            /* Do not need to download this patch. Skip to next patch */
+            NCI_TRACE_DEBUG1 ("Skipping patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+
+            nfc_hal_cb.prm.spd_cur_patch_idx++;
+            if (nfc_hal_cb.prm.spd_cur_patch_idx >= nfc_hal_cb.prm.spd_patch_count)
+            {
+                /* No more to download */
+                nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+                return;
+            }
+            else if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+            {
+                /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch header */
+                (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+                return;
+            }
+            else
+            {
+                /* Patch in buffer. Skip over current patch. Check next patch */
+                nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) cur_patch_len;
+                nfc_hal_cb.prm.cur_patch_offset += (UINT16) cur_patch_len;
+            }
+        }
+    }
+
+
+    /* Begin downloading patch */
+    NCI_TRACE_DEBUG1 ("Downloading patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+    nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_DOWNLOADING;
+    nfc_hal_prm_spd_send_next_segment ();
+}
+
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_download_i2c_fix
+**
+** Description      Start downloading patch for i2c fix
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_download_i2c_fix (void)
+{
+    UINT8 *p, *p_start;
+    UINT16 patchfile_project_id;
+    UINT16 patchfile_ver_major;
+    UINT16 patchfile_ver_minor;
+    UINT16 patchfile_patchsize;
+    UINT8 u8;
+
+    NCI_TRACE_DEBUG0 ("Downloading I2C fix...");
+
+    /* Save pointer and offset of patchfile, so we can resume after downloading the i2c fix */
+    nfc_hal_cb.prm.spd_patch_offset = nfc_hal_cb.prm.cur_patch_offset;
+    nfc_hal_cb.prm.spd_patch_len_remaining = nfc_hal_cb.prm.cur_patch_len_remaining;
+
+    /* Initialize pointers for downloading i2c fix */
+    nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm_i2c.p_patch;
+    nfc_hal_cb.prm.cur_patch_offset = 0;
+    nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm_i2c.len;
+
+    /* Parse the i2c patchfile */
+    if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
+    {
+        /* Parse patchfile header */
+        p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
+        p_start = p;
+        STREAM_TO_UINT16 (patchfile_project_id, p);
+        STREAM_TO_UINT16 (patchfile_ver_major, p);
+        STREAM_TO_UINT16 (patchfile_ver_minor, p);
+
+        /* RFU */
+        p++;
+
+        /* Check how many patches are in the patch file */
+        STREAM_TO_UINT8 (u8, p);
+
+        /* Should only be one patch */
+        if (u8 > 1)
+        {
+            NCI_TRACE_ERROR1 ("Invalid i2c fix: invalid number of patches (%i)", u8);
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
+
+
+        /* Get info about the i2c patch*/
+        STREAM_TO_UINT8 (u8, p);                     /* power mode (not needed for i2c patch)    */
+        STREAM_TO_UINT16 (patchfile_patchsize, p);   /* size of patch                            */
+
+        /* 5 byte RFU */
+        p += 5;
+
+        /* Adjust length to exclude patchfiloe header */
+        nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
+        nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start);              /* Bytes of patchfile transmitted/processed so far */
+
+        /* Begin sending patch to the NFCC */
+        nfc_hal_prm_spd_send_next_segment ();
+    }
+    else
+    {
+        /* ERROR: Bad length for patchfile */
+        NCI_TRACE_ERROR0 ("Invalid i2c fix: unexpected end of patch");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+    }
+}
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_check_version
+**
+** Description      Check patchfile version with current downloaded version
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_check_version (void)
+{
+    UINT8 *p, *p_start, i;
+    UINT32 patchfile_patch_present_mask;
+    UINT16 patchfile_project_id;
+    UINT16 patchfile_ver_major = 0;
+    UINT16 patchfile_ver_minor;
+    UINT16 patchfile_patchsize;
+
+    UINT8  return_code = NFC_HAL_PRM_COMPLETE_EVT;
+
+    /* Initialize patchfile offset pointers */
+    p = p_start = NULL;
+    patchfile_patchsize = 0;
+
+    /* Get patchfile version */
+    if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
+    {
+        /* Parse patchfile header */
+        p       = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
+        p_start = p;
+        STREAM_TO_UINT16 (patchfile_project_id, p);
+        STREAM_TO_UINT16 (patchfile_ver_major, p);
+        STREAM_TO_UINT16 (patchfile_ver_minor, p);
+
+        /* RFU */
+        p++;
+
+        /* Check how many patches are in the patch file */
+        STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_count, p);
+
+        if (nfc_hal_cb.prm.spd_patch_count > NFC_HAL_PRM_MAX_PATCH_COUNT)
+        {
+            NCI_TRACE_ERROR2 ("Unsupported patchfile (number of patches (%i) exceeds maximum (%i)",
+                               nfc_hal_cb.prm.spd_patch_count, NFC_HAL_PRM_MAX_PATCH_COUNT);
+        }
+
+        /* Mask of patches that are present in the patchfile */
+        patchfile_patch_present_mask = 0;
+
+        /* Get lengths for each patch */
+        for (i = 0; i < nfc_hal_cb.prm.spd_patch_count; i++)
+        {
+            /* Get power mode for this patch */
+            STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_desc[i].power_mode, p);
+
+            /* Update mask of power-modes present in the patchfile */
+            patchfile_patch_present_mask |= ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[i].power_mode);
+
+            /* Get length of patch */
+            STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_desc[i].len, p);
+
+            /* Add total size of patches */
+            patchfile_patchsize += nfc_hal_cb.prm.spd_patch_desc[i].len;
+
+            /* 5 byte RFU */
+            p += 5;
+        }
+
+        /* Adjust offset to after the patch file header */
+        nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start);              /* Bytes of patchfile transmitted/processed so far */
+        nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start);       /* Adjust size of patchfile                        */
+
+
+        NCI_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x,  Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i",
+                           patchfile_project_id, patchfile_ver_major, patchfile_ver_minor,
+                           nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize);
+
+        /*********************************************************************
+        * Version check of patchfile against NVM
+        *********************************************************************/
+
+#if (!defined (NFC_HAL_PRM_SKIP_VERSION_CHECK) || (NFC_HAL_PRM_SKIP_VERSION_CHECK == FALSE))
+        /* Download the patchfile if no patches in NVM */
+        if ((nfc_hal_cb.prm.spd_project_id == 0) || (nfc_hal_cb.prm.spd_nvm_patch_mask == 0))
+        {
+            /* No patch in NVM, need to download all */
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+            NCI_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
+                              patchfile_ver_major, patchfile_ver_minor);
+        }
+        /* Skip download if project ID of patchfile does not match NVM */
+        else if (nfc_hal_cb.prm.spd_project_id != patchfile_project_id)
+        {
+            /* Project IDs mismatch */
+            NCI_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
+                              nfc_hal_cb.prm.spd_project_id, patchfile_project_id);
+
+            return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+        }
+        /* Skip download if version of patchfile older or equal to version in NVM */
+        /* unless NVM is corrupted (then don't skip download if patchfile has the same major ver)*/
+        else if (  (nfc_hal_cb.prm.spd_ver_major > patchfile_ver_major)
+                 ||(  (nfc_hal_cb.prm.spd_ver_major == patchfile_ver_major) && (nfc_hal_cb.prm.spd_ver_minor == patchfile_ver_minor)
+                    && !((patchfile_patch_present_mask & ( 1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM)) && (nfc_hal_cb.prm.spd_lpm_patch_size == 0))  /* Do not skip download: patchfile has LPM, but NVM does not */
+                    && !((patchfile_patch_present_mask & ( 1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM)) && (nfc_hal_cb.prm.spd_fpm_patch_size == 0))  /* Do not skip download: patchfile has FPM, but NVM does not */
+                    && !(nfc_hal_cb.prm.flags & (NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED |NFC_HAL_PRM_FLAGS_NVM_LPM_CORRUPTED))  )  )
+        {
+            /* NVM version is newer than patchfile */
+            NCI_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is newer than the patchfile ",
+                              nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
+
+            return_code = NFC_HAL_PRM_COMPLETE_EVT;
+        }
+        /* Remaining cases: patchfile major version is newer than NVM; or major version is the same with different minor version */
+        /* Download all patches in the patchfile */
+        else
+        {
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+            NCI_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                              patchfile_ver_major, patchfile_ver_minor,
+                              nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
+        }
+#else   /* NFC_HAL_PRM_SKIP_VERSION_CHECK */
+        nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+#endif
+    }
+    else
+    {
+        /* Invalid patch file header */
+        NCI_TRACE_ERROR0 ("Invalid patch file header.");
+
+        return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+    }
+
+    /* If we need to download anything, get the first patch to download */
+    if (nfc_hal_cb.prm.spd_patch_needed_mask)
+    {
+        NCI_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                            patchfile_ver_major, patchfile_ver_minor,
+                            nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+        /* Check if I2C patch is needed: if                                     */
+        /*      - I2C patch file was provided using HAL_NfcPrmSetI2cPatch, and        */
+        /*      -   current patch in NVM has ProjectID=0, or                    */
+        /*          FPM is not present or corrupted, or                         */
+        /*          or patchfile is major-ver 76+                               */
+        if (  (nfc_hal_cb.prm_i2c.p_patch)
+            &&(  (nfc_hal_cb.prm.spd_project_id == 0)
+               ||(nfc_hal_cb.prm.spd_fpm_patch_size == 0)
+               ||(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED)
+               ||(patchfile_ver_major >= 76)))
+        {
+            NCI_TRACE_DEBUG0 ("I2C patch fix required.");
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+
+            /* Download i2c fix first */
+            nfc_hal_prm_spd_download_i2c_fix ();
+            return;
+        }
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+        /* Download first segment */
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+        if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+        {
+            /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+        }
+        else
+        {
+            nfc_hal_prm_spd_handle_next_patch_start ();
+        }
+    }
+    else
+    {
+        static BOOLEAN firstTime = TRUE;
+        if (firstTime) {
+            NCI_TRACE_ERROR2 ("BCM2079x: NVM patch version is %d.%d",
+                    nfc_hal_cb.prm.spd_ver_major, nfc_hal_cb.prm.spd_ver_minor);
+            firstTime = FALSE;
+        }
+        /* Download complete */
+        nfc_hal_prm_spd_handle_download_complete (return_code);
+    }
+}
+
+#if (NFC_HAL_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_status_str
+**
+** Description      Return status string for a given spd status code
+**
+** Returns          Status string
+**
+*******************************************************************************/
+UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code)
+{
+    char *p_str;
+
+    switch (spd_status_code)
+    {
+    case NCI_STATUS_SPD_ERROR_DEST:
+        p_str = "SPD_ERROR_DEST";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_PROJECTID:
+        p_str = "SPD_ERROR_PROJECTID";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_CHIPVER:
+        p_str = "SPD_ERROR_CHIPVER";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_MAJORVER:
+        p_str = "SPD_ERROR_MAJORVER";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_INVALID_PARAM:
+        p_str = "SPD_ERROR_INVALID_PARAM";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_INVALID_SIG:
+        p_str = "SPD_ERROR_INVALID_SIG";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_NVM_CORRUPTED:
+        p_str = "SPD_ERROR_NVM_CORRUPTED";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_PWR_MODE:
+        p_str = "SPD_ERROR_PWR_MODE";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_MSG_LEN:
+        p_str = "SPD_ERROR_MSG_LEN";
+        break;
+
+    case NCI_STATUS_SPD_ERROR_PATCHSIZE:
+        p_str = "SPD_ERROR_PATCHSIZE";
+        break;
+
+    default:
+        p_str = "Unspecified Error";
+        break;
+
+    }
+
+    return ((UINT8*) p_str);
+}
+#endif  /* (NFC_HAL_TRACE_VERBOSE == TRUE) */
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_nci_command_complete_cback
+**
+** Description      Callback for NCI vendor specific command complete
+**                  (for secure patch download)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    UINT8 status, u8;
+    UINT8 *p;
+    UINT32 post_signature_delay;
+
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_nci_command_complete_cback");
+
+    /* Stop the command-timeout timer */
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+
+    /* Skip over NCI header */
+    p = p_data + NCI_MSG_HDR_SIZE;
+
+    /* Handle GET_PATCH_VERSION Rsp */
+    if (event == NFC_VS_GET_PATCH_VERSION_EVT)
+    {
+        /* Get project id */
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_project_id, p);
+
+        /* RFU */
+        p++;
+
+        /* Get chip version string */
+        STREAM_TO_UINT8 (u8, p);
+        p += NFC_HAL_PRM_NCD_PATCH_VERSION_LEN;
+
+        /* Get major/minor version */
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_ver_major, p);
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_ver_minor, p);
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_nvm_max_size, p);
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_max_size, p);
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_lpm_patch_size, p);
+        STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_fpm_patch_size, p);
+
+        /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+        STREAM_TO_UINT8 (u8, p);
+        if (!u8)
+        {
+            nfc_hal_cb.prm.spd_nvm_patch_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
+        }
+        else
+        {
+            /* LPM patch in NVM fails CRC check */
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_NVM_LPM_CORRUPTED;
+        }
+
+
+        /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+        STREAM_TO_UINT8 (u8, p);
+        if (!u8)
+        {
+            nfc_hal_cb.prm.spd_nvm_patch_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
+        }
+        else
+        {
+            /* FPM patch in NVM fails CRC check */
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_NVM_FPM_CORRUPTED;
+        }
+
+        /* Check if downloading patch to RAM only (no NVM) */
+        STREAM_TO_UINT8 (u8, p);
+        if (!u8)
+        {
+            if (nfc_hal_prm_nvm_required)
+            {
+                NCI_TRACE_ERROR0 ("This platform requires NVM and the NVM is not available - Abort");
+                nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_NO_NVM_EVT);
+                return;
+            }
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_NO_NVM;
+        }
+        /* Get patchfile version number */
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_COMPARE_VERSION;
+
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+        {
+            /* If patch is in a buffer, get patch version from buffer */
+            nfc_hal_prm_spd_check_version ();
+        }
+        else
+        {
+            /* Notify adaptation layer to send patch version (via HAL_NfcPrmDownloadContinue) */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT);
+        }
+
+    }
+    /* Handle SECURE_PATCH_DOWNLOAD Rsp */
+    else if (event == NFC_VS_SEC_PATCH_DOWNLOAD_EVT)
+    {
+        /* Status and error code */
+        STREAM_TO_UINT8 (status, p);
+        STREAM_TO_UINT8 (u8, p);
+
+        if (status != NCI_STATUS_OK)
+        {
+#if (NFC_HAL_TRACE_VERBOSE == TRUE)
+            NCI_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status));
+#else
+            NCI_TRACE_ERROR1 ("Patch download failed, reason code=0x%X", status);
+#endif
+
+            /* Notify application */
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
+
+        /* If last segment (SIGNATURE) sent */
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SIGNATURE_SENT)
+        {
+            /* Wait for authentication complate (SECURE_PATCH_DOWNLOAD NTF) */
+            nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTHENTICATING;
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+                                            (NFC_HAL_PRM_SPD_TOUT * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+            return;
+        }
+        /* Download next segment */
+        else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+        {
+            /* If patch is in a buffer, get next patch from buffer */
+            nfc_hal_prm_spd_send_next_segment ();
+        }
+        else
+        {
+            /* Notify adaptation layer to get next patch segment (via HAL_NfcPrmDownloadContinue) */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_CONTINUE_EVT);
+        }
+    }
+    /* Handle SECURE_PATCH_DOWNLOAD NTF */
+    else if (event == NFC_VS_SEC_PATCH_AUTH_EVT)
+    {
+        NCI_TRACE_DEBUG1 ("prm flags:0x%x.", nfc_hal_cb.prm.flags);
+        /* Status and error code */
+        STREAM_TO_UINT8 (status, p);
+        STREAM_TO_UINT8 (u8, p);
+
+        /* Sanity check - should only get this NTF while in AUTHENTICATING stage */
+        if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTHENTICATING)
+        {
+            if (status != NCI_STATUS_OK)
+            {
+                NCI_TRACE_ERROR0 ("Patch authentication failed");
+                nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT);
+                return;
+            }
+
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+            if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
+            {
+                NCI_TRACE_DEBUG1 ("PreI2C patch downloaded...waiting %i ms for NFCC to reboot.", nfc_hal_cb.prm_i2c.prei2c_delay);
+
+                /* Restore pointers to patchfile */
+                nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+                nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm.p_spd_patch;
+                nfc_hal_cb.prm.cur_patch_offset = nfc_hal_cb.prm.spd_patch_offset;
+                nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm.spd_patch_len_remaining;
+
+                /* Resume normal patch download */
+                nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+                nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+
+                /* Post PreI2C delay */
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, (nfc_hal_cb.prm_i2c.prei2c_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+                return;
+            }
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+
+            /* Wait for NFCC to save the patch to NVM */
+            if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF)
+            {
+                /* 20791B4 or newer - wait for RESET_NTF */
+                post_signature_delay = NFC_HAL_PRM_RESET_NTF_DELAY;
+                NCI_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay);
+
+            }
+            else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_NO_NVM)
+            {
+                /* No NVM. Wait for NFCC to restart */
+                post_signature_delay = NFC_HAL_PRM_END_DELAY;
+                NCI_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NFCC to restart...", post_signature_delay);
+            }
+            else
+            {
+                /* Wait for NFCC to save the patch to NVM (need about 1 ms per byte) */
+                post_signature_delay = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
+                if (post_signature_delay < nfc_hal_cb.prm.patchram_delay)
+                    post_signature_delay = nfc_hal_cb.prm.patchram_delay;
+                NCI_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NVM update to complete...", post_signature_delay);
+            }
+
+            nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTH_DONE;
+
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+                                            (post_signature_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        }
+        else
+        {
+            NCI_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+    }
+    else
+    {
+        /* Invalid response from NFCC during patch download */
+        NCI_TRACE_ERROR1 ("Invalid response from NFCC during patch download (opcode=0x%02X)", event);
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+    }
+
+    NFC_HAL_PRM_STATE ("prm_nci_command_complete_cback");
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_nfcc_ready_to_continue
+**
+** Description      Continue to download patch or notify application completition
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_nfcc_ready_to_continue (void)
+{
+    /* Clear the bit for the patch we just downloaded */
+    nfc_hal_cb.prm.spd_patch_needed_mask &= ~ ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+
+    /* Check if another patch to download */
+    nfc_hal_cb.prm.spd_cur_patch_idx++;
+    if ((nfc_hal_cb.prm.spd_patch_needed_mask) && (nfc_hal_cb.prm.spd_cur_patch_idx < nfc_hal_cb.prm.spd_patch_count))
+    {
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+        nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+        {
+            /* If patch is in a buffer, get next patch from buffer */
+            nfc_hal_prm_spd_handle_next_patch_start ();
+        }
+        else
+        {
+            /* Notify adaptation layer to get next patch header (via HAL_NfcPrmDownloadContinue) */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+        }
+
+    }
+    else
+    {
+        /* Done downloading */
+        NCI_TRACE_DEBUG0 ("Patch downloaded and authenticated.");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_spd_reset_ntf
+**
+** Description      Received RESET NTF from NFCC, indicating it has completed
+**                  reset after patch download.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type)
+{
+    /* Check if we were expecting a RESET NTF */
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+    {
+        NCI_TRACE_DEBUG2 ("Received RESET NTF after patch download (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
+
+        /* Stop waiting for RESET NTF */
+        nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+
+        {
+        /* Continue with patch download */
+        nfc_hal_prm_nfcc_ready_to_continue ();
+    }
+    }
+    else
+    {
+        NCI_TRACE_ERROR2 ("Received unexpected RESET NTF (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    nfc_post_final_baud_update
+**
+** Description: Called after baud rate udate
+**
+** Returns:     Nothing
+**
+*******************************************************************************/
+void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status)
+{
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_post_baud_update");
+
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+    {
+        /* Proceed with next step of patch download sequence */
+        nfc_hal_prm_nfcc_ready_to_continue ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_prm_process_timeout
+**
+** Description      Process timer expireation for patch download
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_prm_process_timeout (void *p_tle)
+{
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
+
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_IDLE)
+    {
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_VERSION;
+
+        /* Get currently downloaded patch version */
+        nfc_hal_dm_send_nci_cmd (nfc_hal_prm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback);
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+    {
+        if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SUPPORT_RESET_NTF)
+        {
+            /* Timeout waiting for RESET NTF after signature sent */
+            NCI_TRACE_ERROR0 ("Timeout waiting for RESET NTF after patch download");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+        else
+        {
+            nfc_hal_prm_nfcc_ready_to_continue ();
+        }
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+    {
+        NCI_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch");
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else
+    {
+        NCI_TRACE_ERROR1 ("Patch download: command timeout (state=%i)", nfc_hal_cb.prm.state);
+
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+    }
+
+    NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
+}
+
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadStart
+**
+** Description      Initiate patch download
+**
+** Input Params
+**                  format_type     patch format type
+**                                  (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
+**                                   NFC_HAL_PRM_FORMAT_NCD)
+**
+**                  dest_address    destination adderess (needed for BIN format only)
+**
+**                  p_patchram_buf  pointer to patchram buffer. If NULL,
+**                                  then app must call HAL_NfcPrmDownloadContinue when
+**                                  NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
+**                                  segment of patchram
+**
+**                  patchram_len    size of p_patchram_buf (if non-NULL)
+**
+**                  patchram_delay  The delay after each patch.
+**                                  If the given value is less than the size of the patchram,
+**                                  the size of patchram is used instead.
+**
+**                  p_cback         callback for download status
+**
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
+                                 UINT32              dest_address,
+                                 UINT8               *p_patchram_buf,
+                                 UINT32              patchram_len,
+                                 UINT32              patchram_delay,
+                                 tNFC_HAL_PRM_CBACK  *p_cback)
+{
+    NCI_TRACE_API0 ("HAL_NfcPrmDownloadStart ()");
+
+    memset (&nfc_hal_cb.prm, 0, sizeof (tNFC_HAL_PRM_CB));
+
+    if (p_patchram_buf)
+    {
+        nfc_hal_cb.prm.p_cur_patch_data = p_patchram_buf;
+        nfc_hal_cb.prm.cur_patch_offset = 0;
+        nfc_hal_cb.prm.cur_patch_len_remaining = (UINT16) patchram_len;
+        nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF;
+
+        if (patchram_len == 0)
+            return FALSE;
+    }
+
+    nfc_hal_cb.prm.p_cback          = p_cback;
+    nfc_hal_cb.prm.dest_ram         = dest_address;
+    nfc_hal_cb.prm.format           = format_type;
+    nfc_hal_cb.prm.patchram_delay   = patchram_delay;
+
+    nfc_hal_cb.prm.timer.p_cback = nfc_hal_prm_process_timeout;
+
+    if (format_type == NFC_HAL_PRM_FORMAT_NCD)
+    {
+        /* Store patch buffer pointer and length */
+        nfc_hal_cb.prm.p_spd_patch             = p_patchram_buf;
+        nfc_hal_cb.prm.spd_patch_len_remaining = (UINT16)patchram_len;
+        nfc_hal_cb.prm.spd_patch_offset        = 0;
+
+        /* Need delay for controller to finish resetting */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+                                        (NFC_HAL_PRM_SPD_PRE_DOWNLOAD_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+    }
+    else
+    {
+        NCI_TRACE_ERROR0 ("Unexpected patch format.");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadContinue
+**
+** Description      Send next segment of patchram to controller. Called when
+**                  NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+**                  Only needed if HAL_NfcPrmDownloadStart was called with
+**                  p_patchram_buf=NULL
+**
+** Input Params     p_patch_data    pointer to patch data
+**                  patch_data_len  patch data len
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
+                                    UINT16 patch_data_len)
+{
+    NCI_TRACE_API2 ("HAL_NfcPrmDownloadContinue ():state = %d, patch_data_len=%d",
+                     nfc_hal_cb.prm.state, patch_data_len);
+
+    /* Check if we are in a valid state for this API */
+    if (  (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
+        &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+        &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_DOWNLOADING)  )
+        return FALSE;
+
+    if (patch_data_len == 0)
+        return FALSE;
+
+    nfc_hal_cb.prm.cur_patch_offset = 0;
+    nfc_hal_cb.prm.p_cur_patch_data = p_patch_data;
+    nfc_hal_cb.prm.cur_patch_len_remaining = patch_data_len;
+
+    /* Call appropriate handler */
+    if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
+    {
+        nfc_hal_prm_spd_check_version ();
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+    {
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_DOWNLOADING)
+    {
+        nfc_hal_prm_spd_send_next_segment ();
+    }
+    else
+    {
+        NCI_TRACE_ERROR1 ("Unexpected patch state:%d.", nfc_hal_cb.prm.state);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetI2cPatch
+**
+** Description      Specify patchfile for BCM20791B3 I2C fix. This fix
+**                  must be downloaded prior to initial patch download for I2C
+**                  transport
+**
+** Input Params     p_i2c_patchfile_buf: pointer to patch for i2c fix
+**                  i2c_patchfile_len: length of patch
+**                  prei2c_delay: the delay before downloading main patch
+**                                if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
+**
+** Returns          Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf, UINT16 i2c_patchfile_len, UINT32 prei2c_delay)
+{
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+    NCI_TRACE_API0 ("HAL_NfcPrmSetI2cPatch ()");
+
+    nfc_hal_cb.prm_i2c.prei2c_delay    = NFC_HAL_PRM_POST_I2C_FIX_DELAY;
+    if (prei2c_delay)
+        nfc_hal_cb.prm_i2c.prei2c_delay = prei2c_delay;
+    nfc_hal_cb.prm_i2c.p_patch = p_i2c_patchfile_buf;
+    nfc_hal_cb.prm_i2c.len = i2c_patchfile_len;
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description      Set Host-to-NFCC NCI message size for secure patch download
+**
+**                  This API must be called before calling HAL_NfcPrmDownloadStart.
+**                  If the API is not called, then PRM will use the default
+**                  message size.
+**
+**                  Typically, this API is only called for platforms that have
+**                  message-size limitations in the transport/driver.
+**
+**                  Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns          HAL_NFC_STATUS_OK if successful
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size)
+{
+    /* Validate: minimum size is NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE */
+    if (max_payload_size < NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE)
+    {
+        NCI_TRACE_ERROR2 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: invalid size (%i). Must be between %i and 255", max_payload_size, NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE);
+        return (HAL_NFC_STATUS_FAILED);
+    }
+    else
+    {
+        NCI_TRACE_API1 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: new message size during download: %i", max_payload_size);
+        nfc_hal_cb.ncit_cb.nci_ctrl_size = max_payload_size;
+        return (HAL_NFC_STATUS_OK);
+    }
+}
diff --git a/halimpl/bcm2079x/hal/include/gki_hal_target.h b/halimpl/bcm2079x/hal/include/gki_hal_target.h
new file mode 100644
index 0000000..9a9aec9
--- /dev/null
+++ b/halimpl/bcm2079x/hal/include/gki_hal_target.h
@@ -0,0 +1,255 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 GKI_HAL_TARGET_H
+#define GKI_HAL_TARGET_H
+
+#ifdef BUILDCFG
+#include "buildcfg_hal.h"
+#endif
+
+#include "data_types.h"
+
+/* Define export prefixes for modules exported by HAL */
+#ifndef GKI_API
+#define GKI_API
+#endif
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API
+#endif
+
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef NFC_HAL_TASK
+#define NFC_HAL_TASK                0
+#endif
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS               1
+#endif
+
+/******************************************************************************
+**
+** Timer configuration
+**
+******************************************************************************/
+
+/* The number of GKI timers in the software system. */
+#ifndef GKI_NUM_TIMERS
+#define GKI_NUM_TIMERS              2
+#endif
+
+/* A conversion value for translating ticks to calculate GKI timer.  */
+#ifndef TICKS_PER_SEC
+#define TICKS_PER_SEC               100
+#endif
+
+/************************************************************************
+**  Utility macros converting ticks to time with user define OS ticks per sec
+**/
+#ifndef GKI_MS_TO_TICKS
+#define GKI_MS_TO_TICKS(x)   ((x) / (1000 / TICKS_PER_SEC))
+#endif
+
+#ifndef GKI_SECS_TO_TICKS
+#define GKI_SECS_TO_TICKS(x)   ((x) * (TICKS_PER_SEC))
+#endif
+
+#ifndef GKI_TICKS_TO_MS
+#define GKI_TICKS_TO_MS(x)   ((x) * 1000 / TICKS_PER_SEC)
+#endif
+
+#ifndef GKI_TICKS_TO_SECS
+#define GKI_TICKS_TO_SECS(x)   ((x) / TICKS_PER_SEC)
+#endif
+
+
+
+/* TICK per second from OS (OS dependent change this macro accordingly to various OS) */
+#ifndef OS_TICKS_PER_SEC
+#define OS_TICKS_PER_SEC               1000
+#endif
+
+/************************************************************************
+**  Utility macros converting ticks to time with user define OS ticks per sec
+**/
+
+#ifndef GKI_OS_TICKS_TO_MS
+#define GKI_OS_TICKS_TO_MS(x)   ((x) * 1000 / OS_TICKS_PER_SEC)
+#endif
+
+
+#ifndef GKI_OS_TICKS_TO_SECS
+#define GKI_OS_TICKS_TO_SECS(x)   ((x) / OS_TICKS_PER_SEC))
+#endif
+
+
+/* delay in ticks before stopping system tick. */
+#ifndef GKI_DELAY_STOP_SYS_TICK
+#define GKI_DELAY_STOP_SYS_TICK     10
+#endif
+
+/* Option to guarantee no preemption during timer expiration (most system don't need this) */
+#ifndef GKI_TIMER_LIST_NOPREEMPT
+#define GKI_TIMER_LIST_NOPREEMPT    FALSE
+#endif
+
+/******************************************************************************
+**
+** Buffer configuration
+**
+******************************************************************************/
+
+/* TRUE if GKI uses dynamic buffers. */
+#ifndef GKI_USE_DYNAMIC_BUFFERS
+#define GKI_USE_DYNAMIC_BUFFERS     FALSE
+#endif
+
+/* The size of the buffers in pool 0. */
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE               64
+#endif
+
+/* The number of buffers in buffer pool 0. */
+#ifndef GKI_BUF0_MAX
+#define GKI_BUF0_MAX                8
+#endif
+
+/* The ID of buffer pool 0. */
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0               0
+#endif
+
+/* The size of the buffers in pool 1. */
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE               288
+#endif
+
+/* The number of buffers in buffer pool 1. */
+#ifndef GKI_BUF1_MAX
+#define GKI_BUF1_MAX                8
+#endif
+
+/* The ID of buffer pool 1. */
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1               1
+#endif
+
+/* The size of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE
+#define GKI_MAX_BUF_SIZE            GKI_BUF1_SIZE
+#endif
+
+/* The pool ID of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE_POOL_ID
+#define GKI_MAX_BUF_SIZE_POOL_ID    GKI_POOL_ID_1
+#endif
+
+/* buffer size for USERIAL, it must large enough to hold NFC_HDR and max packet size */
+#ifndef USERIAL_POOL_BUF_SIZE
+#define USERIAL_POOL_BUF_SIZE       GKI_BUF1_SIZE
+#endif
+
+/* buffer pool ID for USERIAL */
+#ifndef USERIAL_POOL_ID
+#define USERIAL_POOL_ID             GKI_POOL_ID_1
+#endif
+
+#ifndef GKI_NUM_FIXED_BUF_POOLS
+#define GKI_NUM_FIXED_BUF_POOLS     2
+#endif
+
+/* The number of fixed and dynamic buffer pools */
+#ifndef GKI_NUM_TOTAL_BUF_POOLS
+#define GKI_NUM_TOTAL_BUF_POOLS     2
+#endif
+
+/* The buffer pool usage mask. */
+#ifndef GKI_DEF_BUFPOOL_PERM_MASK
+#define GKI_DEF_BUFPOOL_PERM_MASK   0xfff0
+#endif
+
+/* The buffer corruption check flag. */
+#ifndef GKI_ENABLE_BUF_CORRUPTION_CHECK
+#define GKI_ENABLE_BUF_CORRUPTION_CHECK TRUE
+#endif
+
+/* The GKI severe error macro. */
+#ifndef GKI_SEVERE
+#define GKI_SEVERE(code)
+#endif
+
+/* TRUE if GKI includes debug functionality. */
+#ifndef GKI_DEBUG
+#define GKI_DEBUG                   FALSE
+#endif
+
+/* Maximum number of exceptions logged. */
+#ifndef GKI_MAX_EXCEPTION
+#define GKI_MAX_EXCEPTION           8
+#endif
+
+/* Maximum number of chars stored for each exception message. */
+#ifndef GKI_MAX_EXCEPTION_MSGLEN
+#define GKI_MAX_EXCEPTION_MSGLEN    64
+#endif
+
+#ifndef GKI_SEND_MSG_FROM_ISR
+#define GKI_SEND_MSG_FROM_ISR    FALSE
+#endif
+
+
+#define GKI_TRACE_0(m)
+#define GKI_TRACE_1(m,p1)
+#define GKI_TRACE_2(m,p1,p2)
+#define GKI_TRACE_3(m,p1,p2,p3)
+#define GKI_TRACE_4(m,p1,p2,p3,p4)
+#define GKI_TRACE_5(m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define GKI_TRACE_ERROR_0(m)                    LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m)
+#define GKI_TRACE_ERROR_1(m,p1)                 LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1)
+#define GKI_TRACE_ERROR_2(m,p1,p2)              LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2)
+#define GKI_TRACE_ERROR_3(m,p1,p2,p3)           LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3)
+#define GKI_TRACE_ERROR_4(m,p1,p2,p3,p4)        LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4)
+#define GKI_TRACE_ERROR_5(m,p1,p2,p3,p4,p5)     LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_ERROR_6(m,p1,p2,p3,p4,p5,p6)  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* GKI_TARGET_H */
diff --git a/halimpl/bcm2079x/hal/include/nci_defs.h b/halimpl/bcm2079x/hal/include/nci_defs.h
new file mode 100644
index 0000000..befffd9
--- /dev/null
+++ b/halimpl/bcm2079x/hal/include/nci_defs.h
@@ -0,0 +1,851 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the definition from NCI specification
+ *
+ ******************************************************************************/
+
+#ifndef NFC_NCI_DEFS_H
+#define NFC_NCI_DEFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NCI_BRCM_CO_ID              0x2E
+
+/* Define the message header size for all NCI Commands and Notifications.
+*/
+#define NCI_MSG_HDR_SIZE        3   /* per NCI spec */
+#define NCI_DATA_HDR_SIZE       3   /* per NCI spec */
+#define NCI_MAX_PAYLOAD_SIZE    0xFE
+#define NCI_MAX_CTRL_SIZE       0xFF/* max control message size */
+#define NCI_CTRL_INIT_SIZE      32  /* initial NFCC control payload size */
+#define NCI_MAX_VSC_SIZE        0xFF
+#define NCI_VSC_MSG_HDR_SIZE    12  /* NCI header (3) + callback function pointer(8; use 8 to be safe) + HCIT (1 byte) */
+#define NCI_TL_SIZE             2
+
+#define NCI_ISO_DEP_MAX_INFO      253   /* Max frame size (256) - Prologue (1) - Epilogue (2) in ISO-DEP, CID and NAD are not used*/
+#define NCI_NFC_DEP_MAX_DATA      251   /* Max payload (254) - Protocol Header (3) in NFC-DEP, DID and NAD are not used */
+
+/* NCI Command and Notification Format:
+ * 3 byte message header:
+ * byte 0: MT PBF GID
+ * byte 1: OID
+ * byte 2: Message Length */
+/* MT: Message Type (byte 0) */
+#define NCI_MT_MASK         0xE0
+#define NCI_MT_SHIFT        5
+#define NCI_MT_DATA         0x00
+#define NCI_MT_CMD          1   /* (NCI_MT_CMD << NCI_MT_SHIFT) = 0x20 */
+#define NCI_MT_RSP          2   /* (NCI_MT_RSP << NCI_MT_SHIFT) = 0x40 */
+#define NCI_MT_NTF          3   /* (NCI_MT_NTF << NCI_MT_SHIFT) = 0x60 */
+#define NCI_MT_CFG          4   /* (NCI_MT_CFG << NCI_MT_SHIFT) = 0x80 */
+
+#define NCI_MTS_CMD         0x20
+#define NCI_MTS_RSP         0x40
+#define NCI_MTS_NTF         0x60
+#define NCI_MTS_CFG         0x80
+
+#define NCI_NTF_BIT         0x80     /* the tNFC_VS_EVT is a notification */
+#define NCI_RSP_BIT         0x40     /* the tNFC_VS_EVT is a response     */
+
+/* for internal use only; not from specification */
+/* the following 2 flags are used in layer_specific for fragmentation/reassembly of data packets */
+#define NCI_LS_DATA         0x00
+#define NCI_LS_DATA_PBF     0x01
+
+/* PBF: Packet Boundary Flag (byte 0) */
+#define NCI_PBF_MASK        0x10
+#define NCI_PBF_SHIFT       4
+#define NCI_PBF_NO_OR_LAST  0x00    /* not fragmented or last fragment */
+#define NCI_PBF_ST_CONT     0x10    /* start or continuing fragment */
+
+/* GID: Group Identifier (byte 0) */
+#define NCI_GID_MASK        0x0F
+#define NCI_GID_SHIFT       0
+#define NCI_GID_CORE        0x00    /* 0000b NCI Core group */
+#define NCI_GID_RF_MANAGE   0x01    /* 0001b RF Management group */
+#define NCI_GID_EE_MANAGE   0x02    /* 0010b NFCEE Management group */
+#define NCI_GID_PROP        0x0F    /* 1111b Proprietary */
+/* 0111b - 1110b RFU */
+
+/* OID: Opcode Identifier (byte 1) */
+#define NCI_OID_MASK        0x3F
+#define NCI_OID_SHIFT       0
+
+/* For routing */
+#define NCI_DH_ID               0   /* for DH */
+/* To identify the loopback test */
+#define NCI_TEST_ID             0xFE/* for loopback test */
+
+/* Destination Type */
+#define NCI_DEST_TYPE_NFCC      1   /* NFCC - loopback */
+#define NCI_DEST_TYPE_REMOTE    2   /* Remote NFC Endpoint */
+#define NCI_DEST_TYPE_NFCEE     3   /* NFCEE */
+
+/* builds byte0 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR0(p, mt, gid) \
+    *(p)++ = (UINT8) (((mt) << NCI_MT_SHIFT) | (gid));
+
+#define NCI_MSG_PBLD_HDR0(p, mt, pbf, gid) \
+    *(p)++ = (UINT8) (((mt) << NCI_MT_SHIFT) | ((pbf) << NCI_PBF_SHIFT) | (gid));
+
+/* builds byte1 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR1(p, oid) \
+    *(p)++ = (UINT8) (((oid) << NCI_OID_SHIFT));
+
+/* parse byte0 of NCI packet */
+#define NCI_MSG_PRS_HDR0(p, mt, pbf, gid) \
+    mt = (*(p) & NCI_MT_MASK) >> NCI_MT_SHIFT; \
+    pbf = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT; \
+    gid = *(p)++ & NCI_GID_MASK;
+
+/* parse MT and PBF bits of NCI packet */
+#define NCI_MSG_PRS_MT_PBF(p, mt, pbf) \
+    mt = (*(p) & NCI_MT_MASK) >> NCI_MT_SHIFT; \
+    pbf = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT;
+
+/* parse byte1 of NCI Cmd/Ntf */
+#define NCI_MSG_PRS_HDR1(p, oid) \
+    oid = (*(p) & NCI_OID_MASK); (p)++;
+
+/* NCI Data Format:
+ * byte 0: MT(0) PBF CID
+ * byte 1: RFU
+ * byte 2: Data Length */
+/* CID: Connection Identifier (byte 0) 1-0xF Dynamically assigned (by NFCC), 0 is predefined  */
+#define NCI_CID_MASK        0x0F
+
+/* builds 3-byte message header of NCI Data packet */
+#define NCI_DATA_BLD_HDR(p, cid, len) \
+    *(p)++ = (UINT8) (cid); *(p)++ = 0; *(p)++ = (UINT8) (len);
+
+#define NCI_DATA_PBLD_HDR(p, pbf, cid, len) \
+    *(p)++ = (UINT8) (((pbf) << NCI_PBF_SHIFT) | (cid)); *(p)++=0; *(p)++ = (len);
+
+#define NCI_DATA_PRS_HDR(p, pbf, cid, len) \
+    (pbf) = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT; (cid) = (*(p) & NCI_CID_MASK); p++; p++; (len) = *(p)++;
+
+
+/* Logical target ID 0x01-0xFE */
+
+
+
+/* Status Codes */
+#define NCI_STATUS_OK                   0x00
+#define NCI_STATUS_REJECTED             0x01
+#define NCI_STATUS_MESSAGE_CORRUPTED    0x02
+#define NCI_STATUS_BUFFER_FULL          0xE0
+#define NCI_STATUS_FAILED               0x03
+#define NCI_STATUS_NOT_INITIALIZED      0x04
+#define NCI_STATUS_SYNTAX_ERROR         0x05
+#define NCI_STATUS_SEMANTIC_ERROR       0x06
+#define NCI_STATUS_UNKNOWN_GID          0x07
+#define NCI_STATUS_UNKNOWN_OID          0x08
+#define NCI_STATUS_INVALID_PARAM        0x09
+#define NCI_STATUS_MSG_SIZE_TOO_BIG     0x0A
+/* discovery */
+#define NCI_STATUS_ALREADY_STARTED      0xA0
+#define NCI_STATUS_ACTIVATION_FAILED    0xA1
+#define NCI_STATUS_TEAR_DOWN            0xA2
+/* RF Interface */
+#define NCI_STATUS_RF_TRANSMISSION_ERR  0xB0
+#define NCI_STATUS_RF_PROTOCOL_ERR      0xB1
+#define NCI_STATUS_TIMEOUT              0xB2
+/* NFCEE Interface */
+#define NCI_STATUS_EE_INTF_ACTIVE_FAIL  0xC0
+#define NCI_STATUS_EE_TRANSMISSION_ERR  0xC1
+#define NCI_STATUS_EE_PROTOCOL_ERR      0xC2
+#define NCI_STATUS_EE_TIMEOUT           0xC3
+
+
+typedef UINT8 tNCI_STATUS;
+
+/* RF Technologies */
+#define NCI_RF_TECHNOLOGY_A             0x00
+#define NCI_RF_TECHNOLOGY_B             0x01
+#define NCI_RF_TECHNOLOGY_F             0x02
+#define NCI_RF_TECHNOLOGY_15693         0x03
+
+/* Bit Rates */
+#define NCI_BIT_RATE_106                0x00/* 106 kbit/s */
+#define NCI_BIT_RATE_212                0x01/* 212 kbit/s */
+#define NCI_BIT_RATE_424                0x02/* 424 kbit/s */
+#define NCI_BIT_RATE_848                0x03/* 848 Kbit/s */
+#define NCI_BIT_RATE_1696               0x04/* 1696 Kbit/s*/
+#define NCI_BIT_RATE_3392               0x05/* 3392 Kbit/s*/
+#define NCI_BIT_RATE_6784               0x06/* 6784 Kbit/s*/
+
+/**********************************************
+ * NCI Core Group Opcode        - 0
+ **********************************************/
+#define NCI_MSG_CORE_RESET              0
+#define NCI_MSG_CORE_INIT               1
+#define NCI_MSG_CORE_SET_CONFIG         2
+#define NCI_MSG_CORE_GET_CONFIG         3
+#define NCI_MSG_CORE_CONN_CREATE        4
+#define NCI_MSG_CORE_CONN_CLOSE         5
+#define NCI_MSG_CORE_CONN_CREDITS       6
+#define NCI_MSG_CORE_GEN_ERR_STATUS     7
+#define NCI_MSG_CORE_INTF_ERR_STATUS    8
+
+/**********************************************
+ * RF MANAGEMENT Group Opcode    - 1
+ **********************************************/
+#define NCI_MSG_RF_DISCOVER_MAP         0
+#define NCI_MSG_RF_SET_ROUTING          1
+#define NCI_MSG_RF_GET_ROUTING          2
+#define NCI_MSG_RF_DISCOVER             3
+#define NCI_MSG_RF_DISCOVER_SELECT      4
+#define NCI_MSG_RF_INTF_ACTIVATED       5
+#define NCI_MSG_RF_DEACTIVATE           6
+#define NCI_MSG_RF_FIELD                7
+#define NCI_MSG_RF_T3T_POLLING          8
+#define NCI_MSG_RF_EE_ACTION            9
+#define NCI_MSG_RF_EE_DISCOVERY_REQ     10
+#define NCI_MSG_RF_PARAMETER_UPDATE     11
+
+/**********************************************
+ * NFCEE MANAGEMENT Group Opcode - 2
+ **********************************************/
+#define NCI_MSG_NFCEE_DISCOVER          0
+#define NCI_MSG_NFCEE_MODE_SET          1
+
+/**********************************************
+ * NCI Proprietary  Group       - F
+ **********************************************/
+
+/**********************************************
+ * NCI Core Group Params
+ **********************************************/
+#define NCI_CORE_PARAM_SIZE_RESET       0x01
+#define NCI_CORE_PARAM_SIZE_RESET_RSP   0x03
+#define NCI_CORE_PARAM_SIZE_RESET_NTF   0x02
+
+#define NCI_CORE_PARAM_SIZE_INIT        0x00 /* no payload */
+#define NCI_CORE_PARAM_SIZE_INIT_RSP    0x11
+#define NCI_CORE_INIT_RSP_OFFSET_NUM_INTF   0x05
+
+#define NCI_CORE_PARAM_SIZE_SET_CONFIG_RSP   0x02    /* Status (1 octet) and number of params */
+
+
+/* octet 0 */
+#define NCI_FEAT_DISCOVERY_FREG     0x00000001
+#define NCI_FEAT_DISCOVERY_CFGM     0x00000006
+/* octet 1 */
+#define NCI_FEAT_TECHNOLOGY_ROUTING 0x00000200
+#define NCI_FEAT_PROTOCOL_ROUTING   0x00000400
+#define NCI_FEAT_AID_ROUTING        0x00000800
+/* octet 2 */
+#define NCI_FEAT_BATTERY_OFF_MD     0x00010000
+#define NCI_FEAT_SWITCH_OFF_MD      0x00020000
+
+
+/* supported Interfaces */
+#define NCI_SUP_INTF_FRAME           0x0001
+#define NCI_SUP_INTF_ISO_DEP         0x0002
+#define NCI_SUP_INTF_NFC_DEP         0x0004
+
+
+
+#define NCI_CORE_PARAM_SIZE_CON_CREATE      0x02 /* handle, num_tlv, (tlv) */
+#define NCI_CORE_PARAM_SIZE_CON_CREATE_RSP  0x04 /* status, size, credits, conn_id */
+#define NCI_CON_CREATE_TAG_EE_INTF          0x00 /* old */
+#define NCI_CON_CREATE_TAG_RF_DISC_ID       0x00
+#define NCI_CON_CREATE_TAG_NFCEE_VAL        0x01
+
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE       0x01 /* Conn ID (1 octet) */
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE_RSP   0x01 /* Status (1 octet) */
+
+#define NCI_CORE_PARAM_SIZE_RF_FIELD_NTF            0x01 /* RF Field Status (1 octet) */
+
+#define NCI_RESET_TYPE_KEEP_CFG         0x00  /* Keep the NCI configuration (if possible) and perform NCI initialization. */
+#define NCI_RESET_TYPE_RESET_CFG        0x01  /* Reset the NCI configuration, and perform NCI initialization. */
+
+#define NCI_RESET_STATUS_KEPT_CFG       0x00  /* NCI Configuration has been kept  */
+#define NCI_RESET_STATUS_RESET_CFG      0x01  /* NCI Configuration has been reset */
+
+#define NCI_RF_STS_NO_REMOTE    0x00 /* No operating field generated by remote device  */
+#define NCI_RF_STS_REMOTE       0x01 /* Operating field generated by remote device  */
+
+
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE      0x01 /* Discovery Action (1 octet) */
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE_RSP  0x02 /* Status (1 octet)Number of NFCEEs (1 octet) */
+
+#define NCI_DISCOVER_ACTION_DISABLE     0
+#define NCI_DISCOVER_ACTION_ENABLE      1
+
+#define NCI_EE_DISCOVER_REQ_TYPE_LISTEN     0x01
+#define NCI_EE_DISCOVER_REQ_TYPE_POLL       0x02
+
+#define NCI_RF_PARAM_ID_TECH_N_MODE     0x00  /* RF Technology and Mode   */
+#define NCI_RF_PARAM_ID_TX_BIT_RATE     0x01  /* Transmit Bit Rate        */
+#define NCI_RF_PARAM_ID_RX_BIT_RATE     0x02  /* Receive Bit Rate         */
+#define NCI_RF_PARAM_ID_B_DATA_EX_PARAM 0x03  /* B Data Exchange config param */
+
+
+#define NCI_NFCEE_INTERFACE_APDU         0x00
+#define NCI_NFCEE_INTERFACE_HCI_ACCESS   0x01
+#define NCI_NFCEE_INTERFACE_T3T          0x02
+#define NCI_NFCEE_INTERFACE_TRANSPARENT  0x03
+#define NCI_NFCEE_INTERFACE_PROPRIETARY  0x80
+
+#define NCI_NFCEE_STS_CONN_ACTIVE       0x00
+#define NCI_NFCEE_STS_CONN_INACTIVE     0x01
+#define NCI_NFCEE_STS_REMOVED           0x02
+#define NCI_NUM_NFCEE_STS               3
+
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET      0x02 /* Logical Target ID (1 octet)NFCEE Mode (1 octet) */
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET_RSP  0x01 /* Status (1 octet) */
+
+#define NCI_NFCEE_MD_DEACTIVATE         0x00    /* Deactivate the connected NFCEE */
+#define NCI_NFCEE_MD_ACTIVATE           0x01    /* Activate the connected NFCEE */
+#define NCI_NUM_NFCEE_MODE              2
+
+/**********************************************
+ * NCI Deactivation Type
+ **********************************************/
+#define NCI_DEACTIVATE_TYPE_IDLE        0   /* Idle Mode     */
+#define NCI_DEACTIVATE_TYPE_SLEEP       1   /* Sleep Mode    */
+#define NCI_DEACTIVATE_TYPE_SLEEP_AF    2   /* Sleep_AF Mode */
+#define NCI_DEACTIVATE_TYPE_DISCOVERY   3   /* Discovery     */
+
+/**********************************************
+ * NCI Deactivation Reasons
+ **********************************************/
+#define NCI_DEACTIVATE_REASON_DH_REQ        0   /* DH Request       */
+#define NCI_DEACTIVATE_REASON_ENDPOINT_REQ  1   /* Endpoint Request */
+#define NCI_DEACTIVATE_REASON_RF_LINK_LOSS  2   /* RF Link Loss     */
+#define NCI_DEACTIVATE_REASON_NFCB_BAD_AFI  3   /* NFC-B Bad AFI    */
+
+ /**********************************************
+ * NCI Interface Mode
+ **********************************************/
+#define NCI_INTERFACE_MODE_POLL             1
+#define NCI_INTERFACE_MODE_LISTEN           2
+#define NCI_INTERFACE_MODE_POLL_N_LISTEN    3
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_EE_DIRECT_RF      0
+#define NCI_INTERFACE_FRAME             1
+#define NCI_INTERFACE_ISO_DEP           2
+#define NCI_INTERFACE_NFC_DEP           3
+#define NCI_INTERFACE_MAX               NCI_INTERFACE_NFC_DEP
+#define NCI_INTERFACE_FIRST_VS          0x80
+typedef UINT8 tNCI_INTF_TYPE;
+
+/**********************************************
+ * NCI RF Management / DISCOVERY Group Params
+ **********************************************/
+#define NCI_DISCOVER_PARAM_SIZE_RSP     0x01
+
+#define NCI_DISCOVER_PARAM_SIZE_SELECT      0x03 /* ID, protocol, interface */
+#define NCI_DISCOVER_PARAM_SIZE_SELECT_RSP  0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_STOP        0x00 /*  */
+#define NCI_DISCOVER_PARAM_SIZE_STOP_RSP    0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT       0x01 /* type */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_RSP   0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_NTF   0x01 /* type */
+
+/**********************************************
+ * Supported Protocols
+ **********************************************/
+#define NCI_PROTOCOL_UNKNOWN            0x00
+#define NCI_PROTOCOL_T1T                0x01
+#define NCI_PROTOCOL_T2T                0x02
+#define NCI_PROTOCOL_T3T                0x03
+#define NCI_PROTOCOL_ISO_DEP            0x04
+#define NCI_PROTOCOL_NFC_DEP            0x05
+/**********************************************
+ * Proprietary Protocols
+ **********************************************/
+#ifndef NCI_PROTOCOL_18092_ACTIVE
+#define NCI_PROTOCOL_18092_ACTIVE       0x80
+#endif
+#ifndef NCI_PROTOCOL_B_PRIME
+#define NCI_PROTOCOL_B_PRIME            0x81
+#endif
+#ifndef NCI_PROTOCOL_DUAL
+#define NCI_PROTOCOL_DUAL               0x82
+#endif
+#ifndef NCI_PROTOCOL_15693
+#define NCI_PROTOCOL_15693              0x83
+#endif
+#ifndef NCI_PROTOCOL_KOVIO
+#define NCI_PROTOCOL_KOVIO              0x8a
+#endif
+
+
+/* Discovery Types/Detected Technology and Mode */
+#define NCI_DISCOVERY_TYPE_POLL_A               0x00
+#define NCI_DISCOVERY_TYPE_POLL_B               0x01
+#define NCI_DISCOVERY_TYPE_POLL_F               0x02
+#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE        0x03
+#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE        0x05
+#define NCI_DISCOVERY_TYPE_POLL_B_PRIME         0x74
+#define NCI_DISCOVERY_TYPE_POLL_KOVIO           0x77
+#define NCI_DISCOVERY_TYPE_LISTEN_A             0x80
+#define NCI_DISCOVERY_TYPE_LISTEN_B             0x81
+#define NCI_DISCOVERY_TYPE_LISTEN_F             0x82
+#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE      0x83
+#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE      0x85
+#define NCI_DISCOVERY_TYPE_LISTEN_B_PRIME       0xF4
+#define NCI_DISCOVERY_TYPE_POLL_ISO15693        0x06
+#define NCI_DISCOVERY_TYPE_LISTEN_ISO15693      0x86
+#define NCI_DISCOVERY_TYPE_MAX  NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+
+typedef UINT8 tNCI_DISCOVERY_TYPE;
+
+#define NCI_EE_TRIG_7816_SELECT         0x00
+#define NCI_EE_TRIG_RF_PROTOCOL         0x01
+#define NCI_EE_TRIG_RF_TECHNOLOGY       0x02
+#define NCI_EE_TRIG_APP_INIT            0x10
+
+#define NCI_EE_ACT_TAG_AID              0xC0        /* AID                 */
+#define NCI_EE_ACT_TAG_PROTO            0xC1        /* RF protocol         */
+#define NCI_EE_ACT_TAG_TECH             0xC2        /* RF technology       */
+#define NCI_EE_ACT_TAG_DATA             0xC3        /* hex data for app    */
+#define NCI_EE_ACT_TAG_DEBUG            0xC4        /* debug trace         */
+
+#define NCI_ROUTE_TAG_TECH              0x00        /* Technology based routing  */
+#define NCI_ROUTE_TAG_PROTO             0x01        /* Protocol based routing  */
+#define NCI_ROUTE_TAG_AID               0x02        /* AID routing */
+
+#define NCI_ROUTE_PWR_STATE_ON          0x01        /* The device is on */
+#define NCI_ROUTE_PWR_STATE_SWITCH_OFF  0x02        /* The device is switched off */
+#define NCI_ROUTE_PWR_STATE_BATT_OFF    0x04        /* The device's battery is removed */
+
+#define NCI_NFCEE_TAG_HW_ID             0x00       /* Hardware / Registration Identification  */
+#define NCI_NFCEE_TAG_ATR_BYTES         0x01       /* ATR Bytes  */
+#define NCI_NFCEE_TAG_T3T_INFO          0x02       /* T3T Command Set Interface Supplementary Info */
+#define NCI_NFCEE_TAG_HCI_HOST_ID       0xA0       /* HCI host ID */
+
+#define NCI_DISCOVER_NTF_LAST           0x00
+#define NCI_DISCOVER_NTF_LAST_ABORT     0x01
+#define NCI_DISCOVER_NTF_MORE           0x02
+
+
+/* NCI RF Management Group Params */
+#define NCI_RF_PARAM_SIZE_T3T_POLLING   0x04        /* System Code, RC, TSN */
+
+/**********************************************
+ * NCI Parameter IDs
+ **********************************************/
+
+#define NCI_PARAM_ID_TOTAL_DURATION     0x00
+#define NCI_PARAM_ID_CON_DEVICES_LIMIT  0x01
+#define NCI_PARAM_ID_PA_BAILOUT         0x08
+#define NCI_PARAM_ID_PB_AFI             0x10
+#define NCI_PARAM_ID_PB_BAILOUT         0x11
+#define NCI_PARAM_ID_PB_ATTRIB_PARAM1   0x12
+#define NCI_PARAM_ID_PF_BIT_RATE        0x18
+#define NCI_PARAM_ID_PB_H_INFO          0x20
+#define NCI_PARAM_ID_PI_BIT_RATE        0x21
+
+#define NCI_PARAM_ID_BITR_NFC_DEP       0x28
+#define NCI_PARAM_ID_ATR_REQ_GEN_BYTES  0x29
+#define NCI_PARAM_ID_ATR_REQ_CONFIG     0x2A
+
+#define NCI_PARAM_ID_LA_BIT_FRAME_SDD   0x30
+#define NCI_PARAM_ID_LA_PLATFORM_CONFIG 0x31
+#define NCI_PARAM_ID_LA_SEL_INFO        0x32
+#define NCI_PARAM_ID_LA_NFCID1          0x33
+#define NCI_PARAM_ID_LB_SENSB_INFO      0x38
+#define NCI_PARAM_ID_LB_NFCID0          0x39
+#define NCI_PARAM_ID_LB_APPDATA         0x3A
+#define NCI_PARAM_ID_LB_SFGI            0x3B
+#define NCI_PARAM_ID_LB_ADC_FO          0x3C
+#define NCI_PARAM_ID_LB_PROTOCOL        NCI_PARAM_ID_LB_SENSB_INFO
+
+#define NCI_PARAM_ID_LF_T3T_ID1         0x40
+#define NCI_PARAM_ID_LF_T3T_ID2         0x41
+#define NCI_PARAM_ID_LF_T3T_ID3         0x42
+#define NCI_PARAM_ID_LF_T3T_ID4         0x43
+#define NCI_PARAM_ID_LF_T3T_ID5         0x44
+#define NCI_PARAM_ID_LF_T3T_ID6         0x45
+#define NCI_PARAM_ID_LF_T3T_ID7         0x46
+#define NCI_PARAM_ID_LF_T3T_ID8         0x47
+#define NCI_PARAM_ID_LF_T3T_ID9         0x48
+#define NCI_PARAM_ID_LF_T3T_ID10        0x49
+#define NCI_PARAM_ID_LF_T3T_ID11        0x4A
+#define NCI_PARAM_ID_LF_T3T_ID12        0x4B
+#define NCI_PARAM_ID_LF_T3T_ID13        0x4C
+#define NCI_PARAM_ID_LF_T3T_ID14        0x4D
+#define NCI_PARAM_ID_LF_T3T_ID15        0x4E
+#define NCI_PARAM_ID_LF_T3T_ID16        0x4F
+#define NCI_PARAM_ID_LF_PROTOCOL        0x50
+#define NCI_PARAM_ID_LF_T3T_PMM         0x51
+#define NCI_PARAM_ID_LF_T3T_MAX         0x52    /* max num of LF_T3T_ID supported by NFCC (1 for now) */
+#define NCI_PARAM_ID_LF_T3T_FLAGS2      0x53
+#define NCI_PARAM_ID_LF_CON_BITR_F      0x54
+#define NCI_PARAM_ID_FWI                0x58
+#define NCI_PARAM_ID_LA_HIST_BY         0x59
+#define NCI_PARAM_ID_LB_H_INFO_RSP      0x5A
+#define NCI_PARAM_ID_LI_BIT_RATE        0x5B
+
+#define NCI_PARAM_ID_WT                 0x60
+#define NCI_PARAM_ID_ATR_RES_GEN_BYTES  0x61
+#define NCI_PARAM_ID_ATR_RSP_CONFIG     0x62
+
+#define NCI_PARAM_ID_RF_FIELD_INFO      0x80
+#define NCI_PARAM_ID_RF_NFCEE_ACTION    0x81
+#define NCI_PARAM_ID_NFC_DEP_OP         0x82
+
+
+
+/* NCI_PARAM_ID_HOST_LISTEN_MASK (byte1 for DH, byte2 for UICC) */
+#define NCI_LISTEN_MASK_A               0x01 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_B               0x02 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_F               0x04 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_A_ACTIVE        0x08 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE & 0x0F))  */
+#define NCI_LISTEN_MASK_B_PRIME         0x10 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PRIME & 0x0F))   */
+#define NCI_LISTEN_MASK_F_ACTIVE        0x20 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE & 0x0F))  */
+#define NCI_LISTEN_MASK_ISO15693        0x40 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_ISO15693 & 0x0F))  */
+
+/* Type A Parameters */
+#define NCI_PARAM_PLATFORM_T1T      0x0C
+#define NCI_PARAM_SEL_INFO_ISODEP   0x20
+#define NCI_PARAM_SEL_INFO_NFCDEP   0x40
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_TOTAL_DURATION        2
+
+#define NCI_PARAM_LEN_PA_FSDI               1
+
+#define NCI_PARAM_LEN_LA_BIT_FRAME_SDD      1
+#define NCI_PARAM_LEN_LA_PLATFORM_CONFIG    1
+#define NCI_PARAM_LEN_LA_SEL_INFO           1
+
+#define NCI_PARAM_LEN_LB_SENSB_INFO         1
+#define NCI_PARAM_LEN_LB_NFCID0             4
+#define NCI_PARAM_LEN_LB_APPDATA            4
+#define NCI_PARAM_LEN_LB_ADC_FO             1
+
+#define NCI_PARAM_LEN_LF_PROTOCOL           1
+#define NCI_PARAM_LEN_LF_T3T_FLAGS2         2
+#define NCI_PARAM_LEN_LF_T3T_PMM            8
+#define NCI_PARAM_LEN_LF_T3T_ID            10
+
+#define NCI_PARAM_LEN_FWI                   1
+#define NCI_PARAM_LEN_WT                    1
+/* GEN_BYTES - variable */
+
+/* Listen protocol bits - NCI_PARAM_ID_LF_PROTOCOL and NCI_PARAM_ID_LB_SENSB_INFO */
+#define NCI_LISTEN_PROTOCOL_ISO_DEP     0x01
+#define NCI_LISTEN_PROTOCOL_NFC_DEP     0x02
+
+#define NCI_DISCOVER_PARAM_SIZE_TEST_RF       0x06
+
+
+/* LF_T3T_FLAGS2 listen bits all-disabled definition */
+#define NCI_LF_T3T_FLAGS2_ALL_DISABLED  0x0000
+#define NCI_LF_T3T_FLAGS2_ID1_ENABLED   0x0001
+
+typedef struct
+{
+    UINT16              addr;
+    UINT8               len;
+    UINT8               *data;
+} NCIP_T1T_SETMEM_CMD_t;
+
+typedef struct
+{
+    UINT8               status;
+} NCIP_T1T_SETMEM_RSP_t;
+
+typedef struct
+{
+    UINT16              addr;
+} NCIP_T1T_GETMEM_CMD_t;
+
+typedef struct
+{
+    UINT8               status;
+    UINT8               *data;
+} NCIP_T1T_GETMEM_RSP_t;
+
+typedef struct
+{
+    UINT8               hr0;
+    UINT8               hr1;
+} NCIP_T1T_SETHR_CMD_t;
+
+typedef struct
+{
+    UINT8               status;
+} NCIP_T1T_SETHR_RSP_t;
+
+
+#ifndef NCI_GET_CMD_BUF
+#if (!defined (HCI_USE_VARIABLE_SIZE_CMD_BUF) || (HCI_USE_VARIABLE_SIZE_CMD_BUF == FALSE))
+/* Allocate fixed-size buffer from HCI_CMD_POOL (default case) */
+#define NCI_GET_CMD_BUF(paramlen)    ((BT_HDR *) GKI_getpoolbuf (NFC_NCI_POOL_ID))
+#else
+/* Allocate smallest possible buffer (for platforms with limited RAM) */
+#define NCI_GET_CMD_BUF(paramlen)    ((BT_HDR *) GKI_getbuf ((UINT16) (BT_HDR_SIZE + NCI_MSG_HDR_SIZE + NCI_MSG_OFFSET_SIZE + (paramlen))))
+#endif
+#endif  /* NCI_GET_CMD_BUF */
+
+
+#define NCI_MAX_AID_LEN     16
+
+
+typedef struct
+{
+    UINT8   type;
+    UINT8   frequency;
+} tNCI_DISCOVER_PARAMS;
+
+typedef struct
+{
+    UINT8   protocol;
+    UINT8   mode;
+    UINT8   intf_type;
+} tNCI_DISCOVER_MAPS;
+
+#define NCI_NFCID1_MAX_LEN    10
+typedef struct
+{
+    UINT8       sens_res[2];/* SENS_RES Response (ATQA). Available after Technology Detection */
+    UINT8       nfcid1_len;    /* 4, 7 or 10 */
+    UINT8       nfcid1[NCI_NFCID1_MAX_LEN]; /* AKA NFCID1 */
+    UINT8       sel_rsp;    /* SEL_RSP (SAK) Available after Collision Resolution */
+} tNCI_RF_PA_PARAMS;
+
+
+#define NCI_MAX_SENSB_RES_LEN       12
+typedef struct
+{
+    UINT8       sensb_res_len;/* Length of SENSB_RES Response (Byte 2 - Byte 12 or 13) Available after Technology Detection */
+    UINT8       sensb_res[NCI_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+} tNCI_RF_PB_PARAMS;
+
+#define NCI_MAX_SENSF_RES_LEN       18
+#define NCI_SENSF_RES_OFFSET_PAD0   8
+#define NCI_SENSF_RES_OFFSET_RD     16
+#define NCI_NFCID2_LEN              8
+#define NCI_T3T_PMM_LEN             8
+#define NCI_SYSTEMCODE_LEN          2
+#define NCI_RF_F_UID_LEN            NCI_NFCID2_LEN
+#define NCI_MRTI_CHECK_INDEX        13
+#define NCI_MRTI_UPDATE_INDEX       14
+typedef struct
+{
+    UINT8       bit_rate;/* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+    UINT8       sensf_res_len;/* Length of SENSF_RES Response (Byte 2 - Byte 17 or 19) Available after Technology Detection */
+    UINT8       sensf_res[NCI_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+} tNCI_RF_PF_PARAMS;
+
+typedef struct
+{
+    UINT8       nfcid2[NCI_NFCID2_LEN];  /* NFCID2 generated by the Local NFCC for NFC-DEP Protocol.Available for Frame Interface  */
+} tNCI_RF_LF_PARAMS;
+
+typedef struct
+{
+    tNCI_DISCOVERY_TYPE     mode;
+    union
+    {
+        tNCI_RF_PA_PARAMS   pa;
+        tNCI_RF_PB_PARAMS   pb;
+        tNCI_RF_PF_PARAMS   pf;
+        tNCI_RF_LF_PARAMS   lf;
+    } param; /* Discovery Type specific parameters */
+} tNCI_RF_TECH_PARAMS;
+
+
+#ifndef NCI_MAX_ATS_LEN
+#define NCI_MAX_ATS_LEN             60
+#endif
+#ifndef NCI_MAX_HIS_BYTES_LEN
+#define NCI_MAX_HIS_BYTES_LEN       50
+#endif
+#ifndef NCI_MAX_GEN_BYTES_LEN
+#define NCI_MAX_GEN_BYTES_LEN       48
+#endif
+
+#define NCI_ATS_T0_INDEX            0
+#define NCI_ATS_TC_MASK             0x40
+#define NCI_ATS_TB_MASK             0x20
+#define NCI_ATS_TA_MASK             0x10
+#define NCI_ATS_FSCI_MASK           0x0F
+typedef struct
+{
+    UINT8       ats_res_len;  /* Length of ATS RES */
+    UINT8       ats_res[NCI_MAX_ATS_LEN];  /* ATS RES defined in [DIGPROT] */
+} tNCI_INTF_PA_ISO_DEP;
+
+typedef struct
+{
+    UINT8       rats;  /* RATS */
+} tNCI_INTF_LA_ISO_DEP;
+
+#define NCI_P_GEN_BYTE_INDEX    15
+#define NCI_L_GEN_BYTE_INDEX    14
+#define NCI_L_NFC_DEP_TO_INDEX  13
+typedef struct
+{
+    UINT8       atr_res_len;  /* Length of ATR_RES */
+    UINT8       atr_res[NCI_MAX_ATS_LEN];  /* ATR_RES (Byte 3 - Byte 17+n) as defined in [DIGPROT] */
+} tNCI_INTF_PA_NFC_DEP;
+
+/* Note: keep tNCI_INTF_PA_NFC_DEP data member in the same order as tNCI_INTF_LA_NFC_DEP */
+typedef struct
+{
+    UINT8       atr_req_len;  /* Length of ATR_REQ */
+    UINT8       atr_req[NCI_MAX_ATS_LEN];  /* ATR_REQ (Byte 3 - Byte 18+n) as defined in [DIGPROT] */
+} tNCI_INTF_LA_NFC_DEP;
+typedef tNCI_INTF_LA_NFC_DEP tNCI_INTF_LF_NFC_DEP;
+typedef tNCI_INTF_PA_NFC_DEP tNCI_INTF_PF_NFC_DEP;
+
+#define NCI_MAX_ATTRIB_LEN   (10 + NCI_MAX_GEN_BYTES_LEN)
+
+typedef struct
+{
+    UINT8       attrib_res_len;  /* Length of ATTRIB RES */
+    UINT8       attrib_res[NCI_MAX_ATTRIB_LEN];  /* ATTRIB RES  as defined in [DIGPROT] */
+} tNCI_INTF_PB_ISO_DEP;
+
+typedef struct
+{
+    UINT8       attrib_req_len;  /* Length of ATTRIB REQ */
+    UINT8       attrib_req[NCI_MAX_ATTRIB_LEN];  /* ATTRIB REQ (Byte 2 - Byte 10+k) as defined in [DIGPROT] */
+} tNCI_INTF_LB_ISO_DEP;
+
+typedef struct
+{
+    tNCI_INTF_TYPE      type;  /* Interface Type  1 Byte  See Table 67 */
+    union
+    {
+        tNCI_INTF_LA_ISO_DEP    la_iso;
+        tNCI_INTF_PA_ISO_DEP    pa_iso;
+        tNCI_INTF_LB_ISO_DEP    lb_iso;
+        tNCI_INTF_PB_ISO_DEP    pb_iso;
+        tNCI_INTF_LA_NFC_DEP    la_nfc;
+        tNCI_INTF_PA_NFC_DEP    pa_nfc;
+        tNCI_INTF_LF_NFC_DEP    lf_nfc;
+        tNCI_INTF_PF_NFC_DEP    pf_nfc;
+    } intf_param;       /* Activation Parameters   0 - n Bytes */
+} tNCI_INTF_PARAMS;
+
+/*
+** HCI Network CMD/NTF structure
+*/
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type A card emulation enabled indicator, 0x02:enabled    */
+    UINT8   sak;
+    UINT8   uid_reg_len;
+    UINT8   uid_reg[10];
+    UINT8   atqa[2];        /* ATQA response code */
+    UINT8   app_data_len;
+    UINT8   app_data[15];   /* 15 bytes optional storage for historic data, use 2 slots */
+    UINT8   fwi_sfgi;       /* FRAME WAITING TIME, START-UP FRAME GUARD TIME            */
+    UINT8   cid_support;
+    UINT8   datarate_max[3];
+    UINT8   clt_support;
+} tNCI_HCI_CE_RF_A;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type B card emulation enabled indicator, 0x02:enabled    */
+    UINT8   pupi_len;
+    UINT8   pupi_reg[4];
+    UINT8   afi;
+    UINT8   atqb[4];        /* 4 bytes ATQB application data                            */
+    UINT8   higherlayer_resp[61]; /* 0~ 61 bytes ATRB_INF use 1~4 personality slots     */
+    UINT8   datarate_max[3];
+    UINT8   natrb;
+} tNCI_HCI_CE_RF_B;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type B prime card emulation enabled indicator, 0x02:enabled */
+    UINT8   pat_in_len;
+    UINT8   pat_in[8];
+    UINT8   dat_out_len;
+    UINT8   dat_out[40];    /* ISO7816-3 <=64 byte, and other fields are 9 bytes        */
+    UINT8   natr;
+} tNCI_HCI_CE_RF_BP;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type F card emulation enabled indicator, 0x02:enabled    */
+    UINT8   speed_cap;
+    UINT8   clt_support;
+} tNCI_HCI_CE_RF_F;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   datarate_max;
+} tNCI_HCI_RD_RF_A;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   afi;
+    UINT8   hldata_len;
+    UINT8   high_layer_data[61];  /* INF field in ATTRIB command                        */
+} tNCI_HCI_RD_RF_B;
+
+typedef struct
+{
+    UINT8   source_host;
+    UINT8   dest_host;
+    UINT8   source_gate;
+    UINT8   dest_gate;
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+} tNCI_HCI_DYN_PIPE_INFO;
+
+typedef struct
+{
+    UINT8                target_handle;
+    UINT8                session_id[8];
+    UINT8                sync_id[2];
+    UINT8                static_pipe_info;
+    tNCI_HCI_CE_RF_A     ce_rf_a;
+    tNCI_HCI_CE_RF_B     ce_rf_b;
+    tNCI_HCI_CE_RF_BP    ce_rf_bp;
+    tNCI_HCI_CE_RF_F     ce_rf_f;
+} tNCI_HCI_NETWK;
+
+typedef struct
+{
+    UINT8                   target_handle;
+    UINT8                   session_id[8];
+    UINT8                   static_pipe_info;
+    UINT8                   num_dyn_pipes;
+    tNCI_HCI_DYN_PIPE_INFO  dyn_pipe_info[20];
+} tNCI_HCI_NETWK_DH;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* NFC_NCI_DEFS_H */
diff --git a/halimpl/bcm2079x/hal/include/nfc_hal_api.h b/halimpl/bcm2079x/hal/include/nfc_hal_api.h
new file mode 100644
index 0000000..d147527
--- /dev/null
+++ b/halimpl/bcm2079x/hal/include/nfc_hal_api.h
@@ -0,0 +1,223 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFC Hardware Abstraction Layer API
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_API_H
+#define NFC_HAL_API_H
+#include <hardware/nfc.h>
+#include "data_types.h"
+
+/****************************************************************************
+** NFC_HDR header definition for NFC messages
+*****************************************************************************/
+typedef struct
+{
+    UINT16          event;
+    UINT16          len;
+    UINT16          offset;
+    UINT16          layer_specific;
+} NFC_HDR;
+#define NFC_HDR_SIZE (sizeof (NFC_HDR))
+
+typedef UINT8 tHAL_NFC_STATUS;
+
+typedef void (tHAL_NFC_STATUS_CBACK) (tHAL_NFC_STATUS status);
+typedef void (tHAL_NFC_CBACK) (UINT8 event, tHAL_NFC_STATUS status);
+typedef void (tHAL_NFC_DATA_CBACK) (UINT16 data_len, UINT8   *p_data);
+
+/*******************************************************************************
+** tHAL_NFC_ENTRY HAL entry-point lookup table
+*******************************************************************************/
+
+typedef void (tHAL_API_INITIALIZE) (void);
+typedef void (tHAL_API_TERMINATE) (void);
+typedef void (tHAL_API_OPEN) (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback);
+typedef void (tHAL_API_CLOSE) (void);
+typedef void (tHAL_API_CORE_INITIALIZED) (UINT8 *p_core_init_rsp_params);
+typedef void (tHAL_API_WRITE) (UINT16 data_len, UINT8 *p_data);
+typedef BOOLEAN (tHAL_API_PREDISCOVER) (void);
+typedef void (tHAL_API_CONTROL_GRANTED) (void);
+typedef void (tHAL_API_POWER_CYCLE) (void);
+
+
+typedef struct
+{
+    tHAL_API_INITIALIZE *initialize;
+    tHAL_API_TERMINATE *terminate;
+    tHAL_API_OPEN *open;
+    tHAL_API_CLOSE *close;
+    tHAL_API_CORE_INITIALIZED *core_initialized;
+    tHAL_API_WRITE *write;
+    tHAL_API_PREDISCOVER *prediscover;
+    tHAL_API_CONTROL_GRANTED *control_granted;
+    tHAL_API_POWER_CYCLE *power_cycle;
+
+
+} tHAL_NFC_ENTRY;
+
+
+/*******************************************************************************
+** HAL API Function Prototypes
+*******************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Toolset-specific macro for exporting API funcitons */
+#if (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE)) && (defined(_WINDLL))
+#define EXPORT_HAL_API  __declspec(dllexport)
+#else
+#define EXPORT_HAL_API
+#endif
+
+/*******************************************************************************
+**
+** Function         HAL_NfcInitialize
+**
+** Description      Called when HAL library is loaded.
+**
+**                  Initialize GKI and start the HCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcInitialize(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcTerminate
+**
+** Description      Called to terminate NFC HAL
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcTerminate(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcOpen
+**
+** Description      Open transport and intialize the NFCC, and
+**                  Register callback for HAL event notifications,
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcClose
+**
+** Description      Prepare for shutdown. A HAL_CLOSE_CPLT_EVT will be
+**                  reported when complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcClose (void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcCoreInitialized
+**
+** Description      Called after the CORE_INIT_RSP is received from the NFCC.
+**                  At this time, the HAL can do any chip-specific configuration,
+**                  and when finished signal the libnfc-nci with event
+**                  HAL_POST_INIT_CPLT_EVT.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcCoreInitialized (UINT8 *p_core_init_rsp_params);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcWrite
+**
+** Description      Send an NCI control message or data packet to the
+**                  transport. If an NCI command message exceeds the transport
+**                  size, HAL is responsible for fragmenting it, Data packets
+**                  must be of the correct size.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcWrite (UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreDiscover
+**
+** Description      Perform any vendor-specific pre-discovery actions (if needed)
+**                  If any actions were performed TRUE will be returned, and
+**                  HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
+**                  completed.
+**
+** Returns          TRUE if vendor-specific pre-discovery actions initialized
+**                  FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+EXPORT_HAL_API BOOLEAN HAL_NfcPreDiscover (void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcControlGranted
+**
+** Description      Grant control to HAL control for sending NCI commands.
+**
+**                  Call in response to HAL_REQUEST_CONTROL_EVT.
+**
+**                  Must only be called when there are no NCI commands pending.
+**
+**                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
+**                  needs control of NCI.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcControlGranted (void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPowerCycle
+**
+** Description      Restart NFCC by power cyle
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcPowerCycle (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_API_H  */
diff --git a/halimpl/bcm2079x/hal/include/nfc_hal_target.h b/halimpl/bcm2079x/hal/include/nfc_hal_target.h
new file mode 100644
index 0000000..b6eedc9
--- /dev/null
+++ b/halimpl/bcm2079x/hal/include/nfc_hal_target.h
@@ -0,0 +1,244 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 NFC_HAL_TARGET_H
+#define NFC_HAL_TARGET_H
+
+#include "data_types.h"
+
+#ifdef BUILDCFG
+#include "buildcfg_hal.h"
+#endif
+
+/****************************************************************************
+** NCI related configuration
+****************************************************************************/
+
+/* GKI pool for NCI messages */
+#ifndef NFC_HAL_NCI_POOL_ID
+#define NFC_HAL_NCI_POOL_ID                     GKI_POOL_ID_1
+#endif
+
+#ifndef NFC_HAL_NCI_POOL_BUF_SIZE
+#define NFC_HAL_NCI_POOL_BUF_SIZE               GKI_BUF1_SIZE
+#endif
+
+/* Initial Max Control Packet Payload Size (until receiving payload size in INIT_CORE_RSP) */
+#ifndef NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE
+#define NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE      0xFF
+#endif
+
+/* Number of bytes to reserve in front of NCI messages (e.g. for transport header) */
+#ifndef NFC_HAL_NCI_MSG_OFFSET_SIZE
+#define NFC_HAL_NCI_MSG_OFFSET_SIZE             1
+#endif
+
+/* NFC-WAKE */
+#ifndef NFC_HAL_LP_NFC_WAKE_GPIO
+#define NFC_HAL_LP_NFC_WAKE_GPIO                UPIO_GENERAL3
+#endif
+
+/* NFCC snooze mode idle timeout before deassert NFC_WAKE in ms */
+#ifndef NFC_HAL_LP_IDLE_TIMEOUT
+#define NFC_HAL_LP_IDLE_TIMEOUT                 100
+#endif
+
+/* NFC snooze mode */
+#ifndef NFC_HAL_LP_SNOOZE_MODE
+#define NFC_HAL_LP_SNOOZE_MODE                  NFC_HAL_LP_SNOOZE_MODE_UART
+#endif
+
+/* Idle Threshold Host in 100ms unit */
+#ifndef NFC_HAL_LP_IDLE_THRESHOLD_HOST
+#define NFC_HAL_LP_IDLE_THRESHOLD_HOST          0
+#endif
+
+/* Idle Threshold HC in 100ms unit */
+#ifndef NFC_HAL_LP_IDLE_THRESHOLD_HC
+#define NFC_HAL_LP_IDLE_THRESHOLD_HC            0
+#endif
+
+
+/* Default NFCC power-up baud rate */
+#ifndef NFC_HAL_DEFAULT_BAUD
+#define NFC_HAL_DEFAULT_BAUD                    USERIAL_BAUD_115200
+#endif
+
+/* time (in ms) between power off and on NFCC */
+#ifndef NFC_HAL_POWER_CYCLE_DELAY
+#define NFC_HAL_POWER_CYCLE_DELAY               100
+#endif
+
+#ifndef NFC_HAL_PRM_DEBUG
+#define NFC_HAL_PRM_DEBUG                       TRUE
+#endif
+
+/* max patch data length (Can be overridden by platform for ACL HCI command size) */
+#ifndef NFC_HAL_PRM_HCD_CMD_MAXLEN
+#define NFC_HAL_PRM_HCD_CMD_MAXLEN              250
+#endif
+
+/* Require PreI2C patch by default */
+#ifndef NFC_HAL_PRE_I2C_PATCH_INCLUDED
+#define NFC_HAL_PRE_I2C_PATCH_INCLUDED          TRUE
+#endif
+
+/* Set to TRUE to always download patch regardless of version */
+#ifndef NFC_HAL_PRM_SKIP_VERSION_CHECK
+#define NFC_HAL_PRM_SKIP_VERSION_CHECK          FALSE
+#endif
+
+/* Mininum payload size for SPD NCI commands (used to validate HAL_NfcPrmSetSpdNciCmdPayloadSize) */
+/* Default is 32, as required by the NCI specifications; however this value may be          */
+/* over-riden for platforms that have transport packet limitations                          */
+#ifndef NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE
+#define NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE    (32)
+#endif
+
+/* amount of time to wait for RESET NTF after patch download */
+#ifndef NFC_HAL_PRM_RESET_NTF_DELAY
+#define NFC_HAL_PRM_RESET_NTF_DELAY             (10000)
+#endif
+
+/* amount of time to wait after downloading preI2C patch before downloading LPM/FPM patch */
+#ifndef NFC_HAL_PRM_POST_I2C_FIX_DELAY
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY          (200)
+#endif
+
+/* NFCC will respond to more than one technology during listen discovery  */
+#ifndef NFC_HAL_DM_MULTI_TECH_RESP
+#define NFC_HAL_DM_MULTI_TECH_RESP              TRUE
+#endif
+
+/* Data rate for 15693 command/response, it must be same as RW_I93_FLAG_DATA_RATE in nfc_target.h */
+#define NFC_HAL_I93_FLAG_DATA_RATE_LOW          0x00
+#define NFC_HAL_I93_FLAG_DATA_RATE_HIGH         0x02
+
+#ifndef NFC_HAL_I93_FLAG_DATA_RATE
+#define NFC_HAL_I93_FLAG_DATA_RATE              NFC_HAL_I93_FLAG_DATA_RATE_HIGH
+#endif
+
+/* Quick Timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC               100       /* 10ms timer */
+#endif
+
+#ifndef NFC_HAL_SHARED_TRANSPORT_ENABLED
+#define NFC_HAL_SHARED_TRANSPORT_ENABLED        FALSE
+#endif
+
+/* Enable verbose tracing by default */
+#ifndef NFC_HAL_TRACE_VERBOSE
+#define NFC_HAL_TRACE_VERBOSE                   TRUE
+#endif
+
+#ifndef NFC_HAL_INITIAL_TRACE_LEVEL
+#define NFC_HAL_INITIAL_TRACE_LEVEL             5
+#endif
+
+/* Map NFC serial port to USERIAL_PORT_6 by default */
+#ifndef USERIAL_NFC_PORT
+#define USERIAL_NFC_PORT                        (USERIAL_PORT_6)
+#endif
+
+/* Restore NFCC baud rate to default on shutdown if baud rate was updated */
+#ifndef NFC_HAL_RESTORE_BAUD_ON_SHUTDOWN
+#define NFC_HAL_RESTORE_BAUD_ON_SHUTDOWN        TRUE
+#endif
+
+/* Enable protocol tracing by default */
+#ifndef NFC_HAL_TRACE_PROTOCOL
+#define NFC_HAL_TRACE_PROTOCOL                  TRUE
+#endif
+#define BT_TRACE_PROTOCOL                       (NFC_HAL_TRACE_PROTOCOL)
+
+#define LogMsg_0 LogMsg
+#define LogMsg_1 LogMsg
+#define LogMsg_2 LogMsg
+#define LogMsg_3 LogMsg
+#define LogMsg_4 LogMsg
+#define LogMsg_5 LogMsg
+#define LogMsg_6 LogMsg
+
+/* Trace macros */
+#define BT_TRACE_0(l,t,m)                           LogMsg_0((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)),(m))
+#define BT_TRACE_1(l,t,m,p1)                        LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1))
+#define BT_TRACE_2(l,t,m,p1,p2)                     LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2))
+#define BT_TRACE_3(l,t,m,p1,p2,p3)                  LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3))
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)               LogMsg_4(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4))
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)            LogMsg_5(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5))
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)         LogMsg_6(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5),(UINT32)(p6))
+
+#define NCI_TRACE_ERROR0(m)                     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m);}
+#define NCI_TRACE_ERROR1(m,p1)                  {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1);}
+#define NCI_TRACE_ERROR2(m,p1,p2)               {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)            {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_WARNING0(m)                   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m);}
+#define NCI_TRACE_WARNING1(m,p1)                {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1);}
+#define NCI_TRACE_WARNING2(m,p1,p2)             {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)          {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_API0(m)                       {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_API, m);}
+#define NCI_TRACE_API1(m,p1)                    {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1);}
+#define NCI_TRACE_API2(m,p1,p2)                 {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2);}
+#define NCI_TRACE_API3(m,p1,p2,p3)              {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)           {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_EVENT0(m)                     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m);}
+#define NCI_TRACE_EVENT1(m,p1)                  {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1);}
+#define NCI_TRACE_EVENT2(m,p1,p2)               {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)            {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_DEBUG0(m)                     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m);}
+#define NCI_TRACE_DEBUG1(m,p1)                  {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1);}
+#define NCI_TRACE_DEBUG2(m,p1,p2)               {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* GKI_TARGET_H */
diff --git a/halimpl/bcm2079x/hal/include/nfc_types.h b/halimpl/bcm2079x/hal/include/nfc_types.h
new file mode 100644
index 0000000..c4a963f
--- /dev/null
+++ b/halimpl/bcm2079x/hal/include/nfc_types.h
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 NFC_TYPES_H
+#define NFC_TYPES_H
+
+/* Mask for NFC_HDR event field */
+#define NFC_EVT_MASK                    0xFF00
+#define NFC_SUB_EVT_MASK                0x00FF
+
+/****************************************************************************
+** NFC_HAL_TASK  definitions
+*****************************************************************************/
+
+/* NFC_HAL_TASK event messages */
+#define NFC_HAL_EVT_TO_NFC_NCI             0x0100   /* NCI message for sending to NFCC          */
+#define NFC_HAL_EVT_POST_CORE_RESET        0x0200   /* Request to start NCIT quick timer        */
+#define NFC_HAL_EVT_TO_START_QUICK_TIMER   0x0300   /* Request to start chip-specific config    */
+#define NFC_HAL_EVT_HCI                    0x0400   /* NCI message for hci persistency data     */
+#define NFC_HAL_EVT_PRE_DISCOVER           0x0500   /* NCI message to issue prediscover config  */
+#define NFC_HAL_EVT_CONTROL_GRANTED        0x0600   /* permission to send commands queued in HAL*/
+
+/* NFC_HAL_TASK sub event messages */
+#define NFC_HAL_HCI_RSP_NV_READ_EVT        (0x01 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_RSP_NV_WRITE_EVT       (0x02 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_VSC_TIMEOUT_EVT        (0x03 | NFC_HAL_EVT_HCI)
+
+
+/* Event masks for NFC_TASK messages */
+#define NFC_EVT_TO_NFC_NCI              0x4000      /* NCI message for sending to host stack    */
+#define NFC_EVT_TO_NFC_ERR              0x4100      /* Error notification to NFC Task           */
+#define NFC_EVT_TO_NFC_MSGS             0x4200      /* Messages between NFC and NCI task        */
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*****************************************************************************/
+
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
+#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define INT8_TO_STREAM(p, u8)    {*(p)++ = (INT8)(u8);}
+#define ARRAY32_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 32;           ijk++) *(p)++ = (UINT8) a[31 - ijk];}
+#define ARRAY16_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 16;           ijk++) *(p)++ = (UINT8) a[15 - ijk];}
+#define ARRAY8_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < 8;            ijk++) *(p)++ = (UINT8) a[7 - ijk];}
+#define BDADDR_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN;  ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
+#define LAP_TO_STREAM(p, a)      {register int ijk; for (ijk = 0; ijk < LAP_LEN;      ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
+#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len;        ijk++) *(p)++ = (UINT8) a[ijk];}
+#define REVERSE_ARRAY_TO_STREAM(p, a, len)  {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
+
+#define STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
+#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
+#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
+#define STREAM_TO_BDADDR(a, p)   {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
+#define STREAM_TO_ARRAY32(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY16(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY8(a, p)   {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_LAP(a, p)      {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
+#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
+#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
+#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
+#define UINT8_TO_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*****************************************************************************/
+
+#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24);  *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
+#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
+#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
+#define UINT8_TO_BE_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+
+#define BE_STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
+#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
+#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
+#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24);  *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
+#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
+#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
+#define UINT8_TO_BE_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+/*****************************************************************************
+** Define trace levels
+*****************************************************************************/
+
+#define BT_TRACE_LEVEL_NONE    0          /* No trace messages to be generated    */
+#define BT_TRACE_LEVEL_ERROR   1          /* Error condition trace messages       */
+#define BT_TRACE_LEVEL_WARNING 2          /* Warning condition trace messages     */
+#define BT_TRACE_LEVEL_API     3          /* API traces                           */
+#define BT_TRACE_LEVEL_EVENT   4          /* Debug messages for events            */
+#define BT_TRACE_LEVEL_DEBUG   5          /* Full debug messages                  */
+
+
+#define TRACE_CTRL_GENERAL          0x00000000
+#define TRACE_LAYER_NCI             0x00280000
+#define TRACE_LAYER_GKI             0x001a0000
+#define TRACE_ORG_STACK             0x00000000
+#define TRACE_ORG_GKI               0x00000400
+
+#define TRACE_TYPE_ERROR            0x00000000
+#define TRACE_TYPE_WARNING          0x00000001
+#define TRACE_TYPE_API              0x00000002
+#define TRACE_TYPE_EVENT            0x00000003
+#define TRACE_TYPE_DEBUG            0x00000004
+
+
+/* Define a function for logging */
+typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...);
+
+#endif /* NFC_TYPES_H */
+
diff --git a/halimpl/bcm2079x/hal/int/nfc_brcm_defs.h b/halimpl/bcm2079x/hal/int/nfc_brcm_defs.h
new file mode 100644
index 0000000..9ce68e3
--- /dev/null
+++ b/halimpl/bcm2079x/hal/int/nfc_brcm_defs.h
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Broadcom-specific defintions that are shared
+ *  between HAL, nfc stack, adaptation layer and applications.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_BRCM_DEFS_H
+#define NFC_BRCM_DEFS_H
+
+/*****************************************************************************
+** Broadcom-specific NCI definitions
+*****************************************************************************/
+
+/**********************************************
+ * NCI Message Proprietary  Group       - F
+ **********************************************/
+#define NCI_MSG_TAG_SET_MEM             0x00
+#define NCI_MSG_TAG_GET_MEM             0x01
+#define NCI_MSG_T1T_SET_HR              0x02
+#define NCI_MSG_SET_CLF_REGISTERS       0x03
+#define NCI_MSG_GET_BUILD_INFO          0x04
+#define NCI_MSG_HCI_NETWK               0x05
+#define NCI_MSG_SET_FWFSM               0x06
+#define NCI_MSG_SET_UICCRDRF            0x07
+#define NCI_MSG_POWER_LEVEL             0x08
+#define NCI_MSG_FRAME_LOG               0x09
+#define NCI_MSG_UICC_READER_ACTION      0x0A
+#define NCI_MSG_SET_PPSE_RESPONSE       0x0B
+#define NCI_MSG_PRBS_SET                0x0C
+#define NCI_MSG_RESET_ALL_UICC_CFG      0x0D    /* reset HCI network/close all pipes (S,D) register */
+#define NCI_MSG_GET_NFCEE_INFO          0x0E
+#define NCI_MSG_DISABLE_INIT_CHECK      0x0F
+#define NCI_MSG_ANTENNA_SELF_TEST       0x10
+#define NCI_MSG_SET_MAX_PKT_SIZE        0x11
+#define NCI_MSG_NCIP_CLK_REQ_OR_CAR_DET 0x12
+#define NCI_MSG_NCIP_CONFIG_DBUART      0x13
+#define NCI_MSG_NCIP_ENABLE_DVT_DRIVER  0x14
+#define NCI_MSG_SET_ASWP                0x15
+#define NCI_MSG_ENCAPSULATE_NCI         0x16
+#define NCI_MSG_CONFIGURE_ARM_JTAG      0x17
+#define NCI_MSG_STATISTICS              0x18
+#define NCI_MSG_SET_DSP_TABLE           0x19
+#define NCI_MSG_GET_DSP_TABLE           0x1a
+#define NCI_MSG_READY_RX_CMD            0x1b
+#define NCI_MSG_GET_VBAT                0x1c
+#define NCI_MSG_GET_XTAL_INDEX_FROM_DH  0x1d
+#define NCI_MSG_SWP_LOG                 0x1e
+#define NCI_MSG_GET_PWRLEVEL            0x1f
+#define NCI_MSG_SET_VBAT_MONITOR        0x20
+#define NCI_MSG_SET_TINT_MODE           0x21
+#define NCI_MSG_ACCESS_APP              0x22
+#define NCI_MSG_SET_SECURE_MODE         0x23
+#define NCI_MSG_GET_NV_DEVICE           0x24
+#define NCI_MSG_LPTD                    0x25
+#define NCI_MSG_SET_CE4_AS_SNOOZE       0x26
+#define NCI_MSG_NFCC_SEND_HCI           0x27
+#define NCI_MSG_CE4_PATCH_DOWNLOAD_DONE 0x28
+#define NCI_MSG_EEPROM_RW               0x29
+#define NCI_MSG_GET_CLF_REGISTERS       0x2A
+#define NCI_MSG_RF_TEST                 0x2B
+#define NCI_MSG_DEBUG_PRINT             0x2C
+#define NCI_MSG_GET_PATCH_VERSION       0x2D
+#define NCI_MSG_SECURE_PATCH_DOWNLOAD   0x2E
+#define NCI_MSG_SPD_FORMAT_NVM          0x2F
+#define NCI_MSG_SPD_READ_NVM            0x30
+
+/**********************************************
+ * Proprietary  NCI status codes
+ **********************************************/
+#define NCI_STATUS_SPD_ERROR_ORDER          0xE0
+#define NCI_STATUS_SPD_ERROR_DEST           0xE1
+#define NCI_STATUS_SPD_ERROR_PROJECTID      0xE2
+#define NCI_STATUS_SPD_ERROR_CHIPVER        0xE3
+#define NCI_STATUS_SPD_ERROR_MAJORVER       0xE4
+#define NCI_STATUS_SPD_ERROR_INVALID_PARAM  0xE5
+#define NCI_STATUS_SPD_ERROR_INVALID_SIG    0xE6
+#define NCI_STATUS_SPD_ERROR_NVM_CORRUPTED  0xE7
+#define NCI_STATUS_SPD_ERROR_PWR_MODE       0xE8
+#define NCI_STATUS_SPD_ERROR_MSG_LEN        0xE9
+#define NCI_STATUS_SPD_ERROR_PATCHSIZE      0xEA
+
+
+
+#define NCI_NV_DEVICE_NONE              0x00
+#define NCI_NV_DEVICE_EEPROM            0x08
+#define NCI_NV_DEVICE_UICC1             0x10
+
+/* The events reported on tNFC_VS_CBACK */
+/* The event is (NCI_NTF_BIT|oid) or (NCI_RSP_BIT|oid) */
+#define NFC_VS_HCI_NETWK_EVT            (NCI_NTF_BIT|NCI_MSG_HCI_NETWK)
+#define NFC_VS_HCI_NETWK_RSP            (NCI_RSP_BIT|NCI_MSG_HCI_NETWK)
+#define NFC_VS_UICC_READER_ACTION_EVT   (NCI_NTF_BIT|NCI_MSG_UICC_READER_ACTION)
+#define NFC_VS_POWER_LEVEL_RSP          (NCI_RSP_BIT|NCI_MSG_POWER_LEVEL)
+#define NFC_VS_GET_NV_DEVICE_EVT        (NCI_RSP_BIT|NCI_MSG_GET_NV_DEVICE)
+#define NFC_VS_LPTD_EVT                 (NCI_NTF_BIT|NCI_MSG_LPTD)
+#define NFC_VS_GET_BUILD_INFO_EVT       (NCI_RSP_BIT|NCI_MSG_GET_BUILD_INFO)
+#define NFC_VS_GET_PATCH_VERSION_EVT    (NCI_RSP_BIT|NCI_MSG_GET_PATCH_VERSION)
+#define NFC_VS_SEC_PATCH_DOWNLOAD_EVT   (NCI_RSP_BIT|NCI_MSG_SECURE_PATCH_DOWNLOAD)
+#define NFC_VS_SEC_PATCH_AUTH_EVT       (NCI_NTF_BIT|NCI_MSG_SECURE_PATCH_DOWNLOAD)
+
+#define NCI_GET_PATCH_VERSION_NVM_OFFSET    37
+
+
+#define NCI_NFCC_PIPE_INFO_NV_SIZE      24  /* Static and dynamic pipe id and status for each pipe to uicc0 and uicc1. */
+#define NCI_PERSONALITY_SLOT_SIZE       19
+#define NCI_DYNAMIC_PIPE_SIZE           8
+
+#define NCI_SWP_INTERFACE_TYPE          0xFF    /* Type of TLV in NCI_MSG_HCI_NETWK */
+#define NCI_HCI_GATE_TYPE               0xFE    /* Type of TLV in NCI_MSG_HCI_NETWK */
+
+/* Secure Patch Download definitions (patch type definitions) */
+#define NCI_SPD_TYPE_HEADER             0x00
+#define NCI_SPD_TYPE_SRAM               0x01
+#define NCI_SPD_TYPE_AON                0x02
+#define NCI_SPD_TYPE_PATCH_TABLE        0x03
+#define NCI_SPD_TYPE_SECURE_CONFIG      0x04
+#define NCI_SPD_TYPE_CONTROLLED_CONFIG  0x05
+#define NCI_SPD_TYPE_SIGNATURE          0x06
+#define NCI_SPD_TYPE_SIGCHEK            0x07
+
+/* Secure Patch Download definitions (NCI_SPD_TYPE_HEADER definitions) */
+#define NCI_SPD_HEADER_OFFSET_CHIPVERLEN    0x18
+#define NCI_SPD_HEADER_CHIPVER_LEN          16
+
+/* NVM Type (in GET_PATCH_VERSION RSP) */
+#define NCI_SPD_NVM_TYPE_NONE           0x00
+#define NCI_SPD_NVM_TYPE_EEPROM         0x01
+#define NCI_SPD_NVM_TYPE_UICC           0x02
+
+/**********************************************
+ * NCI NFCC proprietary features in octet 3
+ **********************************************/
+#define NCI_FEAT_SIGNED_PATCH           0x01000000
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_VS_CALYPSO_CE     0x81
+#define NCI_INTERFACE_VS_T2T_CE         0x82    /* for Card Emulation side */
+#define NCI_INTERFACE_VS_15693          0x83    /* for both Reader/Writer and Card Emulation side */
+#define NCI_INTERFACE_VS_T1T_CE         0x84    /* for Card Emulation side */
+
+/**********************************************
+ * NCI Proprietary Parameter IDs
+ **********************************************/
+#define NCI_PARAM_ID_LA_FSDI            0xA0
+#define NCI_PARAM_ID_LB_FSDI            0xA1
+#define NCI_PARAM_ID_HOST_LISTEN_MASK   0xA2
+#define NCI_PARAM_ID_CHIP_TYPE          0xA3 /* NFCDEP */
+#define NCI_PARAM_ID_PA_ANTICOLL        0xA4
+#define NCI_PARAM_ID_CONTINUE_MODE      0xA5
+#define NCI_PARAM_ID_LBP                0xA6
+#define NCI_PARAM_ID_T1T_RDR_ONLY       0xA7
+#define NCI_PARAM_ID_LA_SENS_RES        0xA8
+#define NCI_PARAM_ID_PWR_SETTING_BITMAP 0xA9
+#define NCI_PARAM_ID_WI_NTF_ENABLE      0xAA
+#define NCI_PARAM_ID_LN_BITRATE         0xAB /* NFCDEP Listen Bitrate */
+#define NCI_PARAM_ID_LF_BITRATE         0xAC /* FeliCa */
+#define NCI_PARAM_ID_SWP_BITRATE_MASK   0xAD
+#define NCI_PARAM_ID_KOVIO              0xAE
+#define NCI_PARAM_ID_UICC_NTF_TO        0xAF
+#define NCI_PARAM_ID_NFCDEP             0xB0
+#define NCI_PARAM_ID_CLF_REGS_CFG       0xB1
+#define NCI_PARAM_ID_NFCDEP_TRANS_TIME  0xB2
+#define NCI_PARAM_ID_CREDIT_TIMER       0xB3
+#define NCI_PARAM_ID_CORRUPT_RX         0xB4
+#define NCI_PARAM_ID_ISODEP             0xB5
+#define NCI_PARAM_ID_LF_CONFIG          0xB6
+#define NCI_PARAM_ID_I93_DATARATE       0xB7
+#define NCI_PARAM_ID_CREDITS_THRESHOLD  0xB8
+#define NCI_PARAM_ID_TAGSNIFF_CFG       0xB9
+#define NCI_PARAM_ID_PA_FSDI            0xBA /* ISODEP */
+#define NCI_PARAM_ID_PB_FSDI            0xBB /* ISODEP */
+#define NCI_PARAM_ID_FRAME_INTF_RETXN   0xBC
+
+#define NCI_PARAM_ID_UICC_RDR_PRIORITY  0xBD
+#define NCI_PARAM_ID_GUARD_TIME         0xBE
+#define NCI_PARAM_ID_STDCONFIG          0xBF /* dont not use this config item */
+#define NCI_PARAM_ID_PROPCFG            0xC0 /* dont not use this config item  */
+#define NCI_PARAM_ID_MAXTRY2ACTIVATE    0xC1
+#define NCI_PARAM_ID_SWPCFG             0xC2
+#define NCI_PARAM_ID_CLF_LPM_CFG        0xC3
+#define NCI_PARAM_ID_DCLB               0xC4
+#define NCI_PARAM_ID_ACT_ORDER          0xC5
+#define NCI_PARAM_ID_DEP_DELAY_ACT      0xC6
+#define NCI_PARAM_ID_DH_PARITY_CRC_CTL  0xC7
+#define NCI_PARAM_ID_PREINIT_DSP_CFG    0xC8
+#define NCI_PARAM_ID_FW_WORKAROUND      0xC9
+#define NCI_PARAM_ID_RFU_CONFIG         0xCA
+#define NCI_PARAM_ID_EMVCO_ENABLE       0xCB
+#define NCI_PARAM_ID_ANTDRIVER_PARAM    0xCC
+#define NCI_PARAM_ID_PLL325_CFG_PARAM   0xCD
+#define NCI_PARAM_ID_OPNLP_ADPLL_ENABLE 0xCE
+#define NCI_PARAM_ID_CONFORMANCE_MODE   0xCF
+
+#define NCI_PARAM_ID_LPO_ON_OFF_ENABLE  0xD0
+#define NCI_PARAM_ID_FORCE_VANT         0xD1
+#define NCI_PARAM_ID_COEX_CONFIG        0xD2
+#define NCI_PARAM_ID_INTEL_MODE         0xD3
+
+#define NCI_PARAM_ID_AID                0xFF
+
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_PWR_SETTING_BITMAP    3
+#define NCI_PARAM_LEN_HOST_LISTEN_MASK      2
+#define NCI_PARAM_LEN_PLL325_CFG_PARAM      14
+
+/**********************************************
+ * Snooze Mode
+ **********************************************/
+#define NFC_SNOOZE_MODE_NONE      0x00    /* Snooze mode disabled    */
+#define NFC_SNOOZE_MODE_UART      0x01    /* Snooze mode for UART    */
+#define NFC_SNOOZE_MODE_SPI_I2C   0x08    /* Snooze mode for SPI/I2C */
+
+#define NFC_SNOOZE_ACTIVE_LOW     0x00    /* high to low voltage is asserting */
+#define NFC_SNOOZE_ACTIVE_HIGH    0x01    /* low to high voltage is asserting */
+
+#endif  /* NFC_BRCM_DEFS_H */
diff --git a/halimpl/bcm2079x/hal/int/nfc_hal_int.h b/halimpl/bcm2079x/hal/int/nfc_hal_int.h
new file mode 100644
index 0000000..ca8dc20
--- /dev/null
+++ b/halimpl/bcm2079x/hal/int/nfc_hal_int.h
@@ -0,0 +1,473 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains the NCI transport internal definitions and functions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_HAL_INT_H
+#define NFC_HAL_INT_H
+
+#include "nfc_hal_target.h"
+#include "gki.h"
+#include "nci_defs.h"
+#include "nfc_brcm_defs.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************
+** NFC HAL TASK transport definitions
+****************************************************************************/
+/* NFC HAL Task event masks */
+#define NFC_HAL_TASK_EVT_DATA_RDY               EVENT_MASK (APPL_EVT_0)
+#define NFC_HAL_TASK_EVT_INITIALIZE             EVENT_MASK (APPL_EVT_5)
+#define NFC_HAL_TASK_EVT_TERMINATE              EVENT_MASK (APPL_EVT_6)
+#define NFC_HAL_TASK_EVT_POWER_CYCLE            EVENT_MASK (APPL_EVT_7)
+
+#define NFC_HAL_TASK_EVT_MBOX                   (TASK_MBOX_0_EVT_MASK)
+
+/* NFC HAL Task mailbox definitions */
+#define NFC_HAL_TASK_MBOX                       (TASK_MBOX_0)
+
+/* NFC HAL Task Timer events */
+#ifndef NFC_HAL_QUICK_TIMER_EVT_MASK
+#define NFC_HAL_QUICK_TIMER_EVT_MASK            (TIMER_0_EVT_MASK)
+#endif
+
+#ifndef NFC_HAL_QUICK_TIMER_ID
+#define NFC_HAL_QUICK_TIMER_ID                  (TIMER_0)
+#endif
+
+/* NFC HAL Task Timer types */
+#define NFC_HAL_TTYPE_NCI_WAIT_RSP              0
+#define NFC_HAL_TTYPE_POWER_CYCLE               1
+
+/* NFC HAL Task Wait Response flag */
+#define NFC_HAL_WAIT_RSP_CMD                    0x10    /* wait response on an NCI command                  */
+#define NFC_HAL_WAIT_RSP_VSC                    0x20    /* wait response on an NCI vendor specific command  */
+#define NFC_HAL_WAIT_RSP_PROP                   0x40    /* wait response on a proprietary command           */
+#define NFC_HAL_WAIT_RSP_NONE                   0x00    /* not waiting for anything                         */
+
+typedef UINT8 tNFC_HAL_WAIT_RSP;
+
+typedef UINT16 tNFC_HAL_HCI_EVT;
+
+
+#define NFC_HAL_HCI_DH_TARGET_HANDLE            0xF2
+#define NFC_HAL_HCI_UICC0_TARGET_HANDLE         0xF3
+#define NFC_HAL_HCI_UICC1_TARGET_HANDLE         0xF4
+
+#define NFC_HAL_HCI_SESSION_ID_LEN              0x08
+#define NFC_HAL_HCI_NETWK_INFO_SIZE             184
+#define NFC_HAL_HCI_DH_NETWK_INFO_SIZE          111
+
+#define NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
+#define NFC_HAL_HCI_ADMIN_PIPE                  0x01
+#define NFC_HAL_HCI_HOST_ID_UICC0               0x02        /* Host ID for UICC 0 */
+#define NFC_HAL_HCI_HOST_ID_UICC1               0x03        /* Host ID for UICC 1 */
+#define NFC_HAL_HCI_COMMAND_TYPE                0x00
+
+/* NFC HAL transport configuration */
+typedef struct
+{
+    BOOLEAN         shared_transport;           /* TRUE if using shared HCI/NCI transport */
+    UINT8           userial_baud;
+    UINT8           userial_fc;
+} tNFC_HAL_TRANS_CFG;
+
+#ifdef TESTER
+#define NFC_HAL_TRANS_CFG_QUALIFIER               /* For Insight, ncit_cfg is runtime-configurable */
+#else
+#define NFC_HAL_TRANS_CFG_QUALIFIER   const       /* For all other platforms, ncit_cfg is constant */
+#endif
+extern NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg;
+
+/*****************************************************************************
+* BT HCI definitions
+*****************************************************************************/
+#define BT_HDR      NFC_HDR
+
+/* Tranport message type */
+#define HCIT_TYPE_COMMAND   0x01
+#define HCIT_TYPE_EVENT     0x04
+#define HCIT_TYPE_NFC       0x10
+
+/* Vendor-Specific BT HCI definitions */
+#define HCI_SUCCESS                         0x00
+#define HCI_GRP_VENDOR_SPECIFIC             (0x3F << 10)            /* 0xFC00 */
+#define HCI_BRCM_WRITE_SLEEP_MODE           (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS     (0x03 << 10)            /* 0x0C00 */
+#define HCI_RESET                           (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_COMMAND_COMPLETE_EVT            0x0E
+#define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH    12
+#define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH      0x06
+#define HCIE_PREAMBLE_SIZE                  2
+
+/****************************************************************************
+** Internal constants and definitions
+****************************************************************************/
+
+/* NFC HAL receiving states */
+enum
+{
+    NFC_HAL_RCV_IDLE_ST,            /* waiting for packet type byte             */
+    NFC_HAL_RCV_NCI_MSG_ST,         /* waiting for the first byte of NCI header */
+    NFC_HAL_RCV_NCI_HDR_ST,         /* reading NCI header                       */
+    NFC_HAL_RCV_NCI_PAYLOAD_ST,     /* reading NCI payload                      */
+    NFC_HAL_RCV_BT_MSG_ST,          /* waiting for the first byte of BT header  */
+    NFC_HAL_RCV_BT_HDR_ST,          /* reading BT HCI header                    */
+    NFC_HAL_RCV_BT_PAYLOAD_ST       /* reading BT HCI payload                   */
+};
+
+/* errors during NCI packet reassembly process */
+#define NFC_HAL_NCI_RAS_TOO_BIG             0x01
+#define NFC_HAL_NCI_RAS_ERROR               0x02
+typedef UINT8 tNFC_HAL_NCI_RAS;
+
+/* NFC HAL power mode */
+enum
+{
+    NFC_HAL_POWER_MODE_FULL,            /* NFCC is full power mode      */
+    NFC_HAL_POWER_MODE_LAST
+};
+typedef UINT8 tNFC_HAL_POWER_MODE;
+
+
+/* NFC HAL event for low power mode */
+enum
+{
+    NFC_HAL_LP_TX_DATA_EVT,                 /* DH is sending data to NFCC   */
+    NFC_HAL_LP_RX_DATA_EVT,                 /* DH received data from NFCC   */
+    NFC_HAL_LP_TIMEOUT_EVT,                 /* Timeout                      */
+    NFC_HAL_LP_LAST_EVT
+};
+typedef UINT8 tNFC_HAL_LP_EVT;
+
+#define NFC_HAL_ASSERT_NFC_WAKE      0x00   /* assert NFC_WAKE      */
+#define NFC_HAL_DEASSERT_NFC_WAKE    0x01   /* deassert NFC_WAKE    */
+
+#define NFC_HAL_BT_HCI_CMD_HDR_SIZE     3   /* opcode (2) +  length (1)    */
+#define NFC_HAL_CMD_TOUT            (2000)  /* timeout for NCI CMD (in ms) */
+
+#define NFC_HAL_SAVED_HDR_SIZE          (2)
+#define NFC_HAL_SAVED_CMD_SIZE          (2)
+
+#ifndef NFC_HAL_DEBUG
+#define NFC_HAL_DEBUG  TRUE
+#endif
+
+#if (NFC_HAL_DEBUG == TRUE)
+extern const char * const nfc_hal_init_state_str[];
+#define NFC_HAL_SET_INIT_STATE(state)  NCI_TRACE_DEBUG3 ("init state: %d->%d(%s)", nfc_hal_cb.dev_cb.initializing_state, state, nfc_hal_init_state_str[state]); nfc_hal_cb.dev_cb.initializing_state = state;
+#else
+#define NFC_HAL_SET_INIT_STATE(state)  nfc_hal_cb.dev_cb.initializing_state = state;
+#endif
+
+
+/* NFC HAL - NFCC initializing state */
+enum
+{
+    NFC_HAL_INIT_STATE_IDLE,               /* Initialization is done                */
+    NFC_HAL_INIT_STATE_W4_XTAL_SET,        /* Waiting for crystal setting rsp       */
+    NFC_HAL_INIT_STATE_W4_RESET,           /* Waiting for reset rsp                 */
+    NFC_HAL_INIT_STATE_W4_BUILD_INFO,      /* Waiting for build info rsp            */
+    NFC_HAL_INIT_STATE_W4_PATCH_INFO,      /* Waiting for patch info rsp            */
+    NFC_HAL_INIT_STATE_W4_APP_COMPLETE,    /* Waiting for complete from application */
+    NFC_HAL_INIT_STATE_W4_POST_INIT_DONE,  /* Waiting for complete of post init     */
+    NFC_HAL_INIT_STATE_W4_CONTROL_DONE,    /* Waiting for control release           */
+    NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE,/* Waiting for complete of prediscover   */
+    NFC_HAL_INIT_STATE_W4_RE_INIT,         /* Waiting for reset rsp on ReInit       */
+    NFC_HAL_INIT_STATE_CLOSING             /* Shutting down                         */
+};
+typedef UINT8 tNFC_HAL_INIT_STATE;
+
+/* NFC HAL - NFCC config items during post initialization */
+enum
+{
+    NFC_HAL_DM_CONFIG_LPTD,
+    NFC_HAL_DM_CONFIG_PLL_325,
+    NFC_HAL_DM_CONFIG_START_UP,
+    NFC_HAL_DM_CONFIG_I93_DATA_RATE,
+    NFC_HAL_DM_CONFIG_FW_FSM,
+    NFC_HAL_DM_CONFIG_START_UP_VSC,
+    NFC_HAL_DM_CONFIG_NONE
+};
+typedef UINT8 tNFC_HAL_DM_CONFIG;
+
+/* callback function prototype */
+typedef struct
+{
+    UINT16  opcode;
+    UINT16  param_len;
+    UINT8   *p_param_buf;
+} tNFC_HAL_BTVSC_CPLT;
+
+typedef void (tNFC_HAL_BTVSC_CPLT_CBACK) (tNFC_HAL_BTVSC_CPLT *p1);
+
+
+/* data type for NFC_HAL_HCI_RSP_NV_READ_EVT */
+typedef struct
+{
+    NFC_HDR           hdr;
+    UINT8             block;
+    UINT16            size;
+    tHAL_NFC_STATUS   status;
+} tNFC_HAL_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFC_HAL_HCI_RSP_NV_WRITE_EVT */
+typedef struct
+{
+    NFC_HDR           hdr;
+    tHAL_NFC_STATUS   status;
+} tNFC_HAL_HCI_RSP_NV_WRITE_EVT;
+
+
+/* union of all event data types */
+typedef union
+{
+    NFC_HDR                         hdr;
+    /* Internal events */
+    tNFC_HAL_HCI_RSP_NV_READ_EVT    nv_read;
+    tNFC_HAL_HCI_RSP_NV_WRITE_EVT   nv_write;
+} tNFC_HAL_HCI_EVENT_DATA;
+
+/*****************************************************************************
+** Control block for NFC HAL
+*****************************************************************************/
+
+/* Patch RAM Download Control block */
+
+/* PRM states */
+enum
+{
+    NFC_HAL_PRM_ST_IDLE,
+
+    /* Secure patch download stated */
+    NFC_HAL_PRM_ST_SPD_GET_VERSION,
+    NFC_HAL_PRM_ST_SPD_COMPARE_VERSION,
+    NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER,
+    NFC_HAL_PRM_ST_SPD_DOWNLOADING,
+    NFC_HAL_PRM_ST_SPD_AUTHENTICATING,
+    NFC_HAL_PRM_ST_SPD_AUTH_DONE
+};
+typedef UINT8 tNFC_HAL_PRM_STATE;
+
+/* Maximum number of patches (currently 2: LPM and FPM) */
+#define NFC_HAL_PRM_MAX_PATCH_COUNT    2
+#define NFC_HAL_PRM_PATCH_MASK_ALL     0xFFFFFFFF
+
+/* Structures for PRM Control Block */
+typedef struct
+{
+    UINT8               power_mode;
+    UINT16              len;
+} tNFC_HAL_PRM_PATCHDESC;
+
+typedef struct
+{
+    tNFC_HAL_PRM_STATE  state;                  /* download state */
+    UINT32              flags;                  /* internal flags */
+    UINT16              cur_patch_len_remaining;/* bytes remaining in patchfile to process     */
+    const UINT8*        p_cur_patch_data;       /* pointer to patch currently being downloaded */
+    UINT16              cur_patch_offset;       /* offset of next byte to process              */
+    UINT32              dest_ram;
+    TIMER_LIST_ENT      timer;                  /* Timer for patch download                    */
+
+    /* Secure Patch Download */
+    UINT32              spd_patch_needed_mask;  /* Mask of patches that need to be downloaded */
+    UINT32              spd_nvm_patch_mask;     /* Mask of patches currently in NVM */
+    UINT16              spd_project_id;         /* Current project_id of patch in nvm */
+    UINT16              spd_nvm_max_size;
+    UINT16              spd_patch_max_size;
+    UINT16              spd_fpm_patch_size;
+    UINT16              spd_lpm_patch_size;
+
+    UINT8               spd_patch_count;        /* Number of patches left to download */
+    UINT8               spd_cur_patch_idx;      /* Current patch being downloaded */
+    UINT16              spd_ver_major;          /* Current major version of patch in nvm */
+    UINT16              spd_ver_minor;          /* Current minor version of patch in nvm */
+    tNFC_HAL_PRM_PATCHDESC spd_patch_desc[NFC_HAL_PRM_MAX_PATCH_COUNT];
+
+    /* I2C-patch */
+    UINT8               *p_spd_patch;           /* pointer to spd patch             */
+    UINT16              spd_patch_len_remaining;/* patch length                     */
+    UINT16              spd_patch_offset;       /* offset of next byte to process   */
+
+    tNFC_HAL_PRM_FORMAT format;                 /* format of patch ram              */
+    tNFC_HAL_PRM_CBACK  *p_cback;               /* Callback for download status notifications */
+    UINT32              patchram_delay;         /* the dealy after patch */
+} tNFC_HAL_PRM_CB;
+
+/* Patch for I2C fix */
+typedef struct
+{
+    UINT8               *p_patch;               /* patch for i2c fix                */
+    UINT32              prei2c_delay;           /* the dealy after preI2C patch */
+    UINT16              len;                    /* i2c patch length                 */
+} tNFC_HAL_PRM_I2C_FIX_CB;
+
+/* Control block for NCI transport */
+typedef struct
+{
+    UINT8               nci_ctrl_size;      /* Max size for NCI messages                              */
+    UINT8               rcv_state;          /* current rx state                                       */
+    UINT16              rcv_len;            /* bytes remaining to be received in current rx state     */
+    NFC_HDR             *p_rcv_msg;         /* buffer to receive NCI message                          */
+    NFC_HDR             *p_frag_msg;        /* fragmented NCI message; waiting for last fragment      */
+    NFC_HDR             *p_pend_cmd;        /* pending NCI message; waiting for NFCC state to be free */
+    tNFC_HAL_NCI_RAS    nci_ras;            /* nci reassembly error status                            */
+    TIMER_LIST_ENT      nci_wait_rsp_timer; /* Timer for waiting for nci command response             */
+    tNFC_HAL_WAIT_RSP   nci_wait_rsp;       /* nci wait response flag                                 */
+    UINT8               last_hdr[NFC_HAL_SAVED_HDR_SIZE];/* part of last NCI command header           */
+    UINT8               last_cmd[NFC_HAL_SAVED_CMD_SIZE];/* part of last NCI command payload          */
+    void                *p_vsc_cback;       /* the callback function for last VSC command             */
+} tNFC_HAL_NCIT_CB;
+
+/* Control block for device initialization */
+typedef struct
+{
+    tNFC_HAL_INIT_STATE     initializing_state;     /* state of initializing NFCC               */
+
+    UINT32                  brcm_hw_id;             /* BRCM NFCC HW ID                          */
+    tNFC_HAL_DM_CONFIG      next_dm_config;         /* next config in post initialization       */
+    UINT8                   next_startup_vsc;       /* next start-up VSC offset in post init    */
+
+    tNFC_HAL_POWER_MODE     power_mode;             /* NFCC power mode                          */
+    UINT8                   snooze_mode;            /* current snooze mode                      */
+    UINT8                   new_snooze_mode;        /* next snooze mode after receiving cmpl    */
+    UINT8                   nfc_wake_active_mode;   /* NFC_HAL_LP_ACTIVE_LOW/HIGH               */
+    TIMER_LIST_ENT          lp_timer;               /* timer for low power mode                 */
+
+
+    tHAL_NFC_STATUS_CBACK   *p_prop_cback;          /* callback to notify complete of proprietary update */
+} tNFC_HAL_DEV_CB;
+
+/* data members for NFC_HAL-HCI */
+typedef struct
+{
+    TIMER_LIST_ENT          hci_timer;                /* Timer to avoid indefinitely waiting for response */
+    UINT8                   *p_hci_netwk_info_buf;    /* Buffer for reading HCI Network information */
+    UINT8                   *p_hci_netwk_dh_info_buf; /* Buffer for reading HCI Network DH information */
+    UINT8                   hci_netwk_config_block;   /* Rsp awaiting for hci network configuration block */
+    BOOLEAN                 b_wait_hcp_conn_create_rsp; /* Waiting for hcp connection create response */
+    BOOLEAN                 b_check_clear_all_pipe_cmd;
+    UINT8                   hcp_conn_id;
+} tNFC_HAL_HCI_CB;
+
+typedef struct
+{
+    tHAL_NFC_CBACK          *p_stack_cback;     /* Callback for HAL event notification  */
+    tHAL_NFC_DATA_CBACK     *p_data_cback;      /* Callback for data event notification  */
+
+    TIMER_LIST_Q            quick_timer_queue;  /* timer list queue                 */
+    TIMER_LIST_ENT          timer;              /* timer for NCI transport task     */
+
+    tNFC_HAL_NCIT_CB        ncit_cb;            /* NCI transport */
+    tNFC_HAL_DEV_CB         dev_cb;             /* device initialization */
+
+    /* Patchram control block */
+    tNFC_HAL_PRM_CB         prm;
+    tNFC_HAL_PRM_I2C_FIX_CB prm_i2c;
+
+    /* data members for NFC_HAL-HCI */
+    tNFC_HAL_HCI_CB         hci_cb;
+
+
+    tNFC_HAL_NCI_CBACK      *p_reinit_cback;
+    UINT8                   max_rf_credits;     /* NFC Max RF data credits */
+    UINT8                   trace_level;        /* NFC HAL trace level */
+} tNFC_HAL_CB;
+
+/* Global NCI data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+extern tNFC_HAL_CB   nfc_hal_cb;
+#else
+#define nfc_hal_cb (*nfc_hal_cb_ptr)
+extern tNFC_HAL_CB *nfc_hal_cb_ptr;
+#endif
+
+/****************************************************************************
+** Internal nfc functions
+****************************************************************************/
+
+/* From nfc_hal_main.c */
+UINT32 nfc_hal_main_task (UINT32 param);
+void   nfc_hal_main_init (void);
+void   nfc_hal_main_pre_init_done (tHAL_NFC_STATUS);
+void   nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+void   nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle);
+void   nfc_hal_main_send_error (tHAL_NFC_STATUS status);
+
+/* nfc_hal_nci.c */
+BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte);
+BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg);
+void    nfc_hal_nci_assemble_nci_msg (void);
+void    nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg);
+void    nfc_hal_nci_send_cmd (NFC_HDR *p_buf);
+void    nfc_hal_nci_cmd_timeout_cback (void *p_tle);
+
+/* nfc_hal_dm.c */
+void nfc_hal_dm_init (void);
+void nfc_hal_dm_set_xtal_freq_index (void);
+void nfc_hal_dm_send_reset_cmd (void);
+void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg);
+void nfc_hal_dm_config_nfcc (void);
+void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback);
+void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback);
+void nfc_hal_dm_set_nfc_wake (UINT8 cmd);
+void nfc_hal_dm_pre_init_nfcc (void);
+void nfc_hal_dm_shutting_down_nfcc (void);
+BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event);
+void nfc_hal_dm_send_pend_cmd (void);
+
+/* nfc_hal_prm.c */
+void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type);
+void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+void nfc_hal_prm_process_timeout (void *p_tle);
+
+/* nfc_hal_hci.c */
+void nfc_hal_hci_enable (void);
+void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data);
+void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data);
+void nfc_hal_hci_handle_hcp_pkt (UINT8 *p_data);
+void nfc_hal_hci_timeout_cback (void *p_tle);
+
+
+/* Define default NCI protocol trace function (if protocol tracing is enabled) */
+#if (defined(NFC_HAL_TRACE_PROTOCOL) && (NFC_HAL_TRACE_PROTOCOL == TRUE))
+#if !defined (DISP_NCI)
+#define DISP_NCI    (DispNci)
+void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+#endif  /* DISP_NCI */
+
+/* For displaying vendor-specific HCI commands */
+void DispHciCmd (BT_HDR *p_buf);
+void DispHciEvt (BT_HDR *p_buf);
+#endif /* NFC_HAL_TRACE_PROTOCOL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_H */
diff --git a/halimpl/bcm2079x/hal/int/nfc_hal_int_api.h b/halimpl/bcm2079x/hal/int/nfc_hal_int_api.h
new file mode 100644
index 0000000..5385bb4
--- /dev/null
+++ b/halimpl/bcm2079x/hal/int/nfc_hal_int_api.h
@@ -0,0 +1,293 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Internal NFC HAL API functions.
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_INT_API_H
+#define NFC_HAL_INT_API_H
+
+/****************************************************************************
+** Device Configuration definitions
+****************************************************************************/
+
+#define NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN     (2 + NCI_PARAM_LEN_PLL325_CFG_PARAM)
+
+/* Crystal Frequency Index (in 1 KHz) */
+enum
+{
+    NFC_HAL_XTAL_INDEX_9600,
+    NFC_HAL_XTAL_INDEX_13000,
+    NFC_HAL_XTAL_INDEX_16200,
+    NFC_HAL_XTAL_INDEX_19200,
+    NFC_HAL_XTAL_INDEX_24000,
+    NFC_HAL_XTAL_INDEX_26000,
+    NFC_HAL_XTAL_INDEX_38400,
+    NFC_HAL_XTAL_INDEX_52000,
+    NFC_HAL_XTAL_INDEX_37400,
+    NFC_HAL_XTAL_INDEX_MAX
+};
+typedef UINT8 tNFC_HAL_XTAL_INDEX;
+
+/* Broadcom specific device initialization before sending NCI reset */
+#define NFC_HAL_DEV_INIT_FLAGS_SET_XTAL_FREQ  0x02    /* set crystal frequency    */
+typedef UINT8 tNFC_HAL_DEV_INIT_FLAGS;
+
+typedef struct
+{
+    tNFC_HAL_DEV_INIT_FLAGS flags;
+    UINT16                  xtal_freq;
+} tNFC_HAL_DEV_INIT_CFG;
+
+/*****************************************************************************
+**  Low Power Mode definitions
+*****************************************************************************/
+
+#define NFC_HAL_LP_SNOOZE_MODE_NONE      NFC_SNOOZE_MODE_NONE       /* Snooze mode disabled    */
+#define NFC_HAL_LP_SNOOZE_MODE_UART      NFC_SNOOZE_MODE_UART       /* Snooze mode for UART    */
+#define NFC_HAL_LP_SNOOZE_MODE_SPI_I2C   NFC_SNOOZE_MODE_SPI_I2C    /* Snooze mode for SPI/I2C */
+
+#define NFC_HAL_LP_ACTIVE_LOW            NFC_SNOOZE_ACTIVE_LOW      /* high to low voltage is asserting */
+#define NFC_HAL_LP_ACTIVE_HIGH           NFC_SNOOZE_ACTIVE_HIGH     /* low to high voltage is asserting */
+
+/*****************************************************************************
+**  Patch RAM Constants
+*****************************************************************************/
+
+/* patch format type */
+#define NFC_HAL_PRM_FORMAT_BIN  0x00
+#define NFC_HAL_PRM_FORMAT_HCD  0x01
+#define NFC_HAL_PRM_FORMAT_NCD  0x02
+typedef UINT8 tNFC_HAL_PRM_FORMAT;
+
+/*****************************************************************************
+**  Patch RAM Callback for event notificaton
+*****************************************************************************/
+/* Events for tNFC_HAL_PRM_CBACK */
+enum
+{
+    NFC_HAL_PRM_CONTINUE_EVT,
+    NFC_HAL_PRM_COMPLETE_EVT,
+    NFC_HAL_PRM_ABORT_EVT,
+    NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT,       /* Patch is invalid (bad version, project id, or chip)  */
+    NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT,       /* Patch has invalid signature                          */
+    NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT,     /* Secure Patch Download: request for patchfile header  */
+    NFC_HAL_PRM_SPD_GET_NEXT_PATCH,            /* Get first command of next patch in patchfile         */
+    NFC_HAL_PRM_ABORT_NO_NVM_EVT               /* nfc_hal_prm_nvm_required is TRUE and NVM is unavail  */
+};
+
+typedef void (tNFC_HAL_PRM_CBACK) (UINT8 event);
+
+typedef UINT8 tNFC_HAL_NCI_EVT;     /* MT + Opcode */
+typedef void (tNFC_HAL_NCI_CBACK) (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreInitDone
+**
+** Description      Notify that pre-initialization of NFCC is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcReInit
+**
+** Description      This function is called to send an RESET and GET_PATCH_VERSION
+**                  command to NFCC.
+**
+**                  p_cback         - The callback function to receive the command
+**                                    status
+**
+** Note             This function should be called only during the HAL init process
+**
+** Returns          HAL_NFC_STATUS_OK if successfully initiated
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcReInit (tNFC_HAL_NCI_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetSnoozeMode
+**
+** Description      Set snooze mode
+**                  snooze_mode
+**                      NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
+**                      NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
+**                      NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
+**
+**                  idle_threshold_dh/idle_threshold_nfcc
+**                      Idle Threshold Host in 100ms unit
+**
+**                  nfc_wake_active_mode/dh_wake_active_mode
+**                      NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
+**                      NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting
+**
+**                  p_snooze_cback
+**                      Notify status of operation
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode,
+                                      UINT8 idle_threshold_dh,
+                                      UINT8 idle_threshold_nfcc,
+                                      UINT8 nfc_wake_active_mode,
+                                      UINT8 dh_wake_active_mode,
+                                      tHAL_NFC_STATUS_CBACK *p_snooze_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadStart
+**
+** Description      Initiate patch download
+**
+** Input Params
+**                  format_type     patch format type
+**                                  (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
+**                                   NFC_HAL_PRM_FORMAT_NCD)
+**
+**                  dest_address    destination adderess (needed for BIN format only)
+**
+**                  p_patchram_buf  pointer to patchram buffer. If NULL,
+**                                  then app must call HAL_NfcPrmDownloadContinue when
+**                                  NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
+**                                  segment of patchram
+**
+**                  patchram_len    size of p_patchram_buf (if non-NULL)
+**
+**                  patchram_delay  The delay after each patch.
+**                                  If the given value is less than the size of the patchram,
+**                                  the size of patchram is used instead.
+**
+**                  p_cback         callback for download status
+**
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
+                                 UINT32              dest_address,
+                                 UINT8               *p_patchram_buf,
+                                 UINT32              patchram_len,
+                                 UINT32              patchram_delay,
+                                 tNFC_HAL_PRM_CBACK  *p_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadContinue
+**
+** Description      Send next segment of patchram to controller. Called when
+**                  NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+**                  Only needed if HAL_NfcPrmDownloadStart was called with
+**                  p_patchram_buf=NULL
+**
+** Input Params     p_patch_data    pointer to patch data
+**                  patch_data_len  patch data len
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
+                                    UINT16 patch_data_len);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetI2cPatch
+**
+** Description      Specify patchfile for BCM20791B3 I2C fix. This fix
+**                  must be downloaded prior to initial patch download for I2C
+**                  transport
+**
+** Input Params     p_i2c_patchfile_buf: pointer to patch for i2c fix
+**                  i2c_patchfile_len: length of patch
+**                  prei2c_delay: the delay before downloading main patch
+**                                if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
+**
+** Returns          Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf,
+                      UINT16 i2c_patchfile_len, UINT32 prei2c_delay);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description      Set Host-to-NFCC NCI message size for secure patch download
+**
+**                  This API must be called before calling HAL_NfcPrmDownloadStart.
+**                  If the API is not called, then PRM will use the default
+**                  message size.
+**
+**                  Typically, this API is only called for platforms that have
+**                  message-size limitations in the transport/driver.
+**
+**                  Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns          HAL_NFC_STATUS_OK if successful
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetMaxRfDataCredits
+**
+** Description      This function sets the maximum RF data credit for HAL.
+**                  If 0, use the value reported from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetTraceLevel
+**
+** Description      This function sets the trace level for HAL.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 HAL_NfcSetTraceLevel (UINT8 new_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_API_H */
+
diff --git a/halimpl/bcm2079x/hal/int/nfc_hal_nv_ci.h b/halimpl/bcm2079x/hal/int/nfc_hal_nv_ci.h
new file mode 100644
index 0000000..a77c207
--- /dev/null
+++ b/halimpl/bcm2079x/hal/int/nfc_hal_nv_ci.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for non valtile memory call-in functions.
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_NV_CI_H
+#define NFC_HAL_NV_CI_H
+
+#include "nfc_hal_nv_co.h"
+
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_write
+**
+** Description      This function sends an event to NFAA indicating the phone
+**                  has written the number of bytes specified in the call-out
+**                  function, nfa_nv_co_write (), and is ready for more data.
+**                  This function is used to control the TX data flow.
+**                  Note: The data buffer is released by the stack aioer
+**                        calling this function.
+**
+** Parameters       status - NFA_NV_CO_OK, NFA_NV_CO_NOSPACE, or NFA_NV_CO_FAIL
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_write (tNFC_HAL_NV_CO_STATUS status);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_read
+**
+** Description      This function sends an event to NCIT indicating the phone has
+**                  read in the requested amount of data specified in the
+**                  nfa_nv_co_read () call-out function.  It should only be called
+**                  when the requested number of bytes has been read.
+**
+** Parameters       num_bytes_read - number of bytes read into the buffer
+**                      specified in the read callout-function.
+**                  status - NFC_HAL_NV_CO_OK if full buffer of data,
+**                           NFC_HAL_NV_CO_EOF if the end of file has been reached,
+**                           NFC_HAL_NV_CO_FAIL if an error has occurred.
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_read (UINT16                  num_bytes_read,
+                         tNFC_HAL_NV_CO_STATUS   status,
+                         UINT8                   block);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_NV_CI_H */
+
diff --git a/halimpl/bcm2079x/hal/int/nfc_hal_nv_co.h b/halimpl/bcm2079x/hal/int/nfc_hal_nv_co.h
new file mode 100644
index 0000000..2264cfe
--- /dev/null
+++ b/halimpl/bcm2079x/hal/int/nfc_hal_nv_co.h
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for storing nv data
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_NV_CO_H
+#define NFC_HAL_NV_CO_H
+
+#include <time.h>
+
+
+/*****************************************************************************
+**  Constants and Data Types
+*****************************************************************************/
+
+
+/**************************
+**  Common Definitions
+***************************/
+
+/* Status codes returned by call-out functions, or in call-in functions as status */
+#define NFC_HAL_NV_CO_OK            0x00
+#define NFC_HAL_NV_CO_FAIL          0x01 /* Used to pass all other errors */
+#define NFC_HAL_NV_CO_EACCES        0x02
+#define NFC_HAL_NV_CO_ENOTEMPTY     0x03
+#define NFC_HAL_NV_CO_EOF           0x04
+#define NFC_HAL_NV_CO_EODIR         0x05
+#define NFC_HAL_NV_CO_ENOSPACE      0x06 /* Returned in nfa_nv_ci_open if no room */
+#define NFC_HAL_NV_CO_EIS_DIR       0x07
+#define NFC_HAL_NV_CO_RESUME        0x08 /* used in nfa_nv_ci_open, on resume */
+#define NFC_HAL_NV_CO_NONE          0x09 /* used in nfa_nv_ci_open, on resume (no file to resume) */
+
+typedef UINT8 tNFC_HAL_NV_CO_STATUS;
+
+#define  DH_NV_BLOCK            0x01
+#define  HC_F3_NV_BLOCK         0x02
+#define  HC_F4_NV_BLOCK         0x03
+#define  HC_DH_NV_BLOCK         0x04
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+/**************************
+**  Common Functions
+***************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been read, the end of file has been detected,
+**                        or an error has occurred.
+**
+*******************************************************************************/
+void nfc_hal_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write () is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+
+#endif /* NFC_HAL_NV_CO_H */
diff --git a/halimpl/bcm2079x/hal/int/nfc_hal_post_reset.h b/halimpl/bcm2079x/hal/int/nfc_hal_post_reset.h
new file mode 100644
index 0000000..95da455
--- /dev/null
+++ b/halimpl/bcm2079x/hal/int/nfc_hal_post_reset.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Post NCI reset routines
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_POST_RESET_H
+#define NFC_HAL_POST_RESET_H
+
+
+/*****************************************************************************
+** Application control block definitions
+******************************************************************************/
+#define NFA_APP_PATCHFILE_MAX_PATH          255
+
+typedef struct
+{
+    UINT8 prm_file[NFA_APP_PATCHFILE_MAX_PATH+1];   /* Filename of patchram */
+    UINT8 *p_prm_buf;                               /* Pointer to buffer for holding patchram data */
+
+    /* Patchfile for I2C fix */
+    UINT8 prm_i2c_patchfile[NFA_APP_PATCHFILE_MAX_PATH+1];
+    UINT8 *p_prm_i2c_buf;
+
+    UINT8 userial_baud;
+
+    tNFC_HAL_DEV_INIT_CFG dev_init_config;
+
+    /* snooze mode setting */
+    UINT8 snooze_mode;
+    UINT8 idle_threshold_dh;
+    UINT8 idle_threshold_nfcc;
+    UINT8 nfc_wake_active_mode;
+    UINT8 dh_wake_active_mode;
+
+} tNFC_POST_RESET_CB;
+extern tNFC_POST_RESET_CB nfc_post_reset_cb;
+
+/*
+** Post NCI reset handler
+**
+** This function is called to start device pre-initialization after NCI CORE-RESET.
+** When pre-initialization is completed,
+** HAL_NfcPreInitDone() must be called to proceed with stack start up.
+*/
+void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type);
+
+
+#endif  /* NFC_HAL_POST_RESET_H */
diff --git a/halimpl/bcm2079x/include/HalAdaptation.h b/halimpl/bcm2079x/include/HalAdaptation.h
new file mode 100644
index 0000000..16daa41
--- /dev/null
+++ b/halimpl/bcm2079x/include/HalAdaptation.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  HAL Adaptation Interface (HAI). This interface regulates the interaction
+ *  between standard Android HAL and Broadcom-specific HAL.  It adapts
+ *  Broadcom-specific features to the Android framework.
+ *
+ ******************************************************************************/
+#pragma once
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+    struct nfc_nci_device nci_device;
+    //below declarations are private variables within Broadcom HAL
+    void* data;
+}
+bcm2079x_dev_t;
+
+
+/*
+All functions return POSIX error codes (see errno):
+  0 means success.
+  non-zero means failure; for example EACCES.
+*/
+
+
+extern int HaiInitializeLibrary (const bcm2079x_dev_t* device);
+extern int HaiTerminateLibrary ();
+extern int HaiOpen (const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc, nfc_stack_data_callback_t* halDataCallbackFunc);
+extern int HaiClose (const bcm2079x_dev_t* device);
+extern int HaiCoreInitialized (const bcm2079x_dev_t* device, uint8_t* coreInitResponseParams);
+extern int HaiWrite (const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data);
+extern int HaiPreDiscover (const bcm2079x_dev_t* device);
+extern int HaiControlGranted (const bcm2079x_dev_t* device);
+extern int HaiPowerCycle (const bcm2079x_dev_t* device);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/OverrideLog.h b/halimpl/bcm2079x/include/OverrideLog.h
new file mode 100644
index 0000000..523f331
--- /dev/null
+++ b/halimpl/bcm2079x/include/OverrideLog.h
@@ -0,0 +1,68 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the Android logging macro(s) from
+ *  /system/core/include/cutils/log.h. This header must be the first header
+ *  included by a *.cpp file so the original Android macro can be replaced.
+ *  Do not include this header in another header, because that will create
+ *  unnecessary dependency.
+ *
+ ******************************************************************************/
+#pragma once
+
+//Override Android's ALOGD macro by adding a boolean expression.
+#define ALOGD(...) ((void)ALOGD_IF(appl_trace_level>=BT_TRACE_LEVEL_DEBUG, __VA_ARGS__))
+
+
+#include <cutils/log.h> //define Android logging macros
+#include "bt_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern unsigned char appl_trace_level;
+
+
+/*******************************************************************************
+**
+** Function:        InitializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from .conf or
+**                  Android property nfc.app_log_level.  The Android property
+**                  overrides .conf variable.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3        * API traces
+**                  BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char InitializeGlobalAppLogLevel ();
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/bcm2079x.h b/halimpl/bcm2079x/include/bcm2079x.h
new file mode 100644
index 0000000..7bf095d
--- /dev/null
+++ b/halimpl/bcm2079x/include/bcm2079x.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 _BCM2079X_H
+#define _BCM2079X_H
+
+#define BCMNFC_MAGIC	0xFA
+
+/*
+ * BCMNFC power control via ioctl
+ * BCMNFC_POWER_CTL(0): power off
+ * BCMNFC_POWER_CTL(1): power on
+ * BCMNFC_WAKE_CTL(0): wake off
+ * BCMNFC_WAKE_CTL(1): wake on
+ */
+#define BCMNFC_POWER_CTL		_IO(BCMNFC_MAGIC, 0x01)
+#define BCMNFC_CHANGE_ADDR		_IO(BCMNFC_MAGIC, 0x02)
+#define BCMNFC_READ_FULL_PACKET		_IO(BCMNFC_MAGIC, 0x03)
+#define BCMNFC_SET_WAKE_ACTIVE_STATE	_IO(BCMNFC_MAGIC, 0x04)
+#define BCMNFC_WAKE_CTL			_IO(BCMNFC_MAGIC, 0x05)
+#define BCMNFC_READ_MULTI_PACKETS	_IO(BCMNFC_MAGIC, 0x06)
+
+struct bcm2079x_platform_data {
+	unsigned int irq_gpio;
+	unsigned int en_gpio;
+	int wake_gpio;
+};
+
+#endif
diff --git a/halimpl/bcm2079x/include/bt_trace.h b/halimpl/bcm2079x/include/bt_trace.h
new file mode 100644
index 0000000..d9c58dd
--- /dev/null
+++ b/halimpl/bcm2079x/include/bt_trace.h
@@ -0,0 +1,4837 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 BT_TRACE_H
+#define BT_TRACE_H
+
+#ifndef BTTRC_INCLUDED
+#define BTTRC_INCLUDED  FALSE
+#endif
+#ifndef BTTRC_PARSER_INCLUDED
+#define BTTRC_PARSER_INCLUDED FALSE
+#endif
+#ifndef MAX_TRACE_RAM_SIZE
+#define MAX_TRACE_RAM_SIZE 10000
+#endif
+
+/* BTE tracing IDs for debug purposes */
+/* LayerIDs for stack */
+#define BTTRC_ID_STK_GKI                   1
+#define BTTRC_ID_STK_BTU                   2
+#define BTTRC_ID_STK_HCI                   3
+#define BTTRC_ID_STK_L2CAP                 4
+#define BTTRC_ID_STK_RFCM_MX               5
+#define BTTRC_ID_STK_RFCM_PRT              6
+#define BTTRC_ID_STK_OBEX_C                7
+#define BTTRC_ID_STK_OBEX_S                8
+#define BTTRC_ID_STK_AVCT                  9
+#define BTTRC_ID_STK_AVDT                  10
+#define BTTRC_ID_STK_AVRC                  11
+#define BTTRC_ID_STK_BIC                   12
+#define BTTRC_ID_STK_BIS                   13
+#define BTTRC_ID_STK_BNEP                  14
+#define BTTRC_ID_STK_BPP                   15
+#define BTTRC_ID_STK_BTM_ACL               16
+#define BTTRC_ID_STK_BTM_PM                17
+#define BTTRC_ID_STK_BTM_DEV_CTRL          18
+#define BTTRC_ID_STK_BTM_SVC_DSC           19
+#define BTTRC_ID_STK_BTM_INQ               20
+#define BTTRC_ID_STK_BTM_SCO               21
+#define BTTRC_ID_STK_BTM_SEC               22
+#define BTTRC_ID_STK_DUN                   23
+#define BTTRC_ID_STK_HID                   24
+#define BTTRC_ID_STK_HSP2                  25
+#define BTTRC_ID_STK_CTP                   26
+#define BTTRC_ID_STK_FTC                   27
+#define BTTRC_ID_STK_FTS                   28
+#define BTTRC_ID_STK_GAP                   29
+#define BTTRC_ID_STK_GOEP                  30
+#define BTTRC_ID_STK_HCRP                  31
+#define BTTRC_ID_STK_ICP                   32
+#define BTTRC_ID_STK_OPC                   33
+#define BTTRC_ID_STK_OPS                   34
+#define BTTRC_ID_STK_PAN                   35
+#define BTTRC_ID_STK_SAP                   36
+#define BTTRC_ID_STK_SDP                   37
+#define BTTRC_ID_STK_SLIP                  38
+#define BTTRC_ID_STK_SPP                   39
+#define BTTRC_ID_STK_TCS                   40
+#define BTTRC_ID_STK_VDP                   41
+#define BTTRC_ID_STK_AMP                   42
+#define BTTRC_ID_STK_MCAP                  43
+#define BTTRC_ID_STK_GATT                  44
+#define BTTRC_ID_STK_SMP                   45
+#define BTTRC_ID_STK_NFC                   46
+#define BTTRC_ID_STK_NCI                   47
+#define BTTRC_ID_STK_IDEP                  48
+#define BTTRC_ID_STK_NDEP                  49
+#define BTTRC_ID_STK_LLCP                  50
+#define BTTRC_ID_STK_RW                    51
+#define BTTRC_ID_STK_CE                    52
+#define BTTRC_ID_STK_SNEP                  53
+#define BTTRC_ID_STK_NDEF                  54
+
+
+/* LayerIDs for BTA */
+#define BTTRC_ID_BTA_ACC                   55         /* Advanced Camera Client */
+#define BTTRC_ID_BTA_AG                    56         /* audio gateway */
+#define BTTRC_ID_BTA_AV                    57         /* Advanced audio */
+#define BTTRC_ID_BTA_BIC                   58         /* Basic Imaging Client */
+#define BTTRC_ID_BTA_BIS                   59         /* Basic Imaging Server */
+#define BTTRC_ID_BTA_BP                    60         /* Basic Printing Client */
+#define BTTRC_ID_BTA_CG                    61
+#define BTTRC_ID_BTA_CT                    62         /* cordless telephony terminal */
+#define BTTRC_ID_BTA_DG                    63         /* data gateway */
+#define BTTRC_ID_BTA_DM                    64         /* device manager */
+#define BTTRC_ID_BTA_DM_SRCH               65         /* device manager search */
+#define BTTRC_ID_BTA_DM_SEC                66         /* device manager security */
+#define BTTRC_ID_BTA_FM                    67
+#define BTTRC_ID_BTA_FTC                   68         /* file transfer client */
+#define BTTRC_ID_BTA_FTS                   69         /* file transfer server */
+#define BTTRC_ID_BTA_HIDH                  70
+#define BTTRC_ID_BTA_HIDD                  71
+#define BTTRC_ID_BTA_JV                    72
+#define BTTRC_ID_BTA_OPC                   73         /* object push client */
+#define BTTRC_ID_BTA_OPS                   74         /* object push server */
+#define BTTRC_ID_BTA_PAN                   75         /* Personal Area Networking */
+#define BTTRC_ID_BTA_PR                    76         /* Printer client */
+#define BTTRC_ID_BTA_SC                    77         /* SIM Card Access server */
+#define BTTRC_ID_BTA_SS                    78         /* synchronization server */
+#define BTTRC_ID_BTA_SYS                   79         /* system manager */
+#define BTTRC_ID_AVDT_SCB                  80         /* avdt scb */
+#define BTTRC_ID_AVDT_CCB                  81         /* avdt ccb */
+
+/* LayerIDs for BT APP */
+#define BTTRC_ID_BTAPP                     82
+#define BTTRC_ID_MAX_ID                    BTTRC_ID_BTAPP
+#define BTTRC_ID_ALL_LAYERS                0xFF       /* all trace layers */
+typedef UINT8 tBTTRC_LAYER_ID;
+
+/* Trace type definitions. Note that these are mutually exclusive in a trace. This
+means that any trace can be either error,warning,api,event or dbg */
+#if (BTU_STACK_LITE_ENABLED == TRUE)
+#define BTTRC_TYPE_ERROR                   0x81
+#define BTTRC_TYPE_WARNING                 0x82
+#define BTTRC_TYPE_API                     0x84
+#define BTTRC_TYPE_EVENT                   0x88
+#define BTTRC_TYPE_ACTION                  0x90
+#define BTTRC_TYPE_DBG                     0xA0
+#else
+#define BTTRC_TYPE_ERROR                   0x01       /* Traces for error situation */
+#define BTTRC_TYPE_WARNING	               0x02       /* Traces for warning situation */
+#define BTTRC_TYPE_API                     0x04       /* Traces for API */
+#define BTTRC_TYPE_EVENT                   0x08       /* Traces for EVENT */
+#define BTTRC_TYPE_ACTION                  0x10       /* Traces for Action functions */
+#define BTTRC_TYPE_DBG                     0x20       /* Traces for debugging purpose */
+#endif
+typedef UINT8 tBTTRC_TYPE;
+
+/* Masks to identify the stack that originated the trace */
+#define BTTRC_TRACE_LITE                   0x80       /* MM Lite stack */
+#define BTTRC_TRACE_EMBD                   0x40       /* Embedded host stack */
+
+/* Parameter datatypes used in Trace APIs */
+#define BTTRC_PARAM_UINT8                  1
+#define BTTRC_PARAM_UINT16                 2
+#define BTTRC_PARAM_UINT32                 3
+typedef UINT8 tBTTRC_PARAM_TYPE;
+
+/* Special token definitions */
+#define BTTRC_TOKEN_SM_STATE               0xFFFF     /* Token indicating the State of a State m/c */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* External declaration for appl_trace_level here to avoid to add the declaration in all the files using APPL_TRACExxx macros */
+extern UINT8 appl_trace_level ;
+
+/* Prototype for message logging function. */
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+extern void LogMsg_0 (UINT32 trace_set_mask, const char *p_str);
+extern void LogMsg_1 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1);
+extern void LogMsg_2 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2);
+extern void LogMsg_3 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3);
+extern void LogMsg_4 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3, UINT32 p4);
+extern void LogMsg_5 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3, UINT32 p4, UINT32 p5);
+extern void LogMsg_6 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6);
+
+/* Prototype for stack tracing function. */
+EXPORT_API extern void BTTRC_StackTrace0(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token);
+EXPORT_API extern void BTTRC_StackTrace1(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val);
+EXPORT_API extern void BTTRC_StackTrace2(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val);
+EXPORT_API extern void BTTRC_StackTrace3(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val);
+EXPORT_API extern void BTTRC_StackTrace4(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+                                   tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val);
+EXPORT_API extern void BTTRC_StackTrace5(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+                                   tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val,
+                                   tBTTRC_PARAM_TYPE p5_type, UINT32 p5_val);
+EXPORT_API extern void BTTRC_StackTrace6(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+                                   tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val,
+                                   tBTTRC_PARAM_TYPE p5_type, UINT32 p5_val,
+                                   tBTTRC_PARAM_TYPE p6_type, UINT32 p6_val);
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************************
+**
+** Trace configurable parameters
+**
+******************************************************************************/
+
+/* Enables or disables verbose trace information. */
+#ifndef BT_TRACE_VERBOSE
+#define BT_TRACE_VERBOSE    FALSE
+#endif
+
+/* Enables or disables all trace messages. */
+#ifndef BT_USE_TRACES
+#define BT_USE_TRACES       TRUE
+#endif
+
+/* Enables or disables protocol trace information. */
+#ifndef BT_TRACE_PROTOCOL
+#define BT_TRACE_PROTOCOL   TRUE  /* Android requires TRUE */
+#endif
+
+/******************************************************************************
+**
+** Trace Levels
+**
+** The following values may be used for different levels:
+**      BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**      BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**      BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**      BT_TRACE_LEVEL_API     3        * API traces
+**      BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**      BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+******************************************************************************/
+
+/* Core Stack default trace levels */
+#ifndef HCI_INITIAL_TRACE_LEVEL
+#define HCI_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BTM_INITIAL_TRACE_LEVEL
+#define BTM_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef L2CAP_INITIAL_TRACE_LEVEL
+#define L2CAP_INITIAL_TRACE_LEVEL           BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef LLCP_INITIAL_TRACE_LEVEL
+#define LLCP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AMP_INITIAL_TRACE_LEVEL
+#define AMP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef RFCOMM_INITIAL_TRACE_LEVEL
+#define RFCOMM_INITIAL_TRACE_LEVEL          BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef OBX_INITIAL_TRACE_LEVEL
+#define OBX_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SDP_INITIAL_TRACE_LEVEL
+#define SDP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef TCS_INITIAL_TRACE_LEVEL
+#define TCS_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+/* Profile default trace levels */
+#ifndef DUN_INITIAL_TRACE_LEVEL
+#define DUN_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GAP_INITIAL_TRACE_LEVEL
+#define GAP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GOEP_INITIAL_TRACE_LEVEL
+#define GOEP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HSP2_INITIAL_TRACE_LEVEL
+#define HSP2_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SPP_INITIAL_TRACE_LEVEL
+#define SPP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef ICP_INITIAL_TRACE_LEVEL
+#define ICP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef CTP_INITIAL_TRACE_LEVEL
+#define CTP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HCRP_INITIAL_TRACE_LEVEL
+#define HCRP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HCRPM_INITIAL_TRACE_LEVEL
+#define HCRPM_INITIAL_TRACE_LEVEL           BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BPP_INITIAL_TRACE_LEVEL
+#define BPP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BIP_INITIAL_TRACE_LEVEL
+#define BIP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BNEP_INITIAL_TRACE_LEVEL
+#define BNEP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef PAN_INITIAL_TRACE_LEVEL
+#define PAN_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SAP_INITIAL_TRACE_LEVEL
+#define SAP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef FTP_INITIAL_TRACE_LEVEL
+#define FTP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef OPP_INITIAL_TRACE_LEVEL
+#define OPP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HFP_INITIAL_TRACE_LEVEL
+#define HFP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef A2D_INITIAL_TRACE_LEVEL
+#define A2D_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef VDP_INITIAL_TRACE_LEVEL
+#define VDP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVDT_INITIAL_TRACE_LEVEL
+#define AVDT_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVCT_INITIAL_TRACE_LEVEL
+#define AVCT_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVRC_INITIAL_TRACE_LEVEL
+#define AVRC_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef MCA_INITIAL_TRACE_LEVEL
+#define MCA_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HID_INITIAL_TRACE_LEVEL
+#define HID_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+/* Application and other default trace levels */
+#ifndef RPC_INITIAL_TRACE_LEVEL
+#define RPC_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef APPL_INITIAL_TRACE_LEVEL
+#define APPL_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BT_TRACE_APPL
+#define BT_TRACE_APPL   BT_USE_TRACES
+#endif
+
+#ifndef NFC_INITIAL_TRACE_LEVEL
+#define NFC_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GATT_INITIAL_TRACE_LEVEL
+#define GATT_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SMP_INITIAL_TRACE_LEVEL
+#define SMP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+
+#if (BTTRC_INCLUDED == TRUE)
+/***************************************************************************************/
+/* BTTRC MACROS */
+
+#define BTTRC_EVENT(lid, event, state)   \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_EVENT, event, BTTRC_PARAM_UINT8, state);}
+#define BTTRC_ACTION(lid, action)  \
+            {BTTRC_StackTrace0(lid, BTTRC_TYPE_ACTION, action);}
+#define BTTRC_STATE(lid, state)   \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_EVENT, BTTRC_TOKEN_SM_STATE, BTTRC_PARAM_UINT8, state);}
+
+#define BTTRC_API0(lid, api)  \
+            {BTTRC_StackTrace0(lid, BTTRC_TYPE_API, api);}
+#define BTTRC_API1(lid, api, p1_t,p1_v)  \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_API, api, p1_t,p1_v);}
+#define BTTRC_API2(lid, api, p1_t,p1_v,p2_t,p2_v)  \
+            {BTTRC_StackTrace2(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v);}
+#define BTTRC_API3(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            {BTTRC_StackTrace3(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v);}
+#define BTTRC_API4(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            {BTTRC_StackTrace4(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v);}
+#define BTTRC_API5(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            {BTTRC_StackTrace5(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v);}
+#define BTTRC_API6(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            {BTTRC_StackTrace6(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v);}
+
+
+#define BTTRC_DBG0(lid, dbg)  \
+            {BTTRC_StackTrace0(lid, BTTRC_TYPE_DBG, dbg);}
+#define BTTRC_DBG1(lid, dbg, p1_t,p1_v)  \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v);}
+#define BTTRC_DBG2(lid, dbg, p1_t,p1_v,p2_t,p2_v)  \
+            {BTTRC_StackTrace2(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v);}
+#define BTTRC_DBG3(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            {BTTRC_StackTrace3(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v);}
+#define BTTRC_DBG4(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            {BTTRC_StackTrace4(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v);}
+#define BTTRC_DBG5(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            {BTTRC_StackTrace5(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v);}
+#define BTTRC_DBG6(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            {BTTRC_StackTrace6(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v);}
+
+/***************************************************************************************/
+/*AVDT MACROS */
+
+#define BTTRC_AVDT_API0(api)   \
+        BTTRC_API0(BTTRC_ID_STK_AVDT, api)
+#define BTTRC_AVDT_API1(api, p1_t, p1_v) \
+        BTTRC_API1(BTTRC_ID_STK_AVDT, api, p1_t, p1_v)
+#define BTTRC_AVDT_API2(api, p1_t, p1_v, p2_t, p2_v) \
+        BTTRC_API2(BTTRC_ID_STK_AVDT, api, p1_t, p1_v, p2_t, p2_v)
+/***************************************************************************************/
+/*AVDT_SCB MACROS */
+
+#define BTTRC_AVDT_SCB_EVENT(event, state)   \
+            BTTRC_EVENT(BTTRC_ID_AVDT_SCB, event, state)
+#define BTTRC_AVDT_SCB_ACTION(action)  \
+            BTTRC_ACTION(BTTRC_ID_AVDT_SCB, action)
+#define BTTRC_AVDT_SCB_STATE(next_state)   \
+            BTTRC_STATE(BTTRC_ID_AVDT_SCB, next_state)
+
+#define BTTRC_AVDT_SCB_DBG0(dbg)  \
+            BTTRC_DBG0(BTTRC_ID_AVDT_SCB, dbg)
+#define BTTRC_AVDT_SCB_DBG1(dbg, p1_t,p1_v)  \
+            BTTRC_DBG1(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v)
+#define BTTRC_AVDT_SCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)  \
+            BTTRC_DBG2(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_SCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            BTTRC_DBG3(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_SCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            BTTRC_DBG4(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_SCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            BTTRC_DBG5(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_SCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            BTTRC_DBG6(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+/***************************************************************************************/
+/*AVDT_CCB MACROS */
+
+#define BTTRC_AVDT_CCB_EVENT(event, state)   \
+            BTTRC_EVENT(BTTRC_ID_AVDT_CCB, event, state)
+#define BTTRC_AVDT_CCB_ACTION(action)  \
+            BTTRC_ACTION(BTTRC_ID_AVDT_CCB, action)
+#define BTTRC_AVDT_CCB_STATE(next_state)   \
+            BTTRC_STATE(BTTRC_ID_AVDT_CCB, next_state)
+
+#define BTTRC_AVDT_CCB_DBG0(dbg)  \
+            BTTRC_DBG0(BTTRC_ID_AVDT_CCB, dbg)
+#define BTTRC_AVDT_CCB_DBG1(dbg, p1_t,p1_v)  \
+            BTTRC_DBG1(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v)
+#define BTTRC_AVDT_CCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)  \
+            BTTRC_DBG2(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_CCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            BTTRC_DBG3(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_CCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            BTTRC_DBG4(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_CCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            BTTRC_DBG5(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_CCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            BTTRC_DBG6(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+/***************************************************************************************/
+
+#else /*BTTRC_INCLUDED*/
+
+/***************************************************************************************/
+/* BTTRC MACROS */
+
+#define BTTRC_EVENT(lid, event, state)
+#define BTTRC_ACTION(lid, action)
+#define BTTRC_STATE(lid, state)
+
+#define BTTRC_API0(lid, api)
+#define BTTRC_API1(lid, api, p1_t, p1_v)
+#define BTTRC_API2(lid, api, p1_t, p1_v, p2_t, p2_v)
+#define BTTRC_API3(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_API4(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_API5(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_API6(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+
+#define BTTRC_DBG0(lid, dbg)
+#define BTTRC_DBG1(lid, dbg, p1_t,p1_v)
+#define BTTRC_DBG2(lid, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_DBG3(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_DBG4(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_DBG5(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_DBG6(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+/*AVDT MACROS */
+#define BTTRC_AVDT_API0(api)
+#define BTTRC_AVDT_API1(api, p1_t,p1_v)
+#define BTTRC_AVDT_API2(api, p1_t,p1_v,p2_t,p2_v)
+/***************************************************************************************/
+/*AVDT_SCB MACROS */
+
+#define BTTRC_AVDT_SCB_EVENT(event, state)
+#define BTTRC_AVDT_SCB_ACTION(action)
+#define BTTRC_AVDT_SCB_STATE(next_state)
+
+#define BTTRC_AVDT_SCB_DBG0(dbg)
+#define BTTRC_AVDT_SCB_DBG1(dbg, p1_t,p1_v)
+#define BTTRC_AVDT_SCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_SCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_SCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_SCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_SCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+/*AVDT_CCB MACROS */
+
+#define BTTRC_AVDT_CCB_EVENT(event, state)
+#define BTTRC_AVDT_CCB_ACTION(action)
+#define BTTRC_AVDT_CCB_STATE(next_state)
+
+#define BTTRC_AVDT_CCB_DBG0(dbg)
+#define BTTRC_AVDT_CCB_DBG1(dbg, p1_t,p1_v)
+#define BTTRC_AVDT_CCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_CCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_CCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_CCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_CCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+
+#endif /*BTTRC_INCLUDED*/
+
+
+#if (BT_USE_TRACES == TRUE)
+
+#define BT_TRACE_0(l,t,m)                           LogMsg_0((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)),(m))
+#define BT_TRACE_1(l,t,m,p1)                        LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1))
+#define BT_TRACE_2(l,t,m,p1,p2)                     LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2))
+#define BT_TRACE_3(l,t,m,p1,p2,p3)                  LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3))
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)               LogMsg_4(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4))
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)            LogMsg_5(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5))
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)         LogMsg_6(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5),(UINT32)(p6))
+
+#define BT_ERROR_TRACE_0(l,m)                     LogMsg_0(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m))
+#define BT_ERROR_TRACE_1(l,m,p1)                  LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1))
+#define BT_ERROR_TRACE_2(l,m,p1,p2)               LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1),(UINT32)(p2))
+#define BT_ERROR_TRACE_3(l,m,p1,p2,p3)            LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1),(UINT32)(p2),(UINT32)(p3))
+
+/* Define tracing for the HCI unit
+*/
+#define HCI_TRACE_ERROR0(m)                     {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m);}
+#define HCI_TRACE_ERROR1(m,p1)                  {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1);}
+#define HCI_TRACE_ERROR2(m,p1,p2)               {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCI_TRACE_ERROR3(m,p1,p2,p3)            {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCI_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_WARNING0(m)                   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m);}
+#define HCI_TRACE_WARNING1(m,p1)                {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1);}
+#define HCI_TRACE_WARNING2(m,p1,p2)             {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCI_TRACE_WARNING3(m,p1,p2,p3)          {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCI_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_EVENT0(m)                     {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m);}
+#define HCI_TRACE_EVENT1(m,p1)                  {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m, p1);}
+#define HCI_TRACE_EVENT2(m,p1,p2)               {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCI_TRACE_EVENT3(m,p1,p2,p3)            {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCI_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_DEBUG0(m)                     {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m);}
+#define HCI_TRACE_DEBUG1(m,p1)                  {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1);}
+#define HCI_TRACE_DEBUG2(m,p1,p2)               {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCI_TRACE_DEBUG3(m,p1,p2,p3)            {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCI_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for BTM
+*/
+#define BTM_TRACE_ERROR0(m)                     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m);}
+#define BTM_TRACE_ERROR1(m,p1)                  {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1);}
+#define BTM_TRACE_ERROR2(m,p1,p2)               {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BTM_TRACE_ERROR3(m,p1,p2,p3)            {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BTM_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BTM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_WARNING0(m)                   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m);}
+#define BTM_TRACE_WARNING1(m,p1)                {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1);}
+#define BTM_TRACE_WARNING2(m,p1,p2)             {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BTM_TRACE_WARNING3(m,p1,p2,p3)          {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BTM_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BTM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_API0(m)                       {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_API, m);}
+#define BTM_TRACE_API1(m,p1)                    {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_API, m, p1);}
+#define BTM_TRACE_API2(m,p1,p2)                 {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2);}
+#define BTM_TRACE_API3(m,p1,p2,p3)              {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BTM_TRACE_API4(m,p1,p2,p3,p4)           {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BTM_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_EVENT0(m)                     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m);}
+#define BTM_TRACE_EVENT1(m,p1)                  {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m, p1);}
+#define BTM_TRACE_EVENT2(m,p1,p2)               {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BTM_TRACE_EVENT3(m,p1,p2,p3)            {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BTM_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BTM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_DEBUG0(m)                     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m);}
+#define BTM_TRACE_DEBUG1(m,p1)                  {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1);}
+#define BTM_TRACE_DEBUG2(m,p1,p2)               {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BTM_TRACE_DEBUG3(m,p1,p2,p3)            {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BTM_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BTM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the L2CAP unit
+*/
+#define L2CAP_TRACE_ERROR0(m)                     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m);}
+#define L2CAP_TRACE_ERROR1(m,p1)                  {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1);}
+#define L2CAP_TRACE_ERROR2(m,p1,p2)               {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define L2CAP_TRACE_ERROR3(m,p1,p2,p3)            {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define L2CAP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_WARNING0(m)                   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m);}
+#define L2CAP_TRACE_WARNING1(m,p1)                {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1);}
+#define L2CAP_TRACE_WARNING2(m,p1,p2)             {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define L2CAP_TRACE_WARNING3(m,p1,p2,p3)          {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define L2CAP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_API0(m)                       {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m);}
+#define L2CAP_TRACE_API1(m,p1)                    {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1);}
+#define L2CAP_TRACE_API2(m,p1,p2)                 {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2);}
+#define L2CAP_TRACE_API3(m,p1,p2,p3)              {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define L2CAP_TRACE_API4(m,p1,p2,p3,p4)           {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_EVENT0(m)                     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m);}
+#define L2CAP_TRACE_EVENT1(m,p1)                  {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m, p1);}
+#define L2CAP_TRACE_EVENT2(m,p1,p2)               {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define L2CAP_TRACE_EVENT3(m,p1,p2,p3)            {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define L2CAP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_DEBUG0(m)                     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m);}
+#define L2CAP_TRACE_DEBUG1(m,p1)                  {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1);}
+#define L2CAP_TRACE_DEBUG2(m,p1,p2)               {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define L2CAP_TRACE_DEBUG3(m,p1,p2,p3)            {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define L2CAP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m)                     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m);}
+#define LLCP_TRACE_ERROR1(m,p1)                  {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1);}
+#define LLCP_TRACE_ERROR2(m,p1,p2)               {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LLCP_TRACE_ERROR3(m,p1,p2,p3)            {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LLCP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_WARNING0(m)                   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m);}
+#define LLCP_TRACE_WARNING1(m,p1)                {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1);}
+#define LLCP_TRACE_WARNING2(m,p1,p2)             {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LLCP_TRACE_WARNING3(m,p1,p2,p3)          {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LLCP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_API0(m)                       {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_API, m);}
+#define LLCP_TRACE_API1(m,p1)                    {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1);}
+#define LLCP_TRACE_API2(m,p1,p2)                 {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2);}
+#define LLCP_TRACE_API3(m,p1,p2,p3)              {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define LLCP_TRACE_API4(m,p1,p2,p3,p4)           {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_EVENT0(m)                     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m);}
+#define LLCP_TRACE_EVENT1(m,p1)                  {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1);}
+#define LLCP_TRACE_EVENT2(m,p1,p2)               {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LLCP_TRACE_EVENT3(m,p1,p2,p3)            {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LLCP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_DEBUG0(m)                     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m);}
+#define LLCP_TRACE_DEBUG1(m,p1)                  {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1);}
+#define LLCP_TRACE_DEBUG2(m,p1,p2)               {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LLCP_TRACE_DEBUG3(m,p1,p2,p3)            {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LLCP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the SDP unit
+*/
+#define SDP_TRACE_ERROR0(m)                     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m);}
+#define SDP_TRACE_ERROR1(m,p1)                  {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1);}
+#define SDP_TRACE_ERROR2(m,p1,p2)               {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SDP_TRACE_ERROR3(m,p1,p2,p3)            {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SDP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_WARNING0(m)                   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m);}
+#define SDP_TRACE_WARNING1(m,p1)                {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1);}
+#define SDP_TRACE_WARNING2(m,p1,p2)             {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SDP_TRACE_WARNING3(m,p1,p2,p3)          {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SDP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_API0(m)                       {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_API, m);}
+#define SDP_TRACE_API1(m,p1)                    {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1);}
+#define SDP_TRACE_API2(m,p1,p2)                 {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2);}
+#define SDP_TRACE_API3(m,p1,p2,p3)              {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SDP_TRACE_API4(m,p1,p2,p3,p4)           {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SDP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_EVENT0(m)                     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m);}
+#define SDP_TRACE_EVENT1(m,p1)                  {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m, p1);}
+#define SDP_TRACE_EVENT2(m,p1,p2)               {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SDP_TRACE_EVENT3(m,p1,p2,p3)            {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SDP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_DEBUG0(m)                     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m);}
+#define SDP_TRACE_DEBUG1(m,p1)                  {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1);}
+#define SDP_TRACE_DEBUG2(m,p1,p2)               {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SDP_TRACE_DEBUG3(m,p1,p2,p3)            {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SDP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the RFCOMM unit
+*/
+#define RFCOMM_TRACE_ERROR0(m)                     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m);}
+#define RFCOMM_TRACE_ERROR1(m,p1)                  {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1);}
+#define RFCOMM_TRACE_ERROR2(m,p1,p2)               {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define RFCOMM_TRACE_ERROR3(m,p1,p2,p3)            {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define RFCOMM_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_WARNING0(m)                   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m);}
+#define RFCOMM_TRACE_WARNING1(m,p1)                {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1);}
+#define RFCOMM_TRACE_WARNING2(m,p1,p2)             {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define RFCOMM_TRACE_WARNING3(m,p1,p2,p3)          {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define RFCOMM_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_API0(m)                       {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m);}
+#define RFCOMM_TRACE_API1(m,p1)                    {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1);}
+#define RFCOMM_TRACE_API2(m,p1,p2)                 {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2);}
+#define RFCOMM_TRACE_API3(m,p1,p2,p3)              {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3);}
+#define RFCOMM_TRACE_API4(m,p1,p2,p3,p4)           {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_EVENT0(m)                     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m);}
+#define RFCOMM_TRACE_EVENT1(m,p1)                  {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m, p1);}
+#define RFCOMM_TRACE_EVENT2(m,p1,p2)               {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define RFCOMM_TRACE_EVENT3(m,p1,p2,p3)            {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define RFCOMM_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_DEBUG0(m)                     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m);}
+#define RFCOMM_TRACE_DEBUG1(m,p1)                  {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1);}
+#define RFCOMM_TRACE_DEBUG2(m,p1,p2)               {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define RFCOMM_TRACE_DEBUG3(m,p1,p2,p3)            {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define RFCOMM_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for Serial Port Profile
+*/
+#define SPP_TRACE_ERROR0(m)                     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m);}
+#define SPP_TRACE_ERROR1(m,p1)                  {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1);}
+#define SPP_TRACE_ERROR2(m,p1,p2)               {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SPP_TRACE_ERROR3(m,p1,p2,p3)            {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SPP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_WARNING0(m)                   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m);}
+#define SPP_TRACE_WARNING1(m,p1)                {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1);}
+#define SPP_TRACE_WARNING2(m,p1,p2)             {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SPP_TRACE_WARNING3(m,p1,p2,p3)          {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SPP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_EVENT0(m)                     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m);}
+#define SPP_TRACE_EVENT1(m,p1)                  {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m, p1);}
+#define SPP_TRACE_EVENT2(m,p1,p2)               {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SPP_TRACE_EVENT3(m,p1,p2,p3)            {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SPP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_API0(m)                       {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_API, m);}
+#define SPP_TRACE_API1(m,p1)                    {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_API, m, p1);}
+#define SPP_TRACE_API2(m,p1,p2)                 {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2);}
+#define SPP_TRACE_API3(m,p1,p2,p3)              {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SPP_TRACE_API4(m,p1,p2,p3,p4)           {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SPP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_DEBUG0(m)                     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m);}
+#define SPP_TRACE_DEBUG1(m,p1)                  {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1);}
+#define SPP_TRACE_DEBUG2(m,p1,p2)               {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SPP_TRACE_DEBUG3(m,p1,p2,p3)            {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SPP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Generic Access Profile traces */
+#define GAP_TRACE_ERROR0(m)                     {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m);}
+#define GAP_TRACE_ERROR1(m,p1)                  {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m, p1);}
+#define GAP_TRACE_ERROR2(m,p1,p2)               {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GAP_TRACE_ERROR3(m,p1,p2,p3)            {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GAP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_EVENT0(m)                     {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m);}
+#define GAP_TRACE_EVENT1(m,p1)                  {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m, p1);}
+#define GAP_TRACE_EVENT2(m,p1,p2)               {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GAP_TRACE_EVENT3(m,p1,p2,p3)            {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GAP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_API0(m)                       {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_API, m);}
+#define GAP_TRACE_API1(m,p1)                    {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_API, m, p1);}
+#define GAP_TRACE_API2(m,p1,p2)                 {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2);}
+#define GAP_TRACE_API3(m,p1,p2,p3)              {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GAP_TRACE_API4(m,p1,p2,p3,p4)           {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GAP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_WARNING0(m)                   {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m);}
+#define GAP_TRACE_WARNING1(m,p1)                {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m, p1);}
+#define GAP_TRACE_WARNING2(m,p1,p2)             {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GAP_TRACE_WARNING3(m,p1,p2,p3)          {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GAP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for OBX
+*/
+#define OBX_TRACE_ERROR0(m)                      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m);}
+#define OBX_TRACE_ERROR1(m,p1)                   {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1);}
+#define OBX_TRACE_ERROR2(m,p1,p2)                {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2);}
+#define OBX_TRACE_ERROR3(m,p1,p2,p3)             {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define OBX_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define OBX_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_WARNING0(m)                    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m);}
+#define OBX_TRACE_WARNING1(m,p1)                 {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1);}
+#define OBX_TRACE_WARNING2(m,p1,p2)              {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2);}
+#define OBX_TRACE_WARNING3(m,p1,p2,p3)           {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define OBX_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define OBX_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_EVENT0(m)                      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m);}
+#define OBX_TRACE_EVENT1(m,p1)                   {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m, p1);}
+#define OBX_TRACE_EVENT2(m,p1,p2)                {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2);}
+#define OBX_TRACE_EVENT3(m,p1,p2,p3)             {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define OBX_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define OBX_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_DEBUG0(m)                      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m);}
+#define OBX_TRACE_DEBUG1(m,p1)                   {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1);}
+#define OBX_TRACE_DEBUG2(m,p1,p2)                {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define OBX_TRACE_DEBUG3(m,p1,p2,p3)             {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define OBX_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define OBX_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_API0(m)                        {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_API, m);}
+#define OBX_TRACE_API1(m,p1)                     {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_API, m, p1);}
+#define OBX_TRACE_API2(m,p1,p2)                  {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2);}
+#define OBX_TRACE_API3(m,p1,p2,p3)               {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3);}
+#define OBX_TRACE_API4(m,p1,p2,p3,p4)            {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define OBX_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for OBEX application profiles
+*/
+#define GOEP_TRACE_ERROR0(m)                     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m);}
+#define GOEP_TRACE_ERROR1(m,p1)                  {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1);}
+#define GOEP_TRACE_ERROR2(m,p1,p2)               {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GOEP_TRACE_ERROR3(m,p1,p2,p3)            {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GOEP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_WARNING0(m)                   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m);}
+#define GOEP_TRACE_WARNING1(m,p1)                {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1);}
+#define GOEP_TRACE_WARNING2(m,p1,p2)             {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GOEP_TRACE_WARNING3(m,p1,p2,p3)          {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GOEP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_EVENT0(m)                     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m);}
+#define GOEP_TRACE_EVENT1(m,p1)                  {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m, p1);}
+#define GOEP_TRACE_EVENT2(m,p1,p2)               {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GOEP_TRACE_EVENT3(m,p1,p2,p3)            {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GOEP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_DEBUG0(m)                     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m);}
+#define GOEP_TRACE_DEBUG1(m,p1)                  {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1);}
+#define GOEP_TRACE_DEBUG2(m,p1,p2)               {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define GOEP_TRACE_DEBUG3(m,p1,p2,p3)            {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define GOEP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_API0(m)                       {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_API, m);}
+#define GOEP_TRACE_API1(m,p1)                    {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_API, m, p1);}
+#define GOEP_TRACE_API2(m,p1,p2)                 {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2);}
+#define GOEP_TRACE_API3(m,p1,p2,p3)              {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GOEP_TRACE_API4(m,p1,p2,p3,p4)           {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the BPP profile
+*/
+#define BPP_TRACE_ERROR0(m)                      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m);}
+#define BPP_TRACE_ERROR1(m,p1)                   {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1);}
+#define BPP_TRACE_ERROR2(m,p1,p2)                {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BPP_TRACE_ERROR3(m,p1,p2,p3)             {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BPP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_WARNING0(m)                    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m);}
+#define BPP_TRACE_WARNING1(m,p1)                 {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1);}
+#define BPP_TRACE_WARNING2(m,p1,p2)              {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BPP_TRACE_WARNING3(m,p1,p2,p3)           {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BPP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_EVENT0(m)                      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m);}
+#define BPP_TRACE_EVENT1(m,p1)                   {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m, p1);}
+#define BPP_TRACE_EVENT2(m,p1,p2)                {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BPP_TRACE_EVENT3(m,p1,p2,p3)             {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BPP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_DEBUG0(m)                      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m);}
+#define BPP_TRACE_DEBUG1(m,p1)                   {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1);}
+#define BPP_TRACE_DEBUG2(m,p1,p2)                {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BPP_TRACE_DEBUG3(m,p1,p2,p3)             {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BPP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_API0(m)                        {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_API, m);}
+#define BPP_TRACE_API1(m,p1)                     {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_API, m, p1);}
+#define BPP_TRACE_API2(m,p1,p2)                  {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2);}
+#define BPP_TRACE_API3(m,p1,p2,p3)               {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BPP_TRACE_API4(m,p1,p2,p3,p4)            {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BPP_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the BIP profile
+*/
+#define BIP_TRACE_ERROR0(m)                      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m);}
+#define BIP_TRACE_ERROR1(m,p1)                   {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1);}
+#define BIP_TRACE_ERROR2(m,p1,p2)                {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BIP_TRACE_ERROR3(m,p1,p2,p3)             {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BIP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BIP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_WARNING0(m)                    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m);}
+#define BIP_TRACE_WARNING1(m,p1)                 {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1);}
+#define BIP_TRACE_WARNING2(m,p1,p2)              {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BIP_TRACE_WARNING3(m,p1,p2,p3)           {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BIP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BIP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_EVENT0(m)                      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m);}
+#define BIP_TRACE_EVENT1(m,p1)                   {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m, p1);}
+#define BIP_TRACE_EVENT2(m,p1,p2)                {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BIP_TRACE_EVENT3(m,p1,p2,p3)             {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BIP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BIP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_DEBUG0(m)                      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m);}
+#define BIP_TRACE_DEBUG1(m,p1)                   {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1);}
+#define BIP_TRACE_DEBUG2(m,p1,p2)                {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BIP_TRACE_DEBUG3(m,p1,p2,p3)             {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BIP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BIP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_API0(m)                        {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_API, m);}
+#define BIP_TRACE_API1(m,p1)                     {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_API, m, p1);}
+#define BIP_TRACE_API2(m,p1,p2)                  {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2);}
+#define BIP_TRACE_API3(m,p1,p2,p3)               {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BIP_TRACE_API4(m,p1,p2,p3,p4)            {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BIP_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for TCS
+*/
+#define TCS_TRACE_ERROR0(m)                     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m);}
+#define TCS_TRACE_ERROR1(m,p1)                  {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1);}
+#define TCS_TRACE_ERROR2(m,p1,p2)               {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2);}
+#define TCS_TRACE_ERROR3(m,p1,p2,p3)            {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define TCS_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define TCS_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_WARNING0(m)                   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m);}
+#define TCS_TRACE_WARNING1(m,p1)                {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1);}
+#define TCS_TRACE_WARNING2(m,p1,p2)             {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2);}
+#define TCS_TRACE_WARNING3(m,p1,p2,p3)          {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define TCS_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define TCS_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_EVENT0(m)                     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m);}
+#define TCS_TRACE_EVENT1(m,p1)                  {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m, p1);}
+#define TCS_TRACE_EVENT2(m,p1,p2)               {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2);}
+#define TCS_TRACE_EVENT3(m,p1,p2,p3)            {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define TCS_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define TCS_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_DEBUG0(m)                     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m);}
+#define TCS_TRACE_DEBUG1(m,p1)                  {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1);}
+#define TCS_TRACE_DEBUG2(m,p1,p2)               {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define TCS_TRACE_DEBUG3(m,p1,p2,p3)            {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define TCS_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define TCS_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_API0(m)                       {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_API, m);}
+#define TCS_TRACE_API1(m,p1)                    {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_API, m, p1);}
+#define TCS_TRACE_API2(m,p1,p2)                 {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2);}
+#define TCS_TRACE_API3(m,p1,p2,p3)              {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3);}
+#define TCS_TRACE_API4(m,p1,p2,p3,p4)           {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define TCS_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for ICP
+*/
+#define ICP_TRACE_ERROR0(m)                     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m);}
+#define ICP_TRACE_ERROR1(m,p1)                  {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1);}
+#define ICP_TRACE_ERROR2(m,p1,p2)               {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define ICP_TRACE_ERROR3(m,p1,p2,p3)            {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define ICP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define ICP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_WARNING0(m)                   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m);}
+#define ICP_TRACE_WARNING1(m,p1)                {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1);}
+#define ICP_TRACE_WARNING2(m,p1,p2)             {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define ICP_TRACE_WARNING3(m,p1,p2,p3)          {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define ICP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define ICP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_EVENT0(m)                     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m);}
+#define ICP_TRACE_EVENT1(m,p1)                  {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m, p1);}
+#define ICP_TRACE_EVENT2(m,p1,p2)               {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define ICP_TRACE_EVENT3(m,p1,p2,p3)            {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define ICP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define ICP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_DEBUG0(m)                     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m);}
+#define ICP_TRACE_DEBUG1(m,p1)                  {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1);}
+#define ICP_TRACE_DEBUG2(m,p1,p2)               {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define ICP_TRACE_DEBUG3(m,p1,p2,p3)            {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define ICP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define ICP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_API0(m)                       {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_API, m);}
+#define ICP_TRACE_API1(m,p1)                    {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_API, m, p1);}
+#define ICP_TRACE_API2(m,p1,p2)                 {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2);}
+#define ICP_TRACE_API3(m,p1,p2,p3)              {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define ICP_TRACE_API4(m,p1,p2,p3,p4)           {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define ICP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* CTP */
+#define CTP_TRACE_ERROR0(m)                     {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m);}
+#define CTP_TRACE_ERROR1(m,p1)                  {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1);}
+#define CTP_TRACE_ERROR2(m,p1,p2)               {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CTP_TRACE_ERROR3(m,p1,p2,p3)            {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CTP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_WARNING0(m)                   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m);}
+#define CTP_TRACE_WARNING1(m,p1)                {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1);}
+#define CTP_TRACE_WARNING2(m,p1,p2)             {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CTP_TRACE_WARNING3(m,p1,p2,p3)          {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CTP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_EVENT0(m)                     {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m);}
+#define CTP_TRACE_EVENT1(m,p1)                  {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m, p1);}
+#define CTP_TRACE_EVENT2(m,p1,p2)               {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CTP_TRACE_EVENT3(m,p1,p2,p3)            {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CTP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_DEBUG0(m)                     {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m);}
+#define CTP_TRACE_DEBUG1(m,p1)                  {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1);}
+#define CTP_TRACE_DEBUG2(m,p1,p2)               {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CTP_TRACE_DEBUG3(m,p1,p2,p3)            {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CTP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* define traces for HID Host */
+#define HIDH_TRACE_ERROR0(m)                     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m);}
+#define HIDH_TRACE_ERROR1(m,p1)                  {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m, p1);}
+#define HIDH_TRACE_ERROR2(m,p1,p2)               {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HIDH_TRACE_ERROR3(m,p1,p2,p3)            {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HIDH_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_WARNING0(m)                   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m);}
+#define HIDH_TRACE_WARNING1(m,p1)                {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1);}
+#define HIDH_TRACE_WARNING2(m,p1,p2)             {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HIDH_TRACE_WARNING3(m,p1,p2,p3)          {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HIDH_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_API0(m)                       {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_API, m);}
+#define HIDH_TRACE_API1(m,p1)                    {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_API, m, p1);}
+#define HIDH_TRACE_API2(m,p1,p2)                 {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2);}
+#define HIDH_TRACE_API3(m,p1,p2,p3)              {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HIDH_TRACE_API4(m,p1,p2,p3,p4)           {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_EVENT0(m)                     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m);}
+#define HIDH_TRACE_EVENT1(m,p1)                  {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m, p1);}
+#define HIDH_TRACE_EVENT2(m,p1,p2)               {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HIDH_TRACE_EVENT3(m,p1,p2,p3)            {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HIDH_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_DEBUG0(m)                     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m);}
+#define HIDH_TRACE_DEBUG1(m,p1)                  {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1);}
+#define HIDH_TRACE_DEBUG2(m,p1,p2)               {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HIDH_TRACE_DEBUG3(m,p1,p2,p3)            {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HIDH_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for HID Device */
+#define HIDD_TRACE_ERROR0(m)                     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m);}
+#define HIDD_TRACE_ERROR1(m,p1)                  {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m, p1);}
+#define HIDD_TRACE_ERROR2(m,p1,p2)               {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HIDD_TRACE_ERROR3(m,p1,p2,p3)            {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HIDD_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_WARNING0(m)                   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m);}
+#define HIDD_TRACE_WARNING1(m,p1)                {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1);}
+#define HIDD_TRACE_WARNING2(m,p1,p2)             {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HIDD_TRACE_WARNING3(m,p1,p2,p3)          {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HIDD_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_API0(m)                       {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_API, m);}
+#define HIDD_TRACE_API1(m,p1)                    {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_API, m, p1);}
+#define HIDD_TRACE_API2(m,p1,p2)                 {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2);}
+#define HIDD_TRACE_API3(m,p1,p2,p3)              {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HIDD_TRACE_API4(m,p1,p2,p3,p4)           {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_EVENT0(m)                     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m);}
+#define HIDD_TRACE_EVENT1(m,p1)                  {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m, p1);}
+#define HIDD_TRACE_EVENT2(m,p1,p2)               {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HIDD_TRACE_EVENT3(m,p1,p2,p3)            {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HIDD_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_DEBUG0(m)                     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m);}
+#define HIDD_TRACE_DEBUG1(m,p1)                  {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1);}
+#define HIDD_TRACE_DEBUG2(m,p1,p2)               {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HIDD_TRACE_DEBUG3(m,p1,p2,p3)            {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HIDD_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for headset profile */
+#define HSP2_TRACE_ERROR0(pcb,m)                     {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m);}
+#define HSP2_TRACE_ERROR1(pcb,m,p1)                  {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m, p1);}
+#define HSP2_TRACE_ERROR2(pcb,m,p1,p2)               {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HSP2_TRACE_ERROR3(pcb,m,p1,p2,p3)            {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HSP2_TRACE_ERROR4(pcb,m,p1,p2,p3,p4)         {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_ERROR5(pcb,m,p1,p2,p3,p4,p5)      {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_ERROR6(pcb,m,p1,p2,p3,p4,p5,p6)   {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_WARNING0(pcb,m)                   {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m);}
+#define HSP2_TRACE_WARNING1(pcb,m,p1)                {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1);}
+#define HSP2_TRACE_WARNING2(pcb,m,p1,p2)             {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HSP2_TRACE_WARNING3(pcb,m,p1,p2,p3)          {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HSP2_TRACE_WARNING4(pcb,m,p1,p2,p3,p4)       {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_WARNING5(pcb,m,p1,p2,p3,p4,p5)    {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_WARNING6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_API0(pcb,m)                       {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_API, m);}
+#define HSP2_TRACE_API1(pcb,m,p1)                    {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_API, m, p1);}
+#define HSP2_TRACE_API2(pcb,m,p1,p2)                 {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2);}
+#define HSP2_TRACE_API3(pcb,m,p1,p2,p3)              {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HSP2_TRACE_API4(pcb,m,p1,p2,p3,p4)           {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_API5(pcb,m,p1,p2,p3,p4,p5)        {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_API6(pcb,m,p1,p2,p3,p4,p5,p6)     {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_EVENT0(pcb,m)                     {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m);}
+#define HSP2_TRACE_EVENT1(pcb,m,p1)                  {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m, p1);}
+#define HSP2_TRACE_EVENT2(pcb,m,p1,p2)               {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HSP2_TRACE_EVENT3(pcb,m,p1,p2,p3)            {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HSP2_TRACE_EVENT4(pcb,m,p1,p2,p3,p4)         {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_EVENT5(pcb,m,p1,p2,p3,p4,p5)      {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_EVENT6(pcb,m,p1,p2,p3,p4,p5,p6)   {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_DEBUG0(pcb,m)                     {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m);}
+#define HSP2_TRACE_DEBUG1(pcb,m,p1)                  {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1);}
+#define HSP2_TRACE_DEBUG2(pcb,m,p1,p2)               {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HSP2_TRACE_DEBUG3(pcb,m,p1,p2,p3)            {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HSP2_TRACE_DEBUG4(pcb,m,p1,p2,p3,p4)         {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_DEBUG5(pcb,m,p1,p2,p3,p4,p5)      {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_DEBUG6(pcb,m,p1,p2,p3,p4,p5,p6)   {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m)                     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m);}
+#define NFC_TRACE_ERROR1(m,p1)                  {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1);}
+#define NFC_TRACE_ERROR2(m,p1,p2)               {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NFC_TRACE_ERROR3(m,p1,p2,p3)            {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NFC_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NFC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_WARNING0(m)                   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m);}
+#define NFC_TRACE_WARNING1(m,p1)                {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1);}
+#define NFC_TRACE_WARNING2(m,p1,p2)             {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NFC_TRACE_WARNING3(m,p1,p2,p3)          {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NFC_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NFC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_API0(m)                       {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_API, m);}
+#define NFC_TRACE_API1(m,p1)                    {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1);}
+#define NFC_TRACE_API2(m,p1,p2)                 {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2);}
+#define NFC_TRACE_API3(m,p1,p2,p3)              {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NFC_TRACE_API4(m,p1,p2,p3,p4)           {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NFC_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_EVENT0(m)                     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m);}
+#define NFC_TRACE_EVENT1(m,p1)                  {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1);}
+#define NFC_TRACE_EVENT2(m,p1,p2)               {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NFC_TRACE_EVENT3(m,p1,p2,p3)            {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NFC_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NFC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_DEBUG0(m)                     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m);}
+#define NFC_TRACE_DEBUG1(m,p1)                  {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1);}
+#define NFC_TRACE_DEBUG2(m,p1,p2)               {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NFC_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NFC_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NFC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_ERROR0(m)                     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m);}
+#define NCI_TRACE_ERROR1(m,p1)                  {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1);}
+#define NCI_TRACE_ERROR2(m,p1,p2)               {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)            {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_WARNING0(m)                   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m);}
+#define NCI_TRACE_WARNING1(m,p1)                {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1);}
+#define NCI_TRACE_WARNING2(m,p1,p2)             {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)          {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_API0(m)                       {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_API, m);}
+#define NCI_TRACE_API1(m,p1)                    {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1);}
+#define NCI_TRACE_API2(m,p1,p2)                 {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2);}
+#define NCI_TRACE_API3(m,p1,p2,p3)              {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)           {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_EVENT0(m)                     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m);}
+#define NCI_TRACE_EVENT1(m,p1)                  {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1);}
+#define NCI_TRACE_EVENT2(m,p1,p2)               {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)            {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_DEBUG0(m)                     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m);}
+#define NCI_TRACE_DEBUG1(m,p1)                  {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1);}
+#define NCI_TRACE_DEBUG2(m,p1,p2)               {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)            {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_ERROR0(m)                     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m);}
+#define RW_TRACE_ERROR1(m,p1)                  {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1);}
+#define RW_TRACE_ERROR2(m,p1,p2)               {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2);}
+#define RW_TRACE_ERROR3(m,p1,p2,p3)            {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define RW_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define RW_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_WARNING0(m)                   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m);}
+#define RW_TRACE_WARNING1(m,p1)                {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1);}
+#define RW_TRACE_WARNING2(m,p1,p2)             {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2);}
+#define RW_TRACE_WARNING3(m,p1,p2,p3)          {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define RW_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define RW_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_API0(m)                       {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_API, m);}
+#define RW_TRACE_API1(m,p1)                    {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1);}
+#define RW_TRACE_API2(m,p1,p2)                 {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2);}
+#define RW_TRACE_API3(m,p1,p2,p3)              {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3);}
+#define RW_TRACE_API4(m,p1,p2,p3,p4)           {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define RW_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_EVENT0(m)                     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m);}
+#define RW_TRACE_EVENT1(m,p1)                  {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1);}
+#define RW_TRACE_EVENT2(m,p1,p2)               {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2);}
+#define RW_TRACE_EVENT3(m,p1,p2,p3)            {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define RW_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define RW_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_DEBUG0(m)                     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m);}
+#define RW_TRACE_DEBUG1(m,p1)                  {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1);}
+#define RW_TRACE_DEBUG2(m,p1,p2)               {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define RW_TRACE_DEBUG3(m,p1,p2,p3)            {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define RW_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define RW_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_ERROR0(m)                     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m);}
+#define CE_TRACE_ERROR1(m,p1)                  {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1);}
+#define CE_TRACE_ERROR2(m,p1,p2)               {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CE_TRACE_ERROR3(m,p1,p2,p3)            {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CE_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CE_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_WARNING0(m)                   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m);}
+#define CE_TRACE_WARNING1(m,p1)                {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1);}
+#define CE_TRACE_WARNING2(m,p1,p2)             {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CE_TRACE_WARNING3(m,p1,p2,p3)          {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CE_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CE_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_API0(m)                       {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_API, m);}
+#define CE_TRACE_API1(m,p1)                    {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1);}
+#define CE_TRACE_API2(m,p1,p2)                 {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2);}
+#define CE_TRACE_API3(m,p1,p2,p3)              {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3);}
+#define CE_TRACE_API4(m,p1,p2,p3,p4)           {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define CE_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_EVENT0(m)                     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m);}
+#define CE_TRACE_EVENT1(m,p1)                  {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1);}
+#define CE_TRACE_EVENT2(m,p1,p2)               {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CE_TRACE_EVENT3(m,p1,p2,p3)            {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CE_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CE_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_DEBUG0(m)                     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m);}
+#define CE_TRACE_DEBUG1(m,p1)                  {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1);}
+#define CE_TRACE_DEBUG2(m,p1,p2)               {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CE_TRACE_DEBUG3(m,p1,p2,p3)            {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CE_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CE_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_ERROR0(m)                     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m);}
+#define NDEF_TRACE_ERROR1(m,p1)                  {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1);}
+#define NDEF_TRACE_ERROR2(m,p1,p2)               {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NDEF_TRACE_ERROR3(m,p1,p2,p3)            {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NDEF_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_WARNING0(m)                   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m);}
+#define NDEF_TRACE_WARNING1(m,p1)                {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1);}
+#define NDEF_TRACE_WARNING2(m,p1,p2)             {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NDEF_TRACE_WARNING3(m,p1,p2,p3)          {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NDEF_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_API0(m)                       {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_API, m);}
+#define NDEF_TRACE_API1(m,p1)                    {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1);}
+#define NDEF_TRACE_API2(m,p1,p2)                 {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2);}
+#define NDEF_TRACE_API3(m,p1,p2,p3)              {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NDEF_TRACE_API4(m,p1,p2,p3,p4)           {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_EVENT0(m)                     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m);}
+#define NDEF_TRACE_EVENT1(m,p1)                  {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1);}
+#define NDEF_TRACE_EVENT2(m,p1,p2)               {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NDEF_TRACE_EVENT3(m,p1,p2,p3)            {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NDEF_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_DEBUG0(m)                     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m);}
+#define NDEF_TRACE_DEBUG1(m,p1)                  {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1);}
+#define NDEF_TRACE_DEBUG2(m,p1,p2)               {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NDEF_TRACE_DEBUG3(m,p1,p2,p3)            {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NDEF_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m)                     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m);}
+#define NFA_TRACE_ERROR1(m,p1)                  {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1);}
+#define NFA_TRACE_ERROR2(m,p1,p2)               {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NFA_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NFA_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NFA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_WARNING0(m)                   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m);}
+#define NFA_TRACE_WARNING1(m,p1)                {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1);}
+#define NFA_TRACE_WARNING2(m,p1,p2)             {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NFA_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NFA_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NFA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_API0(m)                       {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_API, m);}
+#define NFA_TRACE_API1(m,p1)                    {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1);}
+#define NFA_TRACE_API2(m,p1,p2)                 {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2);}
+#define NFA_TRACE_API3(m,p1,p2,p3)              {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NFA_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NFA_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_EVENT0(m)                     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m);}
+#define NFA_TRACE_EVENT1(m,p1)                  {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1);}
+#define NFA_TRACE_EVENT2(m,p1,p2)               {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NFA_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NFA_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NFA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_DEBUG0(m)                     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m);}
+#define NFA_TRACE_DEBUG1(m,p1)                  {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1);}
+#define NFA_TRACE_DEBUG2(m,p1,p2)               {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NFA_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NFA_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NFA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m)                     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m);}
+#define P2P_TRACE_ERROR1(m,p1)                  {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1);}
+#define P2P_TRACE_ERROR2(m,p1,p2)               {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2);}
+#define P2P_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define P2P_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define P2P_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_WARNING0(m)                   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m);}
+#define P2P_TRACE_WARNING1(m,p1)                {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1);}
+#define P2P_TRACE_WARNING2(m,p1,p2)             {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2);}
+#define P2P_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define P2P_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define P2P_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_API0(m)                       {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_API, m);}
+#define P2P_TRACE_API1(m,p1)                    {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1);}
+#define P2P_TRACE_API2(m,p1,p2)                 {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2);}
+#define P2P_TRACE_API3(m,p1,p2,p3)              {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3);}
+#define P2P_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define P2P_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_EVENT0(m)                     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m);}
+#define P2P_TRACE_EVENT1(m,p1)                  {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1);}
+#define P2P_TRACE_EVENT2(m,p1,p2)               {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2);}
+#define P2P_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define P2P_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define P2P_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_DEBUG0(m)                     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m);}
+#define P2P_TRACE_DEBUG1(m,p1)                  {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1);}
+#define P2P_TRACE_DEBUG2(m,p1,p2)               {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define P2P_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define P2P_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define P2P_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA CHO unit
+*/
+#define CHO_TRACE_ERROR0(m)                     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m);}
+#define CHO_TRACE_ERROR1(m,p1)                  {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1);}
+#define CHO_TRACE_ERROR2(m,p1,p2)               {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CHO_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CHO_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CHO_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_WARNING0(m)                   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m);}
+#define CHO_TRACE_WARNING1(m,p1)                {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1);}
+#define CHO_TRACE_WARNING2(m,p1,p2)             {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CHO_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CHO_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CHO_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_API0(m)                       {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_API, m);}
+#define CHO_TRACE_API1(m,p1)                    {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1);}
+#define CHO_TRACE_API2(m,p1,p2)                 {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2);}
+#define CHO_TRACE_API3(m,p1,p2,p3)              {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3);}
+#define CHO_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define CHO_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_EVENT0(m)                     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m);}
+#define CHO_TRACE_EVENT1(m,p1)                  {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m, p1);}
+#define CHO_TRACE_EVENT2(m,p1,p2)               {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CHO_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CHO_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CHO_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_DEBUG0(m)                     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m);}
+#define CHO_TRACE_DEBUG1(m,p1)                  {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1);}
+#define CHO_TRACE_DEBUG2(m,p1,p2)               {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CHO_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CHO_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CHO_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA SNEP unit
+*/
+#define SNEP_TRACE_ERROR0(m)                     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m);}
+#define SNEP_TRACE_ERROR1(m,p1)                  {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1);}
+#define SNEP_TRACE_ERROR2(m,p1,p2)               {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SNEP_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SNEP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_WARNING0(m)                   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m);}
+#define SNEP_TRACE_WARNING1(m,p1)                {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1);}
+#define SNEP_TRACE_WARNING2(m,p1,p2)             {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SNEP_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SNEP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_API0(m)                       {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_API, m);}
+#define SNEP_TRACE_API1(m,p1)                    {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1);}
+#define SNEP_TRACE_API2(m,p1,p2)                 {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2);}
+#define SNEP_TRACE_API3(m,p1,p2,p3)              {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SNEP_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_EVENT0(m)                     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m);}
+#define SNEP_TRACE_EVENT1(m,p1)                  {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m, p1);}
+#define SNEP_TRACE_EVENT2(m,p1,p2)               {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SNEP_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SNEP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_DEBUG0(m)                     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m);}
+#define SNEP_TRACE_DEBUG1(m,p1)                  {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1);}
+#define SNEP_TRACE_DEBUG2(m,p1,p2)               {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SNEP_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define MMI_TRACE_0(m)
+#define MMI_TRACE_1(m,p1)
+#define MMI_TRACE_2(m,p1,p2)
+#define MMI_TRACE_3(m,p1,p2,p3)
+#define MMI_TRACE_4(m,p1,p2,p3,p4)
+#define MMI_TRACE_5(m,p1,p2,p3,p4,p5)
+#define MMI_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_DEBUG_0(m)                           BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m)
+#define MMI_DEBUG_1(m,p1)                        BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1)
+#define MMI_DEBUG_2(m,p1,p2)                     BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2)
+#define MMI_DEBUG_3(m,p1,p2,p3)                  BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3)
+#define MMI_DEBUG_4(m,p1,p2,p3,p4)               BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4)
+#define MMI_DEBUG_5(m,p1,p2,p3,p4,p5)            BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5)
+#define MMI_DEBUG_6(m,p1,p2,p3,p4,p5,p6)         BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_WARNING_0(m)                         BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m)
+#define MMI_WARNING_1(m,p1)                      BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1)
+#define MMI_WARNING_2(m,p1,p2)                   BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2)
+#define MMI_WARNING_3(m,p1,p2,p3)                BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3)
+#define MMI_WARNING_4(m,p1,p2,p3,p4)             BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4)
+#define MMI_WARNING_5(m,p1,p2,p3,p4,p5)          BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5)
+#define MMI_WARNING_6(m,p1,p2,p3,p4,p5,p6)       BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_ERROR_0(m)                           BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m)
+#define MMI_ERROR_1(m,p1)                        BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1)
+#define MMI_ERROR_2(m,p1,p2)                     BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2)
+#define MMI_ERROR_3(m,p1,p2,p3)                  BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3)
+#define MMI_ERROR_4(m,p1,p2,p3,p4)               BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4)
+#define MMI_ERROR_5(m,p1,p2,p3,p4,p5)            BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5)
+#define MMI_ERROR_6(m,p1,p2,p3,p4,p5,p6)         BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6)
+
+#define TAK_TRACE_0(m)                            MMI_Echo(m)
+
+/* hid mouse module traces */
+
+#define MSKB_TRACE_0(m)                         MMI_Echo(m)
+#define MSKB_TRACE_1(m,p1)                      MMI_Echo(m,p1)
+#define MSKB_TRACE_2(m,p1,p2)                   MMI_Echo(m,p1,p2)
+#define MSKB_TRACE_3(m,p1,p2,p3)                MMI_Echo(m,p1,p2,p3)
+#define MSKB_TRACE_4(m,p1,p2,p3,p4)             MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_TRACE_5(m,p1,p2,p3,p4,p5)          MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_TRACE_6(m,p1,p2,p3,p4,p5,p6)       MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_DEBUG_0(m)                         MMI_Echo(m)
+#define MSKB_DEBUG_1(m,p1)                      MMI_Echo(m,p1)
+#define MSKB_DEBUG_2(m,p1,p2)                   MMI_Echo(m,p1,p2)
+#define MSKB_DEBUG_3(m,p1,p2,p3)                MMI_Echo(m,p1,p2,p3)
+#define MSKB_DEBUG_4(m,p1,p2,p3,p4)             MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_DEBUG_5(m,p1,p2,p3,p4,p5)          MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_DEBUG_6(m,p1,p2,p3,p4,p5,p6)       MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_ERROR_0(m)                         MMI_Echo(m)
+#define MSKB_ERROR_1(m,p1)                      MMI_Echo(m,p1)
+#define MSKB_ERROR_2(m,p1,p2)                   MMI_Echo(m,p1,p2)
+#define MSKB_ERROR_3(m,p1,p2,p3)                MMI_Echo(m,p1,p2,p3)
+#define MSKB_ERROR_4(m,p1,p2,p3,p4)             MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_ERROR_5(m,p1,p2,p3,p4,p5)          MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_ERROR_6(m,p1,p2,p3,p4,p5,p6)       MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for DUN */
+
+#define DUN_TRACE_ERROR0(m)                     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m);}
+#define DUN_TRACE_ERROR1(m,p1)                  {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m, p1);}
+#define DUN_TRACE_ERROR2(m,p1,p2)               {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2);}
+#define DUN_TRACE_ERROR3(m,p1,p2,p3)            {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define DUN_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define DUN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_WARNING0(m)                   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m);}
+#define DUN_TRACE_WARNING1(m,p1)                {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1);}
+#define DUN_TRACE_WARNING2(m,p1,p2)             {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2);}
+#define DUN_TRACE_WARNING3(m,p1,p2,p3)          {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define DUN_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define DUN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_API0(m)                       {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_API, m);}
+#define DUN_TRACE_API1(m,p1)                    {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_API, m, p1);}
+#define DUN_TRACE_API2(m,p1,p2)                 {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2);}
+#define DUN_TRACE_API3(m,p1,p2,p3)              {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3);}
+#define DUN_TRACE_API4(m,p1,p2,p3,p4)           {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define DUN_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_EVENT0(m)                     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m);}
+#define DUN_TRACE_EVENT1(m,p1)                  {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m, p1);}
+#define DUN_TRACE_EVENT2(m,p1,p2)               {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2);}
+#define DUN_TRACE_EVENT3(m,p1,p2,p3)            {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define DUN_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define DUN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_DEBUG0(m)                     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m);}
+#define DUN_TRACE_DEBUG1(m,p1)                  {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1);}
+#define DUN_TRACE_DEBUG2(m,p1,p2)               {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define DUN_TRACE_DEBUG3(m,p1,p2,p3)            {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define DUN_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define DUN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for hardcopy cable replacement profile */
+
+#define HCRP_TRACE_ERROR0(m)                     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m);}
+#define HCRP_TRACE_ERROR1(m,p1)                  {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m, p1);}
+#define HCRP_TRACE_ERROR2(m,p1,p2)               {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCRP_TRACE_ERROR3(m,p1,p2,p3)            {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCRP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_WARNING0(m)                   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m);}
+#define HCRP_TRACE_WARNING1(m,p1)                {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1);}
+#define HCRP_TRACE_WARNING2(m,p1,p2)             {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCRP_TRACE_WARNING3(m,p1,p2,p3)          {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCRP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_API0(m)                       {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_API, m);}
+#define HCRP_TRACE_API1(m,p1)                    {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_API, m, p1);}
+#define HCRP_TRACE_API2(m,p1,p2)                 {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2);}
+#define HCRP_TRACE_API3(m,p1,p2,p3)              {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HCRP_TRACE_API4(m,p1,p2,p3,p4)           {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_EVENT0(m)                     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m);}
+#define HCRP_TRACE_EVENT1(m,p1)                  {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m, p1);}
+#define HCRP_TRACE_EVENT2(m,p1,p2)               {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCRP_TRACE_EVENT3(m,p1,p2,p3)            {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCRP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_DEBUG0(m)                     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m);}
+#define HCRP_TRACE_DEBUG1(m,p1)                  {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1);}
+#define HCRP_TRACE_DEBUG2(m,p1,p2)               {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCRP_TRACE_DEBUG3(m,p1,p2,p3)            {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCRP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for multi-client server hardcopy cable replacement profile */
+
+#define HCRPM_TRACE_ERROR0(m)                     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m);}
+#define HCRPM_TRACE_ERROR1(m,p1)                  {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m, p1);}
+#define HCRPM_TRACE_ERROR2(m,p1,p2)               {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCRPM_TRACE_ERROR3(m,p1,p2,p3)            {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCRPM_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_WARNING0(m)                   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m);}
+#define HCRPM_TRACE_WARNING1(m,p1)                {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1);}
+#define HCRPM_TRACE_WARNING2(m,p1,p2)             {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCRPM_TRACE_WARNING3(m,p1,p2,p3)          {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCRPM_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_API0(m)                       {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_API, m);}
+#define HCRPM_TRACE_API1(m,p1)                    {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_API, m, p1);}
+#define HCRPM_TRACE_API2(m,p1,p2)                 {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2);}
+#define HCRPM_TRACE_API3(m,p1,p2,p3)              {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HCRPM_TRACE_API4(m,p1,p2,p3,p4)           {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_EVENT0(m)                     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m);}
+#define HCRPM_TRACE_EVENT1(m,p1)                  {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m, p1);}
+#define HCRPM_TRACE_EVENT2(m,p1,p2)               {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCRPM_TRACE_EVENT3(m,p1,p2,p3)            {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCRPM_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_DEBUG0(m)                     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m);}
+#define HCRPM_TRACE_DEBUG1(m,p1)                  {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1);}
+#define HCRPM_TRACE_DEBUG2(m,p1,p2)               {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCRPM_TRACE_DEBUG3(m,p1,p2,p3)            {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCRPM_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for RPC */
+
+#define RPC_TRACE_ERROR0(m)                      {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, (m));}
+#define RPC_TRACE_ERROR1(m,p1)                   {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_ERROR2(m,p1,p2)                {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_ERROR3(m,p1,p2,p3)             {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_WARNING0(m)                    {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, (m));}
+#define RPC_TRACE_WARNING1(m,p1)                 {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_WARNING2(m,p1,p2)              {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_WARNING3(m,p1,p2,p3)           {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_API0(m)                        {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, (m));}
+#define RPC_TRACE_API1(m,p1)                     {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_API2(m,p1,p2)                  {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_API3(m,p1,p2,p3)               {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_API4(m,p1,p2,p3,p4)            {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_EVENT0(m)                      {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, (m));}
+#define RPC_TRACE_EVENT1(m,p1)                   {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_EVENT2(m,p1,p2)                {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_EVENT3(m,p1,p2,p3)             {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_DEBUG0(m)                      {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, (m));}
+#define RPC_TRACE_DEBUG1(m,p1)                   {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_DEBUG2(m,p1,p2)                {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_DEBUG3(m,p1,p2,p3)             {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+/* define traces for BNEP */
+
+#define BNEP_TRACE_ERROR0(m)                     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m);}
+#define BNEP_TRACE_ERROR1(m,p1)                  {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m, p1);}
+#define BNEP_TRACE_ERROR2(m,p1,p2)               {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BNEP_TRACE_ERROR3(m,p1,p2,p3)            {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BNEP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_WARNING0(m)                   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m);}
+#define BNEP_TRACE_WARNING1(m,p1)                {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1);}
+#define BNEP_TRACE_WARNING2(m,p1,p2)             {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BNEP_TRACE_WARNING3(m,p1,p2,p3)          {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BNEP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_API0(m)                       {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_API, m);}
+#define BNEP_TRACE_API1(m,p1)                    {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_API, m, p1);}
+#define BNEP_TRACE_API2(m,p1,p2)                 {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2);}
+#define BNEP_TRACE_API3(m,p1,p2,p3)              {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BNEP_TRACE_API4(m,p1,p2,p3,p4)           {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_EVENT0(m)                     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m);}
+#define BNEP_TRACE_EVENT1(m,p1)                  {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m, p1);}
+#define BNEP_TRACE_EVENT2(m,p1,p2)               {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BNEP_TRACE_EVENT3(m,p1,p2,p3)            {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BNEP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_DEBUG0(m)                     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m);}
+#define BNEP_TRACE_DEBUG1(m,p1)                  {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1);}
+#define BNEP_TRACE_DEBUG2(m,p1,p2)               {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BNEP_TRACE_DEBUG3(m,p1,p2,p3)            {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for PAN */
+
+#define PAN_TRACE_ERROR0(m)                     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m);}
+#define PAN_TRACE_ERROR1(m,p1)                  {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m, p1);}
+#define PAN_TRACE_ERROR2(m,p1,p2)               {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2);}
+#define PAN_TRACE_ERROR3(m,p1,p2,p3)            {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define PAN_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define PAN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_WARNING0(m)                   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m);}
+#define PAN_TRACE_WARNING1(m,p1)                {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1);}
+#define PAN_TRACE_WARNING2(m,p1,p2)             {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2);}
+#define PAN_TRACE_WARNING3(m,p1,p2,p3)          {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define PAN_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define PAN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_API0(m)                       {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_API, m);}
+#define PAN_TRACE_API1(m,p1)                    {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_API, m, p1);}
+#define PAN_TRACE_API2(m,p1,p2)                 {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2);}
+#define PAN_TRACE_API3(m,p1,p2,p3)              {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3);}
+#define PAN_TRACE_API4(m,p1,p2,p3,p4)           {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define PAN_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_EVENT0(m)                     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m);}
+#define PAN_TRACE_EVENT1(m,p1)                  {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m, p1);}
+#define PAN_TRACE_EVENT2(m,p1,p2)               {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2);}
+#define PAN_TRACE_EVENT3(m,p1,p2,p3)            {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define PAN_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define PAN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_DEBUG0(m)                     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m);}
+#define PAN_TRACE_DEBUG1(m,p1)                  {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1);}
+#define PAN_TRACE_DEBUG2(m,p1,p2)               {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define PAN_TRACE_DEBUG3(m,p1,p2,p3)            {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define PAN_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define PAN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for SIM */
+
+#define SAP_TRACE_ERROR0(m)                     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m);}
+#define SAP_TRACE_ERROR1(m,p1)                  {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m, p1);}
+#define SAP_TRACE_ERROR2(m,p1,p2)               {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SAP_TRACE_ERROR3(m,p1,p2,p3)            {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SAP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_WARNING0(m)                   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m);}
+#define SAP_TRACE_WARNING1(m,p1)                {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1);}
+#define SAP_TRACE_WARNING2(m,p1,p2)             {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SAP_TRACE_WARNING3(m,p1,p2,p3)          {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SAP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_API0(m)                       {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_API, m);}
+#define SAP_TRACE_API1(m,p1)                    {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_API, m, p1);}
+#define SAP_TRACE_API2(m,p1,p2)                 {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2);}
+#define SAP_TRACE_API3(m,p1,p2,p3)              {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SAP_TRACE_API4(m,p1,p2,p3,p4)           {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SAP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_EVENT0(m)                     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m);}
+#define SAP_TRACE_EVENT1(m,p1)                  {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m, p1);}
+#define SAP_TRACE_EVENT2(m,p1,p2)               {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SAP_TRACE_EVENT3(m,p1,p2,p3)            {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SAP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_DEBUG0(m)                     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m);}
+#define SAP_TRACE_DEBUG1(m,p1)                  {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1);}
+#define SAP_TRACE_DEBUG2(m,p1,p2)               {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SAP_TRACE_DEBUG3(m,p1,p2,p3)            {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SAP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for OPP profile
+*/
+#define OPP_TRACE_ERROR0(m)                      {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m);}
+#define OPP_TRACE_ERROR1(m,p1)                   {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1);}
+#define OPP_TRACE_ERROR2(m,p1,p2)                {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define OPP_TRACE_ERROR3(m,p1,p2,p3)             {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define OPP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define OPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_WARNING0(m)                    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m);}
+#define OPP_TRACE_WARNING1(m,p1)                 {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1);}
+#define OPP_TRACE_WARNING2(m,p1,p2)              {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define OPP_TRACE_WARNING3(m,p1,p2,p3)           {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define OPP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define OPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_EVENT0(m)                      {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m);}
+#define OPP_TRACE_EVENT1(m,p1)                   {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m, p1);}
+#define OPP_TRACE_EVENT2(m,p1,p2)                {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define OPP_TRACE_EVENT3(m,p1,p2,p3)             {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define OPP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define OPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_DEBUG0(m)                      {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m);}
+#define OPP_TRACE_DEBUG1(m,p1)                   {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1);}
+#define OPP_TRACE_DEBUG2(m,p1,p2)                {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define OPP_TRACE_DEBUG3(m,p1,p2,p3)             {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define OPP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define OPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for FTP profile
+*/
+#define FTP_TRACE_ERROR0(m)                      {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m);}
+#define FTP_TRACE_ERROR1(m,p1)                   {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1);}
+#define FTP_TRACE_ERROR2(m,p1,p2)                {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define FTP_TRACE_ERROR3(m,p1,p2,p3)             {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define FTP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define FTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_WARNING0(m)                    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m);}
+#define FTP_TRACE_WARNING1(m,p1)                 {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1);}
+#define FTP_TRACE_WARNING2(m,p1,p2)              {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define FTP_TRACE_WARNING3(m,p1,p2,p3)           {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define FTP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define FTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_EVENT0(m)                      {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m);}
+#define FTP_TRACE_EVENT1(m,p1)                   {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m, p1);}
+#define FTP_TRACE_EVENT2(m,p1,p2)                {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define FTP_TRACE_EVENT3(m,p1,p2,p3)             {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define FTP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define FTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_DEBUG0(m)                      {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m);}
+#define FTP_TRACE_DEBUG1(m,p1)                   {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1);}
+#define FTP_TRACE_DEBUG2(m,p1,p2)                {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define FTP_TRACE_DEBUG3(m,p1,p2,p3)             {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define FTP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define FTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the A2DP profile
+*/
+#define A2D_TRACE_ERROR0(m)                      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m);}
+#define A2D_TRACE_ERROR1(m,p1)                   {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1);}
+#define A2D_TRACE_ERROR2(m,p1,p2)                {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2);}
+#define A2D_TRACE_ERROR3(m,p1,p2,p3)             {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define A2D_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define A2D_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_WARNING0(m)                    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m);}
+#define A2D_TRACE_WARNING1(m,p1)                 {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1);}
+#define A2D_TRACE_WARNING2(m,p1,p2)              {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2);}
+#define A2D_TRACE_WARNING3(m,p1,p2,p3)           {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define A2D_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define A2D_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_EVENT0(m)                      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m);}
+#define A2D_TRACE_EVENT1(m,p1)                   {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m, p1);}
+#define A2D_TRACE_EVENT2(m,p1,p2)                {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2);}
+#define A2D_TRACE_EVENT3(m,p1,p2,p3)             {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define A2D_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define A2D_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_DEBUG0(m)                      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m);}
+#define A2D_TRACE_DEBUG1(m,p1)                   {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1);}
+#define A2D_TRACE_DEBUG2(m,p1,p2)                {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define A2D_TRACE_DEBUG3(m,p1,p2,p3)             {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define A2D_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define A2D_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_API0(m)                        {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_API,m);}
+#define A2D_TRACE_API1(m,p1)                     {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_API,m, p1);}
+#define A2D_TRACE_API2(m,p1,p2)                  {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2);}
+#define A2D_TRACE_API3(m,p1,p2,p3)               {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3);}
+#define A2D_TRACE_API4(m,p1,p2,p3,p4)            {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define A2D_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the VDP profile
+*/
+#define VDP_TRACE_ERROR0(m)                      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m);}
+#define VDP_TRACE_ERROR1(m,p1)                   {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1);}
+#define VDP_TRACE_ERROR2(m,p1,p2)                {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2);}
+#define VDP_TRACE_ERROR3(m,p1,p2,p3)             {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define VDP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define VDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_WARNING0(m)                    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m);}
+#define VDP_TRACE_WARNING1(m,p1)                 {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1);}
+#define VDP_TRACE_WARNING2(m,p1,p2)              {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2);}
+#define VDP_TRACE_WARNING3(m,p1,p2,p3)           {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define VDP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define VDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_EVENT0(m)                      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m);}
+#define VDP_TRACE_EVENT1(m,p1)                   {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m, p1);}
+#define VDP_TRACE_EVENT2(m,p1,p2)                {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2);}
+#define VDP_TRACE_EVENT3(m,p1,p2,p3)             {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define VDP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define VDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_DEBUG0(m)                      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m);}
+#define VDP_TRACE_DEBUG1(m,p1)                   {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1);}
+#define VDP_TRACE_DEBUG2(m,p1,p2)                {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define VDP_TRACE_DEBUG3(m,p1,p2,p3)             {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define VDP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define VDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_API0(m)                        {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API,m);}
+#define VDP_TRACE_API1(m,p1)                     {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API,m, p1);}
+#define VDP_TRACE_API2(m,p1,p2)                  {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2);}
+#define VDP_TRACE_API3(m,p1,p2,p3)               {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3);}
+#define VDP_TRACE_API4(m,p1,p2,p3,p4)            {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define VDP_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the LM unit
+*/
+#define LMP_TRACE_ERROR0(m)                     {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m);}
+#define LMP_TRACE_ERROR1(m,p1)                  {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1);}
+#define LMP_TRACE_ERROR2(m,p1,p2)               {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LMP_TRACE_ERROR3(m,p1,p2,p3)            {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LMP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_WARNING0(m)                   {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m);}
+#define LMP_TRACE_WARNING1(m,p1)                {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1);}
+#define LMP_TRACE_WARNING2(m,p1,p2)             {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LMP_TRACE_WARNING3(m,p1,p2,p3)          {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LMP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_EVENT0(m)                     {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m);}
+#define LMP_TRACE_EVENT1(m,p1)                  {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m, p1);}
+#define LMP_TRACE_EVENT2(m,p1,p2)               {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LMP_TRACE_EVENT3(m,p1,p2,p3)            {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LMP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_DEBUG0(m)                     {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m);}
+#define LMP_TRACE_DEBUG1(m,p1)                  {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1);}
+#define LMP_TRACE_DEBUG2(m,p1,p2)               {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LMP_TRACE_DEBUG3(m,p1,p2,p3)            {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LMP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define LMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the LC unit
+*/
+#define LC_TRACE_ERROR0(m)                     {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m);}
+#define LC_TRACE_ERROR1(m,p1)                  {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1);}
+#define LC_TRACE_ERROR2(m,p1,p2)               {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LC_TRACE_ERROR3(m,p1,p2,p3)            {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LC_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_WARNING0(m)                   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m);}
+#define LC_TRACE_WARNING1(m,p1)                {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1);}
+#define LC_TRACE_WARNING2(m,p1,p2)             {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LC_TRACE_WARNING3(m,p1,p2,p3)          {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LC_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_EVENT0(m)                     {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m);}
+#define LC_TRACE_EVENT1(m,p1)                  {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m, p1);}
+#define LC_TRACE_EVENT2(m,p1,p2)               {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LC_TRACE_EVENT3(m,p1,p2,p3)            {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LC_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_DEBUG0(m)                     {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m);}
+#define LC_TRACE_DEBUG1(m,p1)                  {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1);}
+#define LC_TRACE_DEBUG2(m,p1,p2)               {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LC_TRACE_DEBUG3(m,p1,p2,p3)            {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LC_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the Serial Dongle Application SDA
+*/
+#define SDA_TRACE_ERROR0(m)                     {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(m);}
+#define SDA_TRACE_ERROR1(m,p1)                  {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_ERROR2(m,p1,p2)               {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_ERROR3(m,p1,p2,p3)            {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_WARNING0(m)                   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(m);}
+#define SDA_TRACE_WARNING1(m,p1)                {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_WARNING2(m,p1,p2)             {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_WARNING3(m,p1,p2,p3)          {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_EVENT0(m)                     {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(m);}
+#define SDA_TRACE_EVENT1(m,p1)                  {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(m, p1);}
+#define SDA_TRACE_EVENT2(m,p1,p2)               {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_EVENT3(m,p1,p2,p3)            {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_DEBUG0(m)                     {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(m);}
+#define SDA_TRACE_DEBUG1(m,p1)                  {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_DEBUG2(m,p1,p2)               {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_DEBUG3(m,p1,p2,p3)            {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+/* AVDTP
+*/
+#define AVDT_TRACE_ERROR0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m);}
+#define AVDT_TRACE_ERROR1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1);}
+#define AVDT_TRACE_ERROR2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AVDT_TRACE_ERROR3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AVDT_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_WARNING0(m)                   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m);}
+#define AVDT_TRACE_WARNING1(m,p1)                {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1);}
+#define AVDT_TRACE_WARNING2(m,p1,p2)             {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AVDT_TRACE_WARNING3(m,p1,p2,p3)          {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AVDT_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_EVENT0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m);}
+#define AVDT_TRACE_EVENT1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m, p1);}
+#define AVDT_TRACE_EVENT2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AVDT_TRACE_EVENT3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AVDT_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_DEBUG0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m);}
+#define AVDT_TRACE_DEBUG1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1);}
+#define AVDT_TRACE_DEBUG2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AVDT_TRACE_DEBUG3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AVDT_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_API0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API, m);}
+#define AVDT_TRACE_API1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1);}
+#define AVDT_TRACE_API2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2);}
+#define AVDT_TRACE_API3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AVDT_TRACE_API4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_API5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the AVCTP protocol
+*/
+#define AVCT_TRACE_ERROR0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m);}
+#define AVCT_TRACE_ERROR1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1);}
+#define AVCT_TRACE_ERROR2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AVCT_TRACE_ERROR3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AVCT_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_WARNING0(m)                   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m);}
+#define AVCT_TRACE_WARNING1(m,p1)                {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1);}
+#define AVCT_TRACE_WARNING2(m,p1,p2)             {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AVCT_TRACE_WARNING3(m,p1,p2,p3)          {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AVCT_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_EVENT0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m);}
+#define AVCT_TRACE_EVENT1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m, p1);}
+#define AVCT_TRACE_EVENT2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AVCT_TRACE_EVENT3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AVCT_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_DEBUG0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m);}
+#define AVCT_TRACE_DEBUG1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1);}
+#define AVCT_TRACE_DEBUG2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AVCT_TRACE_DEBUG3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AVCT_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_API0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API, m);}
+#define AVCT_TRACE_API1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1);}
+#define AVCT_TRACE_API2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2);}
+#define AVCT_TRACE_API3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AVCT_TRACE_API4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_API5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the AVRCP profile
+*/
+#define AVRC_TRACE_ERROR0(m)                      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m);}
+#define AVRC_TRACE_ERROR1(m,p1)                   {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1);}
+#define AVRC_TRACE_ERROR2(m,p1,p2)                {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2);}
+#define AVRC_TRACE_ERROR3(m,p1,p2,p3)             {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define AVRC_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_WARNING0(m)                    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m);}
+#define AVRC_TRACE_WARNING1(m,p1)                 {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1);}
+#define AVRC_TRACE_WARNING2(m,p1,p2)              {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2);}
+#define AVRC_TRACE_WARNING3(m,p1,p2,p3)           {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define AVRC_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_EVENT0(m)                      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m);}
+#define AVRC_TRACE_EVENT1(m,p1)                   {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m, p1);}
+#define AVRC_TRACE_EVENT2(m,p1,p2)                {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2);}
+#define AVRC_TRACE_EVENT3(m,p1,p2,p3)             {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define AVRC_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_DEBUG0(m)                      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m);}
+#define AVRC_TRACE_DEBUG1(m,p1)                   {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1);}
+#define AVRC_TRACE_DEBUG2(m,p1,p2)                {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define AVRC_TRACE_DEBUG3(m,p1,p2,p3)             {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define AVRC_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_API0(m)                        {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API,m);}
+#define AVRC_TRACE_API1(m,p1)                     {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API,m, p1);}
+#define AVRC_TRACE_API2(m,p1,p2)                  {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2);}
+#define AVRC_TRACE_API3(m,p1,p2,p3)               {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3);}
+#define AVRC_TRACE_API4(m,p1,p2,p3,p4)            {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+/* MCAP
+*/
+#define MCA_TRACE_ERROR0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m);}
+#define MCA_TRACE_ERROR1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1);}
+#define MCA_TRACE_ERROR2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2);}
+#define MCA_TRACE_ERROR3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define MCA_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define MCA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_WARNING0(m)                   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m);}
+#define MCA_TRACE_WARNING1(m,p1)                {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1);}
+#define MCA_TRACE_WARNING2(m,p1,p2)             {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2);}
+#define MCA_TRACE_WARNING3(m,p1,p2,p3)          {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define MCA_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define MCA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_EVENT0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m);}
+#define MCA_TRACE_EVENT1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m, p1);}
+#define MCA_TRACE_EVENT2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2);}
+#define MCA_TRACE_EVENT3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define MCA_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define MCA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_DEBUG0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m);}
+#define MCA_TRACE_DEBUG1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1);}
+#define MCA_TRACE_DEBUG2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define MCA_TRACE_DEBUG3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define MCA_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define MCA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_API0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_API, m);}
+#define MCA_TRACE_API1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1);}
+#define MCA_TRACE_API2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2);}
+#define MCA_TRACE_API3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3);}
+#define MCA_TRACE_API4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define MCA_TRACE_API5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the AMP unit
+*/
+#define AMP_TRACE_ERROR0(m)                     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m);}
+#define AMP_TRACE_ERROR1(m,p1)                  {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1);}
+#define AMP_TRACE_ERROR2(m,p1,p2)               {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AMP_TRACE_ERROR3(m,p1,p2,p3)            {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AMP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_WARNING0(m)                   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m);}
+#define AMP_TRACE_WARNING1(m,p1)                {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1);}
+#define AMP_TRACE_WARNING2(m,p1,p2)             {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AMP_TRACE_WARNING3(m,p1,p2,p3)          {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AMP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_API0(m)                       {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_API, m);}
+#define AMP_TRACE_API1(m,p1)                    {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1);}
+#define AMP_TRACE_API2(m,p1,p2)                 {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2);}
+#define AMP_TRACE_API3(m,p1,p2,p3)              {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AMP_TRACE_API4(m,p1,p2,p3,p4)           {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AMP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_EVENT0(m)                     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m);}
+#define AMP_TRACE_EVENT1(m,p1)                  {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m, p1);}
+#define AMP_TRACE_EVENT2(m,p1,p2)               {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AMP_TRACE_EVENT3(m,p1,p2,p3)            {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AMP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_DEBUG0(m)                     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m);}
+#define AMP_TRACE_DEBUG1(m,p1)                  {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1);}
+#define AMP_TRACE_DEBUG2(m,p1,p2)               {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AMP_TRACE_DEBUG3(m,p1,p2,p3)            {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AMP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the ATT/GATT unit
+*/
+#define GATT_TRACE_ERROR0(m)                     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m);}
+#define GATT_TRACE_ERROR1(m,p1)                  {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1);}
+#define GATT_TRACE_ERROR2(m,p1,p2)               {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GATT_TRACE_ERROR3(m,p1,p2,p3)            {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GATT_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GATT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_WARNING0(m)                   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m);}
+#define GATT_TRACE_WARNING1(m,p1)                {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1);}
+#define GATT_TRACE_WARNING2(m,p1,p2)             {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GATT_TRACE_WARNING3(m,p1,p2,p3)          {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GATT_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GATT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_API0(m)                       {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_API, m);}
+#define GATT_TRACE_API1(m,p1)                    {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1);}
+#define GATT_TRACE_API2(m,p1,p2)                 {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2);}
+#define GATT_TRACE_API3(m,p1,p2,p3)              {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GATT_TRACE_API4(m,p1,p2,p3,p4)           {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GATT_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_EVENT0(m)                     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m);}
+#define GATT_TRACE_EVENT1(m,p1)                  {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m, p1);}
+#define GATT_TRACE_EVENT2(m,p1,p2)               {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GATT_TRACE_EVENT3(m,p1,p2,p3)            {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GATT_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GATT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_DEBUG0(m)                     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m);}
+#define GATT_TRACE_DEBUG1(m,p1)                  {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1);}
+#define GATT_TRACE_DEBUG2(m,p1,p2)               {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define GATT_TRACE_DEBUG3(m,p1,p2,p3)            {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define GATT_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define GATT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the SMP unit
+*/
+#define SMP_TRACE_ERROR0(m)                     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m);}
+#define SMP_TRACE_ERROR1(m,p1)                  {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1);}
+#define SMP_TRACE_ERROR2(m,p1,p2)               {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SMP_TRACE_ERROR3(m,p1,p2,p3)            {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SMP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_WARNING0(m)                   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m);}
+#define SMP_TRACE_WARNING1(m,p1)                {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1);}
+#define SMP_TRACE_WARNING2(m,p1,p2)             {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SMP_TRACE_WARNING3(m,p1,p2,p3)          {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SMP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_API0(m)                       {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_API, m);}
+#define SMP_TRACE_API1(m,p1)                    {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1);}
+#define SMP_TRACE_API2(m,p1,p2)                 {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2);}
+#define SMP_TRACE_API3(m,p1,p2,p3)              {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SMP_TRACE_API4(m,p1,p2,p3,p4)           {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SMP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_EVENT0(m)                     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m);}
+#define SMP_TRACE_EVENT1(m,p1)                  {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m, p1);}
+#define SMP_TRACE_EVENT2(m,p1,p2)               {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SMP_TRACE_EVENT3(m,p1,p2,p3)            {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SMP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_DEBUG0(m)                     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m);}
+#define SMP_TRACE_DEBUG1(m,p1)                  {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1);}
+#define SMP_TRACE_DEBUG2(m,p1,p2)               {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SMP_TRACE_DEBUG3(m,p1,p2,p3)            {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SMP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* END OF USE TRACES */
+#else
+
+#define BT_TRACE_0(l,t,m)
+#define BT_TRACE_1(l,t,m,p1)
+#define BT_TRACE_2(l,t,m,p1,p2)
+#define BT_TRACE_3(l,t,m,p1,p2,p3)
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)
+
+#define BT_ERROR_TRACE_0(l,m)
+#define BT_ERROR_TRACE_1(l,m,p1)
+#define BT_ERROR_TRACE_2(l,m,p1,p2)
+#define BT_ERROR_TRACE_3(l,m,p1,p2,p3)
+
+/* Define tracing for the HCI unit
+*/
+#define HCI_TRACE_ERROR0(m)
+#define HCI_TRACE_ERROR1(m,p1)
+#define HCI_TRACE_ERROR2(m,p1,p2)
+#define HCI_TRACE_ERROR3(m,p1,p2,p3)
+#define HCI_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_WARNING0(m)
+#define HCI_TRACE_WARNING1(m,p1)
+#define HCI_TRACE_WARNING2(m,p1,p2)
+#define HCI_TRACE_WARNING3(m,p1,p2,p3)
+#define HCI_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_EVENT0(m)
+#define HCI_TRACE_EVENT1(m,p1)
+#define HCI_TRACE_EVENT2(m,p1,p2)
+#define HCI_TRACE_EVENT3(m,p1,p2,p3)
+#define HCI_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_DEBUG0(m)
+#define HCI_TRACE_DEBUG1(m,p1)
+#define HCI_TRACE_DEBUG2(m,p1,p2)
+#define HCI_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCI_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for BTM
+*/
+#define BTM_TRACE_ERROR0(m)
+#define BTM_TRACE_ERROR1(m,p1)
+#define BTM_TRACE_ERROR2(m,p1,p2)
+#define BTM_TRACE_ERROR3(m,p1,p2,p3)
+#define BTM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BTM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_WARNING0(m)
+#define BTM_TRACE_WARNING1(m,p1)
+#define BTM_TRACE_WARNING2(m,p1,p2)
+#define BTM_TRACE_WARNING3(m,p1,p2,p3)
+#define BTM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BTM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_API0(m)
+#define BTM_TRACE_API1(m,p1)
+#define BTM_TRACE_API2(m,p1,p2)
+#define BTM_TRACE_API3(m,p1,p2,p3)
+#define BTM_TRACE_API4(m,p1,p2,p3,p4)
+#define BTM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_EVENT0(m)
+#define BTM_TRACE_EVENT1(m,p1)
+#define BTM_TRACE_EVENT2(m,p1,p2)
+#define BTM_TRACE_EVENT3(m,p1,p2,p3)
+#define BTM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BTM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_DEBUG0(m)
+#define BTM_TRACE_DEBUG1(m,p1)
+#define BTM_TRACE_DEBUG2(m,p1,p2)
+#define BTM_TRACE_DEBUG3(m,p1,p2,p3)
+#define BTM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BTM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the L2CAP unit
+*/
+#define L2CAP_TRACE_ERROR0(m)
+#define L2CAP_TRACE_ERROR1(m,p1)
+#define L2CAP_TRACE_ERROR2(m,p1,p2)
+#define L2CAP_TRACE_ERROR3(m,p1,p2,p3)
+#define L2CAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_WARNING0(m)
+#define L2CAP_TRACE_WARNING1(m,p1)
+#define L2CAP_TRACE_WARNING2(m,p1,p2)
+#define L2CAP_TRACE_WARNING3(m,p1,p2,p3)
+#define L2CAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_API0(m)
+#define L2CAP_TRACE_API1(m,p1)
+#define L2CAP_TRACE_API2(m,p1,p2)
+#define L2CAP_TRACE_API3(m,p1,p2,p3)
+#define L2CAP_TRACE_API4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_EVENT0(m)
+#define L2CAP_TRACE_EVENT1(m,p1)
+#define L2CAP_TRACE_EVENT2(m,p1,p2)
+#define L2CAP_TRACE_EVENT3(m,p1,p2,p3)
+#define L2CAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_DEBUG0(m)
+#define L2CAP_TRACE_DEBUG1(m,p1)
+#define L2CAP_TRACE_DEBUG2(m,p1,p2)
+#define L2CAP_TRACE_DEBUG3(m,p1,p2,p3)
+#define L2CAP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m)
+#define LLCP_TRACE_ERROR1(m,p1)
+#define LLCP_TRACE_ERROR2(m,p1,p2)
+#define LLCP_TRACE_ERROR3(m,p1,p2,p3)
+#define LLCP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_WARNING0(m)
+#define LLCP_TRACE_WARNING1(m,p1)
+#define LLCP_TRACE_WARNING2(m,p1,p2)
+#define LLCP_TRACE_WARNING3(m,p1,p2,p3)
+#define LLCP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_API0(m)
+#define LLCP_TRACE_API1(m,p1)
+#define LLCP_TRACE_API2(m,p1,p2)
+#define LLCP_TRACE_API3(m,p1,p2,p3)
+#define LLCP_TRACE_API4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_EVENT0(m)
+#define LLCP_TRACE_EVENT1(m,p1)
+#define LLCP_TRACE_EVENT2(m,p1,p2)
+#define LLCP_TRACE_EVENT3(m,p1,p2,p3)
+#define LLCP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_DEBUG0(m)
+#define LLCP_TRACE_DEBUG1(m,p1)
+#define LLCP_TRACE_DEBUG2(m,p1,p2)
+#define LLCP_TRACE_DEBUG3(m,p1,p2,p3)
+#define LLCP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the SDP unit
+*/
+#define SDP_TRACE_ERROR0(m)
+#define SDP_TRACE_ERROR1(m,p1)
+#define SDP_TRACE_ERROR2(m,p1,p2)
+#define SDP_TRACE_ERROR3(m,p1,p2,p3)
+#define SDP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_WARNING0(m)
+#define SDP_TRACE_WARNING1(m,p1)
+#define SDP_TRACE_WARNING2(m,p1,p2)
+#define SDP_TRACE_WARNING3(m,p1,p2,p3)
+#define SDP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_API0(m)
+#define SDP_TRACE_API1(m,p1)
+#define SDP_TRACE_API2(m,p1,p2)
+#define SDP_TRACE_API3(m,p1,p2,p3)
+#define SDP_TRACE_API4(m,p1,p2,p3,p4)
+#define SDP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_EVENT0(m)
+#define SDP_TRACE_EVENT1(m,p1)
+#define SDP_TRACE_EVENT2(m,p1,p2)
+#define SDP_TRACE_EVENT3(m,p1,p2,p3)
+#define SDP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_DEBUG0(m)
+#define SDP_TRACE_DEBUG1(m,p1)
+#define SDP_TRACE_DEBUG2(m,p1,p2)
+#define SDP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SDP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the RFCOMM unit
+*/
+#define RFCOMM_TRACE_ERROR0(m)
+#define RFCOMM_TRACE_ERROR1(m,p1)
+#define RFCOMM_TRACE_ERROR2(m,p1,p2)
+#define RFCOMM_TRACE_ERROR3(m,p1,p2,p3)
+#define RFCOMM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_WARNING0(m)
+#define RFCOMM_TRACE_WARNING1(m,p1)
+#define RFCOMM_TRACE_WARNING2(m,p1,p2)
+#define RFCOMM_TRACE_WARNING3(m,p1,p2,p3)
+#define RFCOMM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_API0(m)
+#define RFCOMM_TRACE_API1(m,p1)
+#define RFCOMM_TRACE_API2(m,p1,p2)
+#define RFCOMM_TRACE_API3(m,p1,p2,p3)
+#define RFCOMM_TRACE_API4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_EVENT0(m)
+#define RFCOMM_TRACE_EVENT1(m,p1)
+#define RFCOMM_TRACE_EVENT2(m,p1,p2)
+#define RFCOMM_TRACE_EVENT3(m,p1,p2,p3)
+#define RFCOMM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_DEBUG0(m)
+#define RFCOMM_TRACE_DEBUG1(m,p1)
+#define RFCOMM_TRACE_DEBUG2(m,p1,p2)
+#define RFCOMM_TRACE_DEBUG3(m,p1,p2,p3)
+#define RFCOMM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for Serial Port Profile
+*/
+#define SPP_TRACE_ERROR0(m)
+#define SPP_TRACE_ERROR1(m,p1)
+#define SPP_TRACE_ERROR2(m,p1,p2)
+#define SPP_TRACE_ERROR3(m,p1,p2,p3)
+#define SPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_WARNING0(m)
+#define SPP_TRACE_WARNING1(m,p1)
+#define SPP_TRACE_WARNING2(m,p1,p2)
+#define SPP_TRACE_WARNING3(m,p1,p2,p3)
+#define SPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_EVENT0(m)
+#define SPP_TRACE_EVENT1(m,p1)
+#define SPP_TRACE_EVENT2(m,p1,p2)
+#define SPP_TRACE_EVENT3(m,p1,p2,p3)
+#define SPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_API0(m)
+#define SPP_TRACE_API1(m,p1)
+#define SPP_TRACE_API2(m,p1,p2)
+#define SPP_TRACE_API3(m,p1,p2,p3)
+#define SPP_TRACE_API4(m,p1,p2,p3,p4)
+#define SPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_DEBUG0(m)
+#define SPP_TRACE_DEBUG1(m,p1)
+#define SPP_TRACE_DEBUG2(m,p1,p2)
+#define SPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Generic Access Profile traces */
+#define GAP_TRACE_ERROR0(m)
+#define GAP_TRACE_ERROR1(m,p1)
+#define GAP_TRACE_ERROR2(m,p1,p2)
+#define GAP_TRACE_ERROR3(m,p1,p2,p3)
+#define GAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_EVENT0(m)
+#define GAP_TRACE_EVENT1(m,p1)
+#define GAP_TRACE_EVENT2(m,p1,p2)
+#define GAP_TRACE_EVENT3(m,p1,p2,p3)
+#define GAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_API0(m)
+#define GAP_TRACE_API1(m,p1)
+#define GAP_TRACE_API2(m,p1,p2)
+#define GAP_TRACE_API3(m,p1,p2,p3)
+#define GAP_TRACE_API4(m,p1,p2,p3,p4)
+#define GAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_WARNING0(m)
+#define GAP_TRACE_WARNING1(m,p1)
+#define GAP_TRACE_WARNING2(m,p1,p2)
+#define GAP_TRACE_WARNING3(m,p1,p2,p3)
+#define GAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for OBX
+*/
+#define OBX_TRACE_ERROR0(m)
+#define OBX_TRACE_ERROR1(m,p1)
+#define OBX_TRACE_ERROR2(m,p1,p2)
+#define OBX_TRACE_ERROR3(m,p1,p2,p3)
+#define OBX_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define OBX_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_WARNING0(m)
+#define OBX_TRACE_WARNING1(m,p1)
+#define OBX_TRACE_WARNING2(m,p1,p2)
+#define OBX_TRACE_WARNING3(m,p1,p2,p3)
+#define OBX_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define OBX_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_EVENT0(m)
+#define OBX_TRACE_EVENT1(m,p1)
+#define OBX_TRACE_EVENT2(m,p1,p2)
+#define OBX_TRACE_EVENT3(m,p1,p2,p3)
+#define OBX_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define OBX_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_DEBUG0(m)
+#define OBX_TRACE_DEBUG1(m,p1)
+#define OBX_TRACE_DEBUG2(m,p1,p2)
+#define OBX_TRACE_DEBUG3(m,p1,p2,p3)
+#define OBX_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define OBX_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_API0(m)
+#define OBX_TRACE_API1(m,p1)
+#define OBX_TRACE_API2(m,p1,p2)
+#define OBX_TRACE_API3(m,p1,p2,p3)
+#define OBX_TRACE_API4(m,p1,p2,p3,p4)
+#define OBX_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for GOEP application profiles
+*/
+#define GOEP_TRACE_ERROR0(m)
+#define GOEP_TRACE_ERROR1(m,p1)
+#define GOEP_TRACE_ERROR2(m,p1,p2)
+#define GOEP_TRACE_ERROR3(m,p1,p2,p3)
+#define GOEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_WARNING0(m)
+#define GOEP_TRACE_WARNING1(m,p1)
+#define GOEP_TRACE_WARNING2(m,p1,p2)
+#define GOEP_TRACE_WARNING3(m,p1,p2,p3)
+#define GOEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_EVENT0(m)
+#define GOEP_TRACE_EVENT1(m,p1)
+#define GOEP_TRACE_EVENT2(m,p1,p2)
+#define GOEP_TRACE_EVENT3(m,p1,p2,p3)
+#define GOEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_DEBUG0(m)
+#define GOEP_TRACE_DEBUG1(m,p1)
+#define GOEP_TRACE_DEBUG2(m,p1,p2)
+#define GOEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define GOEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_API0(m)
+#define GOEP_TRACE_API1(m,p1)
+#define GOEP_TRACE_API2(m,p1,p2)
+#define GOEP_TRACE_API3(m,p1,p2,p3)
+#define GOEP_TRACE_API4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the BPP profile
+*/
+#define BPP_TRACE_ERROR0(m)
+#define BPP_TRACE_ERROR1(m,p1)
+#define BPP_TRACE_ERROR2(m,p1,p2)
+#define BPP_TRACE_ERROR3(m,p1,p2,p3)
+#define BPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_WARNING0(m)
+#define BPP_TRACE_WARNING1(m,p1)
+#define BPP_TRACE_WARNING2(m,p1,p2)
+#define BPP_TRACE_WARNING3(m,p1,p2,p3)
+#define BPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_EVENT0(m)
+#define BPP_TRACE_EVENT1(m,p1)
+#define BPP_TRACE_EVENT2(m,p1,p2)
+#define BPP_TRACE_EVENT3(m,p1,p2,p3)
+#define BPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_DEBUG0(m)
+#define BPP_TRACE_DEBUG1(m,p1)
+#define BPP_TRACE_DEBUG2(m,p1,p2)
+#define BPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_API0(m)
+#define BPP_TRACE_API1(m,p1)
+#define BPP_TRACE_API2(m,p1,p2)
+#define BPP_TRACE_API3(m,p1,p2,p3)
+#define BPP_TRACE_API4(m,p1,p2,p3,p4)
+#define BPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the BIP profile
+*/
+#define BIP_TRACE_ERROR0(m)
+#define BIP_TRACE_ERROR1(m,p1)
+#define BIP_TRACE_ERROR2(m,p1,p2)
+#define BIP_TRACE_ERROR3(m,p1,p2,p3)
+#define BIP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BIP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_WARNING0(m)
+#define BIP_TRACE_WARNING1(m,p1)
+#define BIP_TRACE_WARNING2(m,p1,p2)
+#define BIP_TRACE_WARNING3(m,p1,p2,p3)
+#define BIP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BIP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_EVENT0(m)
+#define BIP_TRACE_EVENT1(m,p1)
+#define BIP_TRACE_EVENT2(m,p1,p2)
+#define BIP_TRACE_EVENT3(m,p1,p2,p3)
+#define BIP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BIP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_DEBUG0(m)
+#define BIP_TRACE_DEBUG1(m,p1)
+#define BIP_TRACE_DEBUG2(m,p1,p2)
+#define BIP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BIP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BIP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_API0(m)
+#define BIP_TRACE_API1(m,p1)
+#define BIP_TRACE_API2(m,p1,p2)
+#define BIP_TRACE_API3(m,p1,p2,p3)
+#define BIP_TRACE_API4(m,p1,p2,p3,p4)
+#define BIP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for TCS
+*/
+#define TCS_TRACE_ERROR0(m)
+#define TCS_TRACE_ERROR1(m,p1)
+#define TCS_TRACE_ERROR2(m,p1,p2)
+#define TCS_TRACE_ERROR3(m,p1,p2,p3)
+#define TCS_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define TCS_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_WARNING0(m)
+#define TCS_TRACE_WARNING1(m,p1)
+#define TCS_TRACE_WARNING2(m,p1,p2)
+#define TCS_TRACE_WARNING3(m,p1,p2,p3)
+#define TCS_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define TCS_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_EVENT0(m)
+#define TCS_TRACE_EVENT1(m,p1)
+#define TCS_TRACE_EVENT2(m,p1,p2)
+#define TCS_TRACE_EVENT3(m,p1,p2,p3)
+#define TCS_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define TCS_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_DEBUG0(m)
+#define TCS_TRACE_DEBUG1(m,p1)
+#define TCS_TRACE_DEBUG2(m,p1,p2)
+#define TCS_TRACE_DEBUG3(m,p1,p2,p3)
+#define TCS_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define TCS_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_API0(m)
+#define TCS_TRACE_API1(m,p1)
+#define TCS_TRACE_API2(m,p1,p2)
+#define TCS_TRACE_API3(m,p1,p2,p3)
+#define TCS_TRACE_API4(m,p1,p2,p3,p4)
+#define TCS_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for ICP
+*/
+#define ICP_TRACE_ERROR0(m)
+#define ICP_TRACE_ERROR1(m,p1)
+#define ICP_TRACE_ERROR2(m,p1,p2)
+#define ICP_TRACE_ERROR3(m,p1,p2,p3)
+#define ICP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define ICP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_WARNING0(m)
+#define ICP_TRACE_WARNING1(m,p1)
+#define ICP_TRACE_WARNING2(m,p1,p2)
+#define ICP_TRACE_WARNING3(m,p1,p2,p3)
+#define ICP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define ICP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_EVENT0(m)
+#define ICP_TRACE_EVENT1(m,p1)
+#define ICP_TRACE_EVENT2(m,p1,p2)
+#define ICP_TRACE_EVENT3(m,p1,p2,p3)
+#define ICP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define ICP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_DEBUG0(m)
+#define ICP_TRACE_DEBUG1(m,p1)
+#define ICP_TRACE_DEBUG2(m,p1,p2)
+#define ICP_TRACE_DEBUG3(m,p1,p2,p3)
+#define ICP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define ICP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_API0(m)
+#define ICP_TRACE_API1(m,p1)
+#define ICP_TRACE_API2(m,p1,p2)
+#define ICP_TRACE_API3(m,p1,p2,p3)
+#define ICP_TRACE_API4(m,p1,p2,p3,p4)
+#define ICP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for CTP
+*/
+#define CTP_TRACE_ERROR0(m)
+#define CTP_TRACE_ERROR1(m,p1)
+#define CTP_TRACE_ERROR2(m,p1,p2)
+#define CTP_TRACE_ERROR3(m,p1,p2,p3)
+#define CTP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_WARNING0(m)
+#define CTP_TRACE_WARNING1(m,p1)
+#define CTP_TRACE_WARNING2(m,p1,p2)
+#define CTP_TRACE_WARNING3(m,p1,p2,p3)
+#define CTP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_EVENT0(m)
+#define CTP_TRACE_EVENT1(m,p1)
+#define CTP_TRACE_EVENT2(m,p1,p2)
+#define CTP_TRACE_EVENT3(m,p1,p2,p3)
+#define CTP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_DEBUG0(m)
+#define CTP_TRACE_DEBUG1(m,p1)
+#define CTP_TRACE_DEBUG2(m,p1,p2)
+#define CTP_TRACE_DEBUG3(m,p1,p2,p3)
+#define CTP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_API0(m)
+#define CTP_TRACE_API1(m,p1)
+#define CTP_TRACE_API2(m,p1,p2)
+#define CTP_TRACE_API3(m,p1,p2,p3)
+#define CTP_TRACE_API4(m,p1,p2,p3,p4)
+#define CTP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for headset profile */
+
+#define HSP2_TRACE_ERROR0(pcb,m)
+#define HSP2_TRACE_ERROR1(pcb,m,p1)
+#define HSP2_TRACE_ERROR2(pcb,m,p1,p2)
+#define HSP2_TRACE_ERROR3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_ERROR4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_ERROR5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_ERROR6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_WARNING0(pcb,m)
+#define HSP2_TRACE_WARNING1(pcb,m,p1)
+#define HSP2_TRACE_WARNING2(pcb,m,p1,p2)
+#define HSP2_TRACE_WARNING3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_WARNING4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_WARNING5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_WARNING6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_API0(pcb,m)
+#define HSP2_TRACE_API1(pcb,m,p1)
+#define HSP2_TRACE_API2(pcb,m,p1,p2)
+#define HSP2_TRACE_API3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_API4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_API5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_API6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_EVENT0(pcb,m)
+#define HSP2_TRACE_EVENT1(pcb,m,p1)
+#define HSP2_TRACE_EVENT2(pcb,m,p1,p2)
+#define HSP2_TRACE_EVENT3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_EVENT4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_EVENT5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_EVENT6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_DEBUG0(pcb,m)
+#define HSP2_TRACE_DEBUG1(pcb,m,p1)
+#define HSP2_TRACE_DEBUG2(pcb,m,p1,p2)
+#define HSP2_TRACE_DEBUG3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_DEBUG4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_DEBUG5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_DEBUG6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m)
+#define NFC_TRACE_ERROR1(m,p1)
+#define NFC_TRACE_ERROR2(m,p1,p2)
+#define NFC_TRACE_ERROR3(m,p1,p2,p3)
+#define NFC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NFC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_WARNING0(m)
+#define NFC_TRACE_WARNING1(m,p1)
+#define NFC_TRACE_WARNING2(m,p1,p2)
+#define NFC_TRACE_WARNING3(m,p1,p2,p3)
+#define NFC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NFC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_API0(m)
+#define NFC_TRACE_API1(m,p1)
+#define NFC_TRACE_API2(m,p1,p2)
+#define NFC_TRACE_API3(m,p1,p2,p3)
+#define NFC_TRACE_API4(m,p1,p2,p3,p4)
+#define NFC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_EVENT0(m)
+#define NFC_TRACE_EVENT1(m,p1)
+#define NFC_TRACE_EVENT2(m,p1,p2)
+#define NFC_TRACE_EVENT3(m,p1,p2,p3)
+#define NFC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NFC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_DEBUG0(m)
+#define NFC_TRACE_DEBUG1(m,p1)
+#define NFC_TRACE_DEBUG2(m,p1,p2)
+#define NFC_TRACE_DEBUG3(m,p1,p2,p3)
+#define NFC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NFC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_ERROR0(m)
+#define NCI_TRACE_ERROR1(m,p1)
+#define NCI_TRACE_ERROR2(m,p1,p2)
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_WARNING0(m)
+#define NCI_TRACE_WARNING1(m,p1)
+#define NCI_TRACE_WARNING2(m,p1,p2)
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_API0(m)
+#define NCI_TRACE_API1(m,p1)
+#define NCI_TRACE_API2(m,p1,p2)
+#define NCI_TRACE_API3(m,p1,p2,p3)
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_EVENT0(m)
+#define NCI_TRACE_EVENT1(m,p1)
+#define NCI_TRACE_EVENT2(m,p1,p2)
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_DEBUG0(m)
+#define NCI_TRACE_DEBUG1(m,p1)
+#define NCI_TRACE_DEBUG2(m,p1,p2)
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_ERROR0(m)
+#define RW_TRACE_ERROR1(m,p1)
+#define RW_TRACE_ERROR2(m,p1,p2)
+#define RW_TRACE_ERROR3(m,p1,p2,p3)
+#define RW_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RW_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_WARNING0(m)
+#define RW_TRACE_WARNING1(m,p1)
+#define RW_TRACE_WARNING2(m,p1,p2)
+#define RW_TRACE_WARNING3(m,p1,p2,p3)
+#define RW_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RW_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) }
+
+#define RW_TRACE_API0(m)
+#define RW_TRACE_API1(m,p1)
+#define RW_TRACE_API2(m,p1,p2)
+#define RW_TRACE_API3(m,p1,p2,p3)
+#define RW_TRACE_API4(m,p1,p2,p3,p4)
+#define RW_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_EVENT0(m)
+#define RW_TRACE_EVENT1(m,p1)
+#define RW_TRACE_EVENT2(m,p1,p2)
+#define RW_TRACE_EVENT3(m,p1,p2,p3)
+#define RW_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RW_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_DEBUG0(m)
+#define RW_TRACE_DEBUG1(m,p1)
+#define RW_TRACE_DEBUG2(m,p1,p2)
+#define RW_TRACE_DEBUG3(m,p1,p2,p3)
+#define RW_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RW_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_ERROR0(m)
+#define CE_TRACE_ERROR1(m,p1)
+#define CE_TRACE_ERROR2(m,p1,p2)
+#define CE_TRACE_ERROR3(m,p1,p2,p3)
+#define CE_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CE_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_WARNING0(m)
+#define CE_TRACE_WARNING1(m,p1)
+#define CE_TRACE_WARNING2(m,p1,p2)
+#define CE_TRACE_WARNING3(m,p1,p2,p3)
+#define CE_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CE_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_API0(m)
+#define CE_TRACE_API1(m,p1)
+#define CE_TRACE_API2(m,p1,p2)
+#define CE_TRACE_API3(m,p1,p2,p3)
+#define CE_TRACE_API4(m,p1,p2,p3,p4)
+#define CE_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_EVENT0(m)
+#define CE_TRACE_EVENT1(m,p1)
+#define CE_TRACE_EVENT2(m,p1,p2)
+#define CE_TRACE_EVENT3(m,p1,p2,p3)
+#define CE_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CE_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_DEBUG0(m)
+#define CE_TRACE_DEBUG1(m,p1)
+#define CE_TRACE_DEBUG2(m,p1,p2)
+#define CE_TRACE_DEBUG3(m,p1,p2,p3)
+#define CE_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CE_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_ERROR0(m)
+#define NDEF_TRACE_ERROR1(m,p1)
+#define NDEF_TRACE_ERROR2(m,p1,p2)
+#define NDEF_TRACE_ERROR3(m,p1,p2,p3)
+#define NDEF_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_WARNING0(m)
+#define NDEF_TRACE_WARNING1(m,p1)
+#define NDEF_TRACE_WARNING2(m,p1,p2)
+#define NDEF_TRACE_WARNING3(m,p1,p2,p3)
+#define NDEF_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_API0(m)
+#define NDEF_TRACE_API1(m,p1)
+#define NDEF_TRACE_API2(m,p1,p2)
+#define NDEF_TRACE_API3(m,p1,p2,p3)
+#define NDEF_TRACE_API4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_EVENT0(m)
+#define NDEF_TRACE_EVENT1(m,p1)
+#define NDEF_TRACE_EVENT2(m,p1,p2)
+#define NDEF_TRACE_EVENT3(m,p1,p2,p3)
+#define NDEF_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_DEBUG0(m)
+#define NDEF_TRACE_DEBUG1(m,p1)
+#define NDEF_TRACE_DEBUG2(m,p1,p2)
+#define NDEF_TRACE_DEBUG3(m,p1,p2,p3)
+#define NDEF_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m)
+#define NFA_TRACE_ERROR1(m,p1)
+#define NFA_TRACE_ERROR2(m,p1,p2)
+#define NFA_TRACE_ERROR3(m,p1,p2,p3)
+#define NFA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NFA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_WARNING0(m)
+#define NFA_TRACE_WARNING1(m,p1)
+#define NFA_TRACE_WARNING2(m,p1,p2)
+#define NFA_TRACE_WARNING3(m,p1,p2,p3)
+#define NFA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NFA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_API0(m)
+#define NFA_TRACE_API1(m,p1)
+#define NFA_TRACE_API2(m,p1,p2)
+#define NFA_TRACE_API3(m,p1,p2,p3)
+#define NFA_TRACE_API4(m,p1,p2,p3,p4)
+#define NFA_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_EVENT0(m)
+#define NFA_TRACE_EVENT1(m,p1)
+#define NFA_TRACE_EVENT2(m,p1,p2)
+#define NFA_TRACE_EVENT3(m,p1,p2,p3)
+#define NFA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NFA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_DEBUG0(m)
+#define NFA_TRACE_DEBUG1(m,p1)
+#define NFA_TRACE_DEBUG2(m,p1,p2)
+#define NFA_TRACE_DEBUG3(m,p1,p2,p3)
+#define NFA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NFA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m)
+#define P2P_TRACE_ERROR1(m,p1)
+#define P2P_TRACE_ERROR2(m,p1,p2)
+#define P2P_TRACE_ERROR3(m,p1,p2,p3)
+#define P2P_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define P2P_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_WARNING0(m)
+#define P2P_TRACE_WARNING1(m,p1)
+#define P2P_TRACE_WARNING2(m,p1,p2)
+#define P2P_TRACE_WARNING3(m,p1,p2,p3)
+#define P2P_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define P2P_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_API0(m)
+#define P2P_TRACE_API1(m,p1)
+#define P2P_TRACE_API2(m,p1,p2)
+#define P2P_TRACE_API3(m,p1,p2,p3)
+#define P2P_TRACE_API4(m,p1,p2,p3,p4)
+#define P2P_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_EVENT0(m)
+#define P2P_TRACE_EVENT1(m,p1)
+#define P2P_TRACE_EVENT2(m,p1,p2)
+#define P2P_TRACE_EVENT3(m,p1,p2,p3)
+#define P2P_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define P2P_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_DEBUG0(m)
+#define P2P_TRACE_DEBUG1(m,p1)
+#define P2P_TRACE_DEBUG2(m,p1,p2)
+#define P2P_TRACE_DEBUG3(m,p1,p2,p3)
+#define P2P_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define P2P_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA CHO unit
+*/
+#define CHO_TRACE_ERROR0(m)
+#define CHO_TRACE_ERROR1(m,p1)
+#define CHO_TRACE_ERROR2(m,p1,p2)
+#define CHO_TRACE_ERROR3(m,p1,p2,p3)
+#define CHO_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CHO_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_WARNING0(m)
+#define CHO_TRACE_WARNING1(m,p1)
+#define CHO_TRACE_WARNING2(m,p1,p2)
+#define CHO_TRACE_WARNING3(m,p1,p2,p3)
+#define CHO_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CHO_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_API0(m)
+#define CHO_TRACE_API1(m,p1)
+#define CHO_TRACE_API2(m,p1,p2)
+#define CHO_TRACE_API3(m,p1,p2,p3)
+#define CHO_TRACE_API4(m,p1,p2,p3,p4)
+#define CHO_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_EVENT0(m)
+#define CHO_TRACE_EVENT1(m,p1)
+#define CHO_TRACE_EVENT2(m,p1,p2)
+#define CHO_TRACE_EVENT3(m,p1,p2,p3)
+#define CHO_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CHO_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_DEBUG0(m)
+#define CHO_TRACE_DEBUG1(m,p1)
+#define CHO_TRACE_DEBUG2(m,p1,p2)
+#define CHO_TRACE_DEBUG3(m,p1,p2,p3)
+#define CHO_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CHO_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA SNEP unit
+*/
+#define SNEP_TRACE_ERROR0(m)
+#define SNEP_TRACE_ERROR1(m,p1)
+#define SNEP_TRACE_ERROR2(m,p1,p2)
+#define SNEP_TRACE_ERROR3(m,p1,p2,p3)
+#define SNEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_WARNING0(m)
+#define SNEP_TRACE_WARNING1(m,p1)
+#define SNEP_TRACE_WARNING2(m,p1,p2)
+#define SNEP_TRACE_WARNING3(m,p1,p2,p3)
+#define SNEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_API0(m)
+#define SNEP_TRACE_API1(m,p1)
+#define SNEP_TRACE_API2(m,p1,p2)
+#define SNEP_TRACE_API3(m,p1,p2,p3)
+#define SNEP_TRACE_API4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_EVENT0(m)
+#define SNEP_TRACE_EVENT1(m,p1)
+#define SNEP_TRACE_EVENT2(m,p1,p2)
+#define SNEP_TRACE_EVENT3(m,p1,p2,p3)
+#define SNEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_DEBUG0(m)
+#define SNEP_TRACE_DEBUG1(m,p1)
+#define SNEP_TRACE_DEBUG2(m,p1,p2)
+#define SNEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* define traces for HID Host */
+#define HIDH_TRACE_ERROR0(m)
+#define HIDH_TRACE_ERROR1(m,p1)
+#define HIDH_TRACE_ERROR2(m,p1,p2)
+#define HIDH_TRACE_ERROR3(m,p1,p2,p3)
+#define HIDH_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_WARNING0(m)
+#define HIDH_TRACE_WARNING1(m,p1)
+#define HIDH_TRACE_WARNING2(m,p1,p2)
+#define HIDH_TRACE_WARNING3(m,p1,p2,p3)
+#define HIDH_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_API0(m)
+#define HIDH_TRACE_API1(m,p1)
+#define HIDH_TRACE_API2(m,p1,p2)
+#define HIDH_TRACE_API3(m,p1,p2,p3)
+#define HIDH_TRACE_API4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_EVENT0(m)
+#define HIDH_TRACE_EVENT1(m,p1)
+#define HIDH_TRACE_EVENT2(m,p1,p2)
+#define HIDH_TRACE_EVENT3(m,p1,p2,p3)
+#define HIDH_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_DEBUG0(m)
+#define HIDH_TRACE_DEBUG1(m,p1)
+#define HIDH_TRACE_DEBUG2(m,p1,p2)
+#define HIDH_TRACE_DEBUG3(m,p1,p2,p3)
+#define HIDH_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for HID Device */
+#define HIDD_TRACE_ERROR0(m)
+#define HIDD_TRACE_ERROR1(m,p1)
+#define HIDD_TRACE_ERROR2(m,p1,p2)
+#define HIDD_TRACE_ERROR3(m,p1,p2,p3)
+#define HIDD_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_WARNING0(m)
+#define HIDD_TRACE_WARNING1(m,p1)
+#define HIDD_TRACE_WARNING2(m,p1,p2)
+#define HIDD_TRACE_WARNING3(m,p1,p2,p3)
+#define HIDD_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_API0(m)
+#define HIDD_TRACE_API1(m,p1)
+#define HIDD_TRACE_API2(m,p1,p2)
+#define HIDD_TRACE_API3(m,p1,p2,p3)
+#define HIDD_TRACE_API4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_EVENT0(m)
+#define HIDD_TRACE_EVENT1(m,p1)
+#define HIDD_TRACE_EVENT2(m,p1,p2)
+#define HIDD_TRACE_EVENT3(m,p1,p2,p3)
+#define HIDD_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_DEBUG0(m)
+#define HIDD_TRACE_DEBUG1(m,p1)
+#define HIDD_TRACE_DEBUG2(m,p1,p2)
+#define HIDD_TRACE_DEBUG3(m,p1,p2,p3)
+#define HIDD_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for DUN */
+
+#define DUN_TRACE_ERROR0(m)
+#define DUN_TRACE_ERROR1(m,p1)
+#define DUN_TRACE_ERROR2(m,p1,p2)
+#define DUN_TRACE_ERROR3(m,p1,p2,p3)
+#define DUN_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define DUN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_WARNING0(m)
+#define DUN_TRACE_WARNING1(m,p1)
+#define DUN_TRACE_WARNING2(m,p1,p2)
+#define DUN_TRACE_WARNING3(m,p1,p2,p3)
+#define DUN_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DUN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_API0(m)
+#define DUN_TRACE_API1(m,p1)
+#define DUN_TRACE_API2(m,p1,p2)
+#define DUN_TRACE_API3(m,p1,p2,p3)
+#define DUN_TRACE_API4(m,p1,p2,p3,p4)
+#define DUN_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_EVENT0(m)
+#define DUN_TRACE_EVENT1(m,p1)
+#define DUN_TRACE_EVENT2(m,p1,p2)
+#define DUN_TRACE_EVENT3(m,p1,p2,p3)
+#define DUN_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define DUN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_DEBUG0(m)
+#define DUN_TRACE_DEBUG1(m,p1)
+#define DUN_TRACE_DEBUG2(m,p1,p2)
+#define DUN_TRACE_DEBUG3(m,p1,p2,p3)
+#define DUN_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define DUN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for HCRP */
+
+#define HCRP_TRACE_ERROR0(m)
+#define HCRP_TRACE_ERROR1(m,p1)
+#define HCRP_TRACE_ERROR2(m,p1,p2)
+#define HCRP_TRACE_ERROR3(m,p1,p2,p3)
+#define HCRP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_WARNING0(m)
+#define HCRP_TRACE_WARNING1(m,p1)
+#define HCRP_TRACE_WARNING2(m,p1,p2)
+#define HCRP_TRACE_WARNING3(m,p1,p2,p3)
+#define HCRP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_API0(m)
+#define HCRP_TRACE_API1(m,p1)
+#define HCRP_TRACE_API2(m,p1,p2)
+#define HCRP_TRACE_API3(m,p1,p2,p3)
+#define HCRP_TRACE_API4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_EVENT0(m)
+#define HCRP_TRACE_EVENT1(m,p1)
+#define HCRP_TRACE_EVENT2(m,p1,p2)
+#define HCRP_TRACE_EVENT3(m,p1,p2,p3)
+#define HCRP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_DEBUG0(m)
+#define HCRP_TRACE_DEBUG1(m,p1)
+#define HCRP_TRACE_DEBUG2(m,p1,p2)
+#define HCRP_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCRP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* define traces for HCRP */
+
+#define HCRPM_TRACE_ERROR0(m)
+#define HCRPM_TRACE_ERROR1(m,p1)
+#define HCRPM_TRACE_ERROR2(m,p1,p2)
+#define HCRPM_TRACE_ERROR3(m,p1,p2,p3)
+#define HCRPM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_WARNING0(m)
+#define HCRPM_TRACE_WARNING1(m,p1)
+#define HCRPM_TRACE_WARNING2(m,p1,p2)
+#define HCRPM_TRACE_WARNING3(m,p1,p2,p3)
+#define HCRPM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_API0(m)
+#define HCRPM_TRACE_API1(m,p1)
+#define HCRPM_TRACE_API2(m,p1,p2)
+#define HCRPM_TRACE_API3(m,p1,p2,p3)
+#define HCRPM_TRACE_API4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_EVENT0(m)
+#define HCRPM_TRACE_EVENT1(m,p1)
+#define HCRPM_TRACE_EVENT2(m,p1,p2)
+#define HCRPM_TRACE_EVENT3(m,p1,p2,p3)
+#define HCRPM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_DEBUG0(m)
+#define HCRPM_TRACE_DEBUG1(m,p1)
+#define HCRPM_TRACE_DEBUG2(m,p1,p2)
+#define HCRPM_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCRPM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for RPC */
+
+#define RPC_TRACE_ERROR0(m)
+#define RPC_TRACE_ERROR1(m,p1)
+#define RPC_TRACE_ERROR2(m,p1,p2)
+#define RPC_TRACE_ERROR3(m,p1,p2,p3)
+#define RPC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RPC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_WARNING0(m)
+#define RPC_TRACE_WARNING1(m,p1)
+#define RPC_TRACE_WARNING2(m,p1,p2)
+#define RPC_TRACE_WARNING3(m,p1,p2,p3)
+#define RPC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RPC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_API0(m)
+#define RPC_TRACE_API1(m,p1)
+#define RPC_TRACE_API2(m,p1,p2)
+#define RPC_TRACE_API3(m,p1,p2,p3)
+#define RPC_TRACE_API4(m,p1,p2,p3,p4)
+#define RPC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_EVENT0(m)
+#define RPC_TRACE_EVENT1(m,p1)
+#define RPC_TRACE_EVENT2(m,p1,p2)
+#define RPC_TRACE_EVENT3(m,p1,p2,p3)
+#define RPC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RPC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_DEBUG0(m)
+#define RPC_TRACE_DEBUG1(m,p1)
+#define RPC_TRACE_DEBUG2(m,p1,p2)
+#define RPC_TRACE_DEBUG3(m,p1,p2,p3)
+#define RPC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RPC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for BNEP */
+
+#define BNEP_TRACE_ERROR0(m)
+#define BNEP_TRACE_ERROR1(m,p1)
+#define BNEP_TRACE_ERROR2(m,p1,p2)
+#define BNEP_TRACE_ERROR3(m,p1,p2,p3)
+#define BNEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_WARNING0(m)
+#define BNEP_TRACE_WARNING1(m,p1)
+#define BNEP_TRACE_WARNING2(m,p1,p2)
+#define BNEP_TRACE_WARNING3(m,p1,p2,p3)
+#define BNEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_API0(m)
+#define BNEP_TRACE_API1(m,p1)
+#define BNEP_TRACE_API2(m,p1,p2)
+#define BNEP_TRACE_API3(m,p1,p2,p3)
+#define BNEP_TRACE_API4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_EVENT0(m)
+#define BNEP_TRACE_EVENT1(m,p1)
+#define BNEP_TRACE_EVENT2(m,p1,p2)
+#define BNEP_TRACE_EVENT3(m,p1,p2,p3)
+#define BNEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_DEBUG0(m)
+#define BNEP_TRACE_DEBUG1(m,p1)
+#define BNEP_TRACE_DEBUG2(m,p1,p2)
+#define BNEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* hid module traces */
+
+#define MSKB_TRACE_0(m)
+#define MSKB_TRACE_1(m,p1)
+#define MSKB_TRACE_2(m,p1,p2)
+#define MSKB_TRACE_3(m,p1,p2,p3)
+#define MSKB_TRACE_4(m,p1,p2,p3,p4)
+#define MSKB_TRACE_5(m,p1,p2,p3,p4,p5)
+#define MSKB_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_DEBUG_0(m)
+#define MSKB_DEBUG_1(m,p1)
+#define MSKB_DEBUG_2(m,p1,p2)
+#define MSKB_DEBUG_3(m,p1,p2,p3)
+#define MSKB_DEBUG_4(m,p1,p2,p3,p4)
+#define MSKB_DEBUG_5(m,p1,p2,p3,p4,p5)
+#define MSKB_DEBUG_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_ERROR_0(m)
+#define MSKB_ERROR_1(m,p1)
+#define MSKB_ERROR_2(m,p1,p2)
+#define MSKB_ERROR_3(m,p1,p2,p3)
+#define MSKB_ERROR_4(m,p1,p2,p3,p4)
+#define MSKB_ERROR_5(m,p1,p2,p3,p4,p5)
+#define MSKB_ERROR_6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for PAN */
+
+#define PAN_TRACE_ERROR0(m)
+#define PAN_TRACE_ERROR1(m,p1)
+#define PAN_TRACE_ERROR2(m,p1,p2)
+#define PAN_TRACE_ERROR3(m,p1,p2,p3)
+#define PAN_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define PAN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_WARNING0(m)
+#define PAN_TRACE_WARNING1(m,p1)
+#define PAN_TRACE_WARNING2(m,p1,p2)
+#define PAN_TRACE_WARNING3(m,p1,p2,p3)
+#define PAN_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define PAN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_API0(m)
+#define PAN_TRACE_API1(m,p1)
+#define PAN_TRACE_API2(m,p1,p2)
+#define PAN_TRACE_API3(m,p1,p2,p3)
+#define PAN_TRACE_API4(m,p1,p2,p3,p4)
+#define PAN_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_EVENT0(m)
+#define PAN_TRACE_EVENT1(m,p1)
+#define PAN_TRACE_EVENT2(m,p1,p2)
+#define PAN_TRACE_EVENT3(m,p1,p2,p3)
+#define PAN_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define PAN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_DEBUG0(m)
+#define PAN_TRACE_DEBUG1(m,p1)
+#define PAN_TRACE_DEBUG2(m,p1,p2)
+#define PAN_TRACE_DEBUG3(m,p1,p2,p3)
+#define PAN_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define PAN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for SIM */
+
+#define SAP_TRACE_ERROR0(m)
+#define SAP_TRACE_ERROR1(m,p1)
+#define SAP_TRACE_ERROR2(m,p1,p2)
+#define SAP_TRACE_ERROR3(m,p1,p2,p3)
+#define SAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_WARNING0(m)
+#define SAP_TRACE_WARNING1(m,p1)
+#define SAP_TRACE_WARNING2(m,p1,p2)
+#define SAP_TRACE_WARNING3(m,p1,p2,p3)
+#define SAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_API0(m)
+#define SAP_TRACE_API1(m,p1)
+#define SAP_TRACE_API2(m,p1,p2)
+#define SAP_TRACE_API3(m,p1,p2,p3)
+#define SAP_TRACE_API4(m,p1,p2,p3,p4)
+#define SAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_EVENT0(m)
+#define SAP_TRACE_EVENT1(m,p1)
+#define SAP_TRACE_EVENT2(m,p1,p2)
+#define SAP_TRACE_EVENT3(m,p1,p2,p3)
+#define SAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_DEBUG0(m)
+#define SAP_TRACE_DEBUG1(m,p1)
+#define SAP_TRACE_DEBUG2(m,p1,p2)
+#define SAP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SAP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the OPP profile
+*/
+#define OPP_TRACE_ERROR0(m)
+#define OPP_TRACE_ERROR1(m,p1)
+#define OPP_TRACE_ERROR2(m,p1,p2)
+#define OPP_TRACE_ERROR3(m,p1,p2,p3)
+#define OPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define OPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_WARNING0(m)
+#define OPP_TRACE_WARNING1(m,p1)
+#define OPP_TRACE_WARNING2(m,p1,p2)
+#define OPP_TRACE_WARNING3(m,p1,p2,p3)
+#define OPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define OPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_EVENT0(m)
+#define OPP_TRACE_EVENT1(m,p1)
+#define OPP_TRACE_EVENT2(m,p1,p2)
+#define OPP_TRACE_EVENT3(m,p1,p2,p3)
+#define OPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define OPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_DEBUG0(m)
+#define OPP_TRACE_DEBUG1(m,p1)
+#define OPP_TRACE_DEBUG2(m,p1,p2)
+#define OPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define OPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define OPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_API0(m)
+#define OPP_TRACE_API1(m,p1)
+#define OPP_TRACE_API2(m,p1,p2)
+#define OPP_TRACE_API3(m,p1,p2,p3)
+#define OPP_TRACE_API4(m,p1,p2,p3,p4)
+#define OPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the FTP profile
+*/
+#define FTP_TRACE_ERROR0(m)
+#define FTP_TRACE_ERROR1(m,p1)
+#define FTP_TRACE_ERROR2(m,p1,p2)
+#define FTP_TRACE_ERROR3(m,p1,p2,p3)
+#define FTP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define FTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_WARNING0(m)
+#define FTP_TRACE_WARNING1(m,p1)
+#define FTP_TRACE_WARNING2(m,p1,p2)
+#define FTP_TRACE_WARNING3(m,p1,p2,p3)
+#define FTP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define FTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_EVENT0(m)
+#define FTP_TRACE_EVENT1(m,p1)
+#define FTP_TRACE_EVENT2(m,p1,p2)
+#define FTP_TRACE_EVENT3(m,p1,p2,p3)
+#define FTP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define FTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_DEBUG0(m)
+#define FTP_TRACE_DEBUG1(m,p1)
+#define FTP_TRACE_DEBUG2(m,p1,p2)
+#define FTP_TRACE_DEBUG3(m,p1,p2,p3)
+#define FTP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define FTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_API0(m)
+#define FTP_TRACE_API1(m,p1)
+#define FTP_TRACE_API2(m,p1,p2)
+#define FTP_TRACE_API3(m,p1,p2,p3)
+#define FTP_TRACE_API4(m,p1,p2,p3,p4)
+#define FTP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the A2DP profile
+*/
+#define A2D_TRACE_ERROR0(m)
+#define A2D_TRACE_ERROR1(m,p1)
+#define A2D_TRACE_ERROR2(m,p1,p2)
+#define A2D_TRACE_ERROR3(m,p1,p2,p3)
+#define A2D_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define A2D_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_WARNING0(m)
+#define A2D_TRACE_WARNING1(m,p1)
+#define A2D_TRACE_WARNING2(m,p1,p2)
+#define A2D_TRACE_WARNING3(m,p1,p2,p3)
+#define A2D_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define A2D_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_EVENT0(m)
+#define A2D_TRACE_EVENT1(m,p1)
+#define A2D_TRACE_EVENT2(m,p1,p2)
+#define A2D_TRACE_EVENT3(m,p1,p2,p3)
+#define A2D_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define A2D_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_DEBUG0(m)
+#define A2D_TRACE_DEBUG1(m,p1)
+#define A2D_TRACE_DEBUG2(m,p1,p2)
+#define A2D_TRACE_DEBUG3(m,p1,p2,p3)
+#define A2D_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define A2D_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_API0(m)
+#define A2D_TRACE_API1(m,p1)
+#define A2D_TRACE_API2(m,p1,p2)
+#define A2D_TRACE_API3(m,p1,p2,p3)
+#define A2D_TRACE_API4(m,p1,p2,p3,p4)
+#define A2D_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the VDP profile
+*/
+#define VDP_TRACE_ERROR0(m)
+#define VDP_TRACE_ERROR1(m,p1)
+#define VDP_TRACE_ERROR2(m,p1,p2)
+#define VDP_TRACE_ERROR3(m,p1,p2,p3)
+#define VDP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define VDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_WARNING0(m)
+#define VDP_TRACE_WARNING1(m,p1)
+#define VDP_TRACE_WARNING2(m,p1,p2)
+#define VDP_TRACE_WARNING3(m,p1,p2,p3)
+#define VDP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define VDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_EVENT0(m)
+#define VDP_TRACE_EVENT1(m,p1)
+#define VDP_TRACE_EVENT2(m,p1,p2)
+#define VDP_TRACE_EVENT3(m,p1,p2,p3)
+#define VDP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define VDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_DEBUG0(m)
+#define VDP_TRACE_DEBUG1(m,p1)
+#define VDP_TRACE_DEBUG2(m,p1,p2)
+#define VDP_TRACE_DEBUG3(m,p1,p2,p3)
+#define VDP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define VDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_API0(m)
+#define VDP_TRACE_API1(m,p1)
+#define VDP_TRACE_API2(m,p1,p2)
+#define VDP_TRACE_API3(m,p1,p2,p3)
+#define VDP_TRACE_API4(m,p1,p2,p3,p4)
+#define VDP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the LM unit
+*/
+#define LMP_TRACE_ERROR0(m)
+#define LMP_TRACE_ERROR1(m,p1)
+#define LMP_TRACE_ERROR2(m,p1,p2)
+#define LMP_TRACE_ERROR3(m,p1,p2,p3)
+#define LMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_WARNING0(m)
+#define LMP_TRACE_WARNING1(m,p1)
+#define LMP_TRACE_WARNING2(m,p1,p2)
+#define LMP_TRACE_WARNING3(m,p1,p2,p3)
+#define LMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_EVENT0(m)
+#define LMP_TRACE_EVENT1(m,p1)
+#define LMP_TRACE_EVENT2(m,p1,p2)
+#define LMP_TRACE_EVENT3(m,p1,p2,p3)
+#define LMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_DEBUG0(m)
+#define LMP_TRACE_DEBUG1(m,p1)
+#define LMP_TRACE_DEBUG2(m,p1,p2)
+#define LMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define LMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the LC unit
+*/
+#define LC_TRACE_ERROR0(m)
+#define LC_TRACE_ERROR1(m,p1)
+#define LC_TRACE_ERROR2(m,p1,p2)
+#define LC_TRACE_ERROR3(m,p1,p2,p3)
+#define LC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_WARNING0(m)
+#define LC_TRACE_WARNING1(m,p1)
+#define LC_TRACE_WARNING2(m,p1,p2)
+#define LC_TRACE_WARNING3(m,p1,p2,p3)
+#define LC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_EVENT0(m)
+#define LC_TRACE_EVENT1(m,p1)
+#define LC_TRACE_EVENT2(m,p1,p2)
+#define LC_TRACE_EVENT3(m,p1,p2,p3)
+#define LC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_DEBUG0(m)
+#define LC_TRACE_DEBUG1(m,p1)
+#define LC_TRACE_DEBUG2(m,p1,p2)
+#define LC_TRACE_DEBUG3(m,p1,p2,p3)
+#define LC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_ERROR0(m)
+#define SDA_TRACE_ERROR1(m,p1)
+#define SDA_TRACE_ERROR2(m,p1,p2)
+#define SDA_TRACE_ERROR3(m,p1,p2,p3)
+#define SDA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SDA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_WARNING0(m)
+#define SDA_TRACE_WARNING1(m,p1)
+#define SDA_TRACE_WARNING2(m,p1,p2)
+#define SDA_TRACE_WARNING3(m,p1,p2,p3)
+#define SDA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SDA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_EVENT0(m)
+#define SDA_TRACE_EVENT1(m,p1)
+#define SDA_TRACE_EVENT2(m,p1,p2)
+#define SDA_TRACE_EVENT3(m,p1,p2,p3)
+#define SDA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SDA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_DEBUG0(m)
+#define SDA_TRACE_DEBUG1(m,p1)
+#define SDA_TRACE_DEBUG2(m,p1,p2)
+#define SDA_TRACE_DEBUG3(m,p1,p2,p3)
+#define SDA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SDA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* AVDTP
+*/
+#define AVDT_TRACE_ERROR0(m)
+#define AVDT_TRACE_ERROR1(m,p1)
+#define AVDT_TRACE_ERROR2(m,p1,p2)
+#define AVDT_TRACE_ERROR3(m,p1,p2,p3)
+#define AVDT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_WARNING0(m)
+#define AVDT_TRACE_WARNING1(m,p1)
+#define AVDT_TRACE_WARNING2(m,p1,p2)
+#define AVDT_TRACE_WARNING3(m,p1,p2,p3)
+#define AVDT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_EVENT0(m)
+#define AVDT_TRACE_EVENT1(m,p1)
+#define AVDT_TRACE_EVENT2(m,p1,p2)
+#define AVDT_TRACE_EVENT3(m,p1,p2,p3)
+#define AVDT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_DEBUG0(m)
+#define AVDT_TRACE_DEBUG1(m,p1)
+#define AVDT_TRACE_DEBUG2(m,p1,p2)
+#define AVDT_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVDT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_API0(m)
+#define AVDT_TRACE_API1(m,p1)
+#define AVDT_TRACE_API2(m,p1,p2)
+#define AVDT_TRACE_API3(m,p1,p2,p3)
+#define AVDT_TRACE_API4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the AVCTP protocol
+*/
+#define AVCT_TRACE_ERROR0(m)
+#define AVCT_TRACE_ERROR1(m,p1)
+#define AVCT_TRACE_ERROR2(m,p1,p2)
+#define AVCT_TRACE_ERROR3(m,p1,p2,p3)
+#define AVCT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_WARNING0(m)
+#define AVCT_TRACE_WARNING1(m,p1)
+#define AVCT_TRACE_WARNING2(m,p1,p2)
+#define AVCT_TRACE_WARNING3(m,p1,p2,p3)
+#define AVCT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_EVENT0(m)
+#define AVCT_TRACE_EVENT1(m,p1)
+#define AVCT_TRACE_EVENT2(m,p1,p2)
+#define AVCT_TRACE_EVENT3(m,p1,p2,p3)
+#define AVCT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_DEBUG0(m)
+#define AVCT_TRACE_DEBUG1(m,p1)
+#define AVCT_TRACE_DEBUG2(m,p1,p2)
+#define AVCT_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVCT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_API0(m)
+#define AVCT_TRACE_API1(m,p1)
+#define AVCT_TRACE_API2(m,p1,p2)
+#define AVCT_TRACE_API3(m,p1,p2,p3)
+#define AVCT_TRACE_API4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the AVRCP profile
+*/
+#define AVRC_TRACE_ERROR0(m)
+#define AVRC_TRACE_ERROR1(m,p1)
+#define AVRC_TRACE_ERROR2(m,p1,p2)
+#define AVRC_TRACE_ERROR3(m,p1,p2,p3)
+#define AVRC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_WARNING0(m)
+#define AVRC_TRACE_WARNING1(m,p1)
+#define AVRC_TRACE_WARNING2(m,p1,p2)
+#define AVRC_TRACE_WARNING3(m,p1,p2,p3)
+#define AVRC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_EVENT0(m)
+#define AVRC_TRACE_EVENT1(m,p1)
+#define AVRC_TRACE_EVENT2(m,p1,p2)
+#define AVRC_TRACE_EVENT3(m,p1,p2,p3)
+#define AVRC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_DEBUG0(m)
+#define AVRC_TRACE_DEBUG1(m,p1)
+#define AVRC_TRACE_DEBUG2(m,p1,p2)
+#define AVRC_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVRC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_API0(m)
+#define AVRC_TRACE_API1(m,p1)
+#define AVRC_TRACE_API2(m,p1,p2)
+#define AVRC_TRACE_API3(m,p1,p2,p3)
+#define AVRC_TRACE_API4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* MCAP
+*/
+#define MCA_TRACE_ERROR0(m)
+#define MCA_TRACE_ERROR1(m,p1)
+#define MCA_TRACE_ERROR2(m,p1,p2)
+#define MCA_TRACE_ERROR3(m,p1,p2,p3)
+#define MCA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define MCA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_WARNING0(m)
+#define MCA_TRACE_WARNING1(m,p1)
+#define MCA_TRACE_WARNING2(m,p1,p2)
+#define MCA_TRACE_WARNING3(m,p1,p2,p3)
+#define MCA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define MCA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_EVENT0(m)
+#define MCA_TRACE_EVENT1(m,p1)
+#define MCA_TRACE_EVENT2(m,p1,p2)
+#define MCA_TRACE_EVENT3(m,p1,p2,p3)
+#define MCA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define MCA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_DEBUG0(m)
+#define MCA_TRACE_DEBUG1(m,p1)
+#define MCA_TRACE_DEBUG2(m,p1,p2)
+#define MCA_TRACE_DEBUG3(m,p1,p2,p3)
+#define MCA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define MCA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_API0(m)
+#define MCA_TRACE_API1(m,p1)
+#define MCA_TRACE_API2(m,p1,p2)
+#define MCA_TRACE_API3(m,p1,p2,p3)
+#define MCA_TRACE_API4(m,p1,p2,p3,p4)
+#define MCA_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the AMP unit
+*/
+#define AMP_TRACE_ERROR0(m)
+#define AMP_TRACE_ERROR1(m,p1)
+#define AMP_TRACE_ERROR2(m,p1,p2)
+#define AMP_TRACE_ERROR3(m,p1,p2,p3)
+#define AMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_WARNING0(m)
+#define AMP_TRACE_WARNING1(m,p1)
+#define AMP_TRACE_WARNING2(m,p1,p2)
+#define AMP_TRACE_WARNING3(m,p1,p2,p3)
+#define AMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_API0(m)
+#define AMP_TRACE_API1(m,p1)
+#define AMP_TRACE_API2(m,p1,p2)
+#define AMP_TRACE_API3(m,p1,p2,p3)
+#define AMP_TRACE_API4(m,p1,p2,p3,p4)
+#define AMP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_EVENT0(m)
+#define AMP_TRACE_EVENT1(m,p1)
+#define AMP_TRACE_EVENT2(m,p1,p2)
+#define AMP_TRACE_EVENT3(m,p1,p2,p3)
+#define AMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_DEBUG0(m)
+#define AMP_TRACE_DEBUG1(m,p1)
+#define AMP_TRACE_DEBUG2(m,p1,p2)
+#define AMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define AMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the GATT
+*/
+#define GATT_TRACE_ERROR0(m)
+#define GATT_TRACE_ERROR1(m,p1)
+#define GATT_TRACE_ERROR2(m,p1,p2)
+#define GATT_TRACE_ERROR3(m,p1,p2,p3)
+#define GATT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GATT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_WARNING0(m)
+#define GATT_TRACE_WARNING1(m,p1)
+#define GATT_TRACE_WARNING2(m,p1,p2)
+#define GATT_TRACE_WARNING3(m,p1,p2,p3)
+#define GATT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GATT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_API0(m)
+#define GATT_TRACE_API1(m,p1)
+#define GATT_TRACE_API2(m,p1,p2)
+#define GATT_TRACE_API3(m,p1,p2,p3)
+#define GATT_TRACE_API4(m,p1,p2,p3,p4)
+#define GATT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_EVENT0(m)
+#define GATT_TRACE_EVENT1(m,p1)
+#define GATT_TRACE_EVENT2(m,p1,p2)
+#define GATT_TRACE_EVENT3(m,p1,p2,p3)
+#define GATT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GATT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_DEBUG0(m)
+#define GATT_TRACE_DEBUG1(m,p1)
+#define GATT_TRACE_DEBUG2(m,p1,p2)
+#define GATT_TRACE_DEBUG3(m,p1,p2,p3)
+#define GATT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define GATT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the SMP unit
+*/
+#define SMP_TRACE_ERROR0(m)
+#define SMP_TRACE_ERROR1(m,p1)
+#define SMP_TRACE_ERROR2(m,p1,p2)
+#define SMP_TRACE_ERROR3(m,p1,p2,p3)
+#define SMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_WARNING0(m)
+#define SMP_TRACE_WARNING1(m,p1)
+#define SMP_TRACE_WARNING2(m,p1,p2)
+#define SMP_TRACE_WARNING3(m,p1,p2,p3)
+#define SMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_API0(m)
+#define SMP_TRACE_API1(m,p1)
+#define SMP_TRACE_API2(m,p1,p2)
+#define SMP_TRACE_API3(m,p1,p2,p3)
+#define SMP_TRACE_API4(m,p1,p2,p3,p4)
+#define SMP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_EVENT0(m)
+#define SMP_TRACE_EVENT1(m,p1)
+#define SMP_TRACE_EVENT2(m,p1,p2)
+#define SMP_TRACE_EVENT3(m,p1,p2,p3)
+#define SMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_DEBUG0(m)
+#define SMP_TRACE_DEBUG1(m,p1)
+#define SMP_TRACE_DEBUG2(m,p1,p2)
+#define SMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
+
+/* define traces for application */
+#define APPL_TRACE_ERROR0(m)                    {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, (m));}
+#define APPL_TRACE_ERROR1(m,p1)                 {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_ERROR2(m,p1,p2)              {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_ERROR3(m,p1,p2,p3)           {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_ERROR4(m,p1,p2,p3,p4)        {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)     {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)  {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_WARNING0(m)                  {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, (m));}
+#define APPL_TRACE_WARNING1(m,p1)               {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_WARNING2(m,p1,p2)            {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_WARNING3(m,p1,p2,p3)         {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_WARNING4(m,p1,p2,p3,p4)      {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)   {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_API0(m)                      {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, (m));}
+#define APPL_TRACE_API1(m,p1)                   {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_API2(m,p1,p2)                {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_API3(m,p1,p2,p3)             {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_API4(m,p1,p2,p3,p4)          {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_API5(m,p1,p2,p3,p4,p5)       {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_API6(m,p1,p2,p3,p4,p5,p6)    {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_EVENT0(m)                    {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, (m));}
+#define APPL_TRACE_EVENT1(m,p1)                 {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_EVENT2(m,p1,p2)              {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_EVENT3(m,p1,p2,p3)           {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_EVENT4(m,p1,p2,p3,p4)        {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_EVENT5(m,p1,p2,p3,p4,p5)     {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)  {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_DEBUG0(m)                    {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, (m));}
+#define APPL_TRACE_DEBUG1(m,p1)                 {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_DEBUG2(m,p1,p2)              {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_DEBUG3(m,p1,p2,p3)           {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)        {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)     {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)  {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+#else
+/* define traces for Application */
+
+#define APPL_TRACE_ERROR0(m)
+#define APPL_TRACE_ERROR1(m,p1)
+#define APPL_TRACE_ERROR2(m,p1,p2)
+#define APPL_TRACE_ERROR3(m,p1,p2,p3)
+#define APPL_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_WARNING0(m)
+#define APPL_TRACE_WARNING1(m,p1)
+#define APPL_TRACE_WARNING2(m,p1,p2)
+#define APPL_TRACE_WARNING3(m,p1,p2,p3)
+#define APPL_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_API0(m)
+#define APPL_TRACE_API1(m,p1)
+#define APPL_TRACE_API2(m,p1,p2)
+#define APPL_TRACE_API3(m,p1,p2,p3)
+#define APPL_TRACE_API4(m,p1,p2,p3,p4)
+#define APPL_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_EVENT0(m)
+#define APPL_TRACE_EVENT1(m,p1)
+#define APPL_TRACE_EVENT2(m,p1,p2)
+#define APPL_TRACE_EVENT3(m,p1,p2,p3)
+#define APPL_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define APPL_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_DEBUG0(m)
+#define APPL_TRACE_DEBUG1(m,p1)
+#define APPL_TRACE_DEBUG2(m,p1,p2)
+#define APPL_TRACE_DEBUG3(m,p1,p2,p3)
+#define APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#if ((MMI_INCLUDED == TRUE) && (!defined(HID_MSKB_INCLUDED) || (HID_MSKB_INCLUDED == FALSE)))
+/* UI for sample applications */
+#define SAP_TRACE_0(m)                            MMI_Echo(m)
+#define SAP_TRACE_1(m,p1)                         MMI_Echo(m,p1)
+#define SAP_TRACE_2(m,p1,p2)                      MMI_Echo(m,p1,p2)
+#define SAP_TRACE_3(m,p1,p2,p3)                   MMI_Echo(m,p1,p2,p3)
+#define SAP_TRACE_4(m,p1,p2,p3,p4)                MMI_Echo(m,p1,p2,p3,p4)
+#define SAP_TRACE_5(m,p1,p2,p3,p4,p5)             MMI_Echo(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_6(m,p1,p2,p3,p4,p5,p6)          MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+#else
+#define SAP_TRACE_0(m)
+#define SAP_TRACE_1(m,p1)
+#define SAP_TRACE_2(m,p1,p2)
+#define SAP_TRACE_3(m,p1,p2,p3)
+#define SAP_TRACE_4(m,p1,p2,p3,p4)
+#define SAP_TRACE_5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#endif  /* End of MMI_INCLUDED */
+#if defined(DRV_DEBUG_MSG) && (DRV_DEBUG_MSG == TRUE)
+/* Driver Trace macros
+*/
+#define DRV_TRACE_WARNING0(m)                      APPL_TRACE_WARNING0(m)
+#define DRV_TRACE_WARNING1(m,p1)                   APPL_TRACE_WARNING1(m,p1)
+#define DRV_TRACE_WARNING2(m,p1,p2)                APPL_TRACE_WARNING2(m,p1,p2)
+#define DRV_TRACE_WARNING3(m,p1,p2,p3)             APPL_TRACE_WARNING3(m,p1,p2,p3)
+#define DRV_TRACE_WARNING4(m,p1,p2,p3,p4)          APPL_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DRV_TRACE_WARNING5(m,p1,p2,p3,p4,p5)       APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)    APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+#else
+/* Driver Trace macros
+*/
+#define DRV_TRACE_WARNING0(m)
+#define DRV_TRACE_WARNING1(m,p1)
+#define DRV_TRACE_WARNING2(m,p1,p2)
+#define DRV_TRACE_WARNING3(m,p1,p2,p3)
+#define DRV_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DRV_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+#endif
+
+#define DRV_TRACE_ERROR0(m)                      APPL_TRACE_ERROR0(m)
+#define DRV_TRACE_ERROR1(m,p1)                   APPL_TRACE_ERROR1(m,p1)
+#define DRV_TRACE_ERROR2(m,p1,p2)                APPL_TRACE_ERROR2(m,p1,p2)
+#define DRV_TRACE_ERROR3(m,p1,p2,p3)             APPL_TRACE_ERROR3(m,p1,p2,p3)
+#define DRV_TRACE_ERROR4(m,p1,p2,p3,p4)          APPL_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define DRV_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+/* Driver Trace macros
+*/
+#define DRV_TRACE_DEBUG0(m)                    APPL_TRACE_DEBUG0(m)
+#define DRV_TRACE_DEBUG1(m,p1)                 APPL_TRACE_DEBUG1(m,p1)
+#define DRV_TRACE_DEBUG2(m,p1,p2)              APPL_TRACE_DEBUG2(m,p1,p2)
+#define DRV_TRACE_DEBUG3(m,p1,p2,p3)           APPL_TRACE_DEBUG3(m,p1,p2,p3)
+#define DRV_TRACE_DEBUG4(m,p1,p2,p3,p4)        APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define DRV_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)     APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)  APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+#endif /* BT_TRACE_H */
+
+
diff --git a/halimpl/bcm2079x/include/bt_types.h b/halimpl/bcm2079x/include/bt_types.h
new file mode 100644
index 0000000..2b0e809
--- /dev/null
+++ b/halimpl/bcm2079x/include/bt_types.h
@@ -0,0 +1,702 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 BT_TYPES_H
+#define BT_TYPES_H
+
+#include "data_types.h"
+
+#ifdef _WIN32
+#ifdef BLUESTACK_TESTER
+    #include "bte_stack_entry.h"
+#endif
+#endif
+
+/* READ WELL !!
+**
+** This section defines global events. These are events that cross layers.
+** Any event that passes between layers MUST be one of these events. Tasks
+** can use their own events internally, but a FUNDAMENTAL design issue is
+** that global events MUST be one of these events defined below.
+**
+** The convention used is the the event name contains the layer that the
+** event is going to.
+*/
+#define BT_EVT_MASK                 0xFF00
+#define BT_SUB_EVT_MASK             0x00FF
+                                                /* To Bluetooth Upper Layers        */
+                                                /************************************/
+#define BT_EVT_TO_BTU_L2C_EVT       0x0900      /* L2CAP event */
+#define BT_EVT_TO_BTU_HCI_EVT       0x1000      /* HCI Event                        */
+#define BT_EVT_TO_BTU_HCI_BR_EDR_EVT (0x0000 | BT_EVT_TO_BTU_HCI_EVT)      /* event from BR/EDR controller */
+#define BT_EVT_TO_BTU_HCI_AMP1_EVT   (0x0001 | BT_EVT_TO_BTU_HCI_EVT)      /* event from local AMP 1 controller */
+#define BT_EVT_TO_BTU_HCI_AMP2_EVT   (0x0002 | BT_EVT_TO_BTU_HCI_EVT)      /* event from local AMP 2 controller */
+#define BT_EVT_TO_BTU_HCI_AMP3_EVT   (0x0003 | BT_EVT_TO_BTU_HCI_EVT)      /* event from local AMP 3 controller */
+
+#define BT_EVT_TO_BTU_HCI_ACL       0x1100      /* ACL Data from HCI                */
+#define BT_EVT_TO_BTU_HCI_SCO       0x1200      /* SCO Data from HCI                */
+#define BT_EVT_TO_BTU_HCIT_ERR      0x1300      /* HCI Transport Error              */
+
+#define BT_EVT_TO_BTU_SP_EVT        0x1400      /* Serial Port Event                */
+#define BT_EVT_TO_BTU_SP_DATA       0x1500      /* Serial Port Data                 */
+
+#define BT_EVT_TO_BTU_HCI_CMD       0x1600      /* HCI command from upper layer     */
+
+
+#define BT_EVT_TO_BTU_L2C_SEG_XMIT  0x1900      /* L2CAP segment(s) transmitted     */
+
+#define BT_EVT_PROXY_INCOMING_MSG   0x1A00      /* BlueStackTester event: incoming message from target */
+
+#define BT_EVT_BTSIM                0x1B00      /* Insight BTSIM event */
+#define BT_EVT_BTISE                0x1C00      /* Insight Script Engine event */
+
+                                                /* To LM                            */
+                                                /************************************/
+#define BT_EVT_TO_LM_HCI_CMD        0x2000      /* HCI Command                      */
+#define BT_EVT_TO_LM_HCI_ACL        0x2100      /* HCI ACL Data                     */
+#define BT_EVT_TO_LM_HCI_SCO        0x2200      /* HCI SCO Data                     */
+#define BT_EVT_TO_LM_HCIT_ERR       0x2300      /* HCI Transport Error              */
+#define BT_EVT_TO_LM_LC_EVT         0x2400      /* LC event                         */
+#define BT_EVT_TO_LM_LC_LMP         0x2500      /* LC Received LMP command frame    */
+#define BT_EVT_TO_LM_LC_ACL         0x2600      /* LC Received ACL data             */
+#define BT_EVT_TO_LM_LC_SCO         0x2700      /* LC Received SCO data  (not used) */
+#define BT_EVT_TO_LM_LC_ACL_TX      0x2800      /* LMP data transmit complete       */
+#define BT_EVT_TO_LM_LC_LMPC_TX     0x2900      /* LMP Command transmit complete    */
+#define BT_EVT_TO_LM_LOCAL_ACL_LB   0x2a00      /* Data to be locally loopbacked    */
+#define BT_EVT_TO_LM_HCI_ACL_ACK    0x2b00      /* HCI ACL Data ack      (not used) */
+#define BT_EVT_TO_LM_DIAG           0x2c00      /* LM Diagnostics commands          */
+
+
+#define BT_EVT_TO_BTM_CMDS          0x2f00
+#define BT_EVT_TO_BTM_PM_MDCHG_EVT (0x0001 | BT_EVT_TO_BTM_CMDS)
+
+#define BT_EVT_TO_TCS_CMDS          0x3000
+
+#define BT_EVT_TO_OBX_CL_MSG        0x3100
+#define BT_EVT_TO_OBX_SR_MSG        0x3200
+
+#define BT_EVT_TO_CTP_CMDS          0x3300
+
+/* Obex Over L2CAP */
+#define BT_EVT_TO_OBX_CL_L2C_MSG    0x3400
+#define BT_EVT_TO_OBX_SR_L2C_MSG    0x3500
+
+/* ftp events */
+#define BT_EVT_TO_FTP_SRVR_CMDS     0x3600
+#define BT_EVT_TO_FTP_CLNT_CMDS     0x3700
+
+#define BT_EVT_TO_BTU_SAP           0x3800       /* SIM Access Profile events */
+
+/* opp events */
+#define BT_EVT_TO_OPP_SRVR_CMDS     0x3900
+#define BT_EVT_TO_OPP_CLNT_CMDS     0x3a00
+
+/* gap events */
+#define BT_EVT_TO_GAP_MSG           0x3b00
+
+/* start timer */
+#define BT_EVT_TO_START_TIMER       0x3c00
+
+/* stop timer */
+#define BT_EVT_TO_STOP_TIMER        0x3d00
+
+/* start quick timer */
+#define BT_EVT_TO_START_QUICK_TIMER 0x3e00
+
+
+/* for NFC                          */
+                                                /************************************/
+#define BT_EVT_TO_NFC_NCI           0x4000      /* NCI Command, Notification or Data*/
+#define BT_EVT_TO_NFC_NCI_VS        0x4200      /* Vendor specific message */
+#define BT_EVT_TO_NFC_MSGS          0x4300      /* messages between NFC and NCI task */
+
+#define BT_EVT_TO_NFCCSIM_NCI       0x4a00      /* events to NFCC simulation (NCI packets) */
+
+/* HCISU Events */
+
+#define BT_EVT_HCISU                0x5000
+
+#define BT_EVT_TO_HCISU_LP_APP_SLEEPING_EVT     (0x0005 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_ALLOW_BT_SLEEP_EVT   (0x0006 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_WAKEUP_HOST_EVT      (0x0007 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_RCV_H4IBSS_EVT       (0x0008 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_H5_RESET_EVT            (0x0009 | BT_EVT_HCISU)
+#define BT_EVT_HCISU_START_QUICK_TIMER          (0x000a | BT_EVT_HCISU)
+
+#define BT_EVT_DATA_TO_AMP_1        0x5100
+#define BT_EVT_DATA_TO_AMP_15       0x5f00
+
+/* HSP Events */
+
+#define BT_EVT_BTU_HSP2             0x6000
+
+#define BT_EVT_TO_BTU_HSP2_EVT     (0x0001 | BT_EVT_BTU_HSP2)
+
+/* BPP Events */
+#define BT_EVT_TO_BPP_PR_CMDS       0x6100      /* Printer Events */
+#define BT_EVT_TO_BPP_SND_CMDS      0x6200      /* BPP Sender Events */
+
+/* BIP Events */
+#define BT_EVT_TO_BIP_CMDS          0x6300
+
+/* HCRP Events */
+
+#define BT_EVT_BTU_HCRP             0x7000
+
+#define BT_EVT_TO_BTU_HCRP_EVT     (0x0001 | BT_EVT_BTU_HCRP)
+#define BT_EVT_TO_BTU_HCRPM_EVT    (0x0002 | BT_EVT_BTU_HCRP)
+
+
+#define BT_EVT_BTU_HFP              0x8000
+#define BT_EVT_TO_BTU_HFP_EVT      (0x0001 | BT_EVT_BTU_HFP)
+
+#define BT_EVT_BTU_IPC_EVT          0x9000
+#define BT_EVT_BTU_IPC_LOGMSG_EVT  (0x0000 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_ACL_EVT     (0x0001 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTU_EVT     (0x0002 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_L2C_EVT     (0x0003 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_L2C_MSG_EVT (0x0004 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTM_EVT     (0x0005 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_AVDT_EVT    (0x0006 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_SLIP_EVT    (0x0007 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_MGMT_EVT    (0x0008 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTTRC_EVT   (0x0009 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BURST_EVT   (0x000A | BT_EVT_BTU_IPC_EVT)
+
+/* Define the header of each buffer used in the Bluetooth stack.
+*/
+typedef struct
+{
+    UINT16          event;
+    UINT16          len;
+    UINT16          offset;
+    UINT16          layer_specific;
+} BT_HDR;
+
+#define BT_HDR_SIZE (sizeof (BT_HDR))
+
+#define BT_PSM_SDP                      0x0001
+#define BT_PSM_RFCOMM                   0x0003
+#define BT_PSM_TCS                      0x0005
+#define BT_PSM_CTP                      0x0007
+#define BT_PSM_BNEP                     0x000F
+#define BT_PSM_HIDC                     0x0011
+#define BT_PSM_HIDI                     0x0013
+#define BT_PSM_UPNP                     0x0015
+#define BT_PSM_AVCTP                    0x0017
+#define BT_PSM_AVDTP                    0x0019
+#define BT_PSM_AVCTP_13                 0x001B /* Advanced Control - Browsing */
+#define BT_PSM_UDI_CP                   0x001D /* Unrestricted Digital Information Profile C-Plane  */
+#define BT_PSM_ATT                      0x001F /* Attribute Protocol  */
+
+
+/* These macros extract the HCI opcodes from a buffer
+*/
+#define HCI_GET_CMD_HDR_OPCODE(p)    (UINT16)((*((UINT8 *)((p) + 1) + p->offset) + \
+                                              (*((UINT8 *)((p) + 1) + p->offset + 1) << 8)))
+#define HCI_GET_CMD_HDR_PARAM_LEN(p) (UINT8)  (*((UINT8 *)((p) + 1) + p->offset + 2))
+
+#define HCI_GET_EVT_HDR_OPCODE(p)    (UINT8)(*((UINT8 *)((p) + 1) + p->offset))
+#define HCI_GET_EVT_HDR_PARAM_LEN(p) (UINT8)  (*((UINT8 *)((p) + 1) + p->offset + 1))
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*/
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
+#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define INT8_TO_STREAM(p, u8)    {*(p)++ = (INT8)(u8);}
+#define ARRAY32_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 32;           ijk++) *(p)++ = (UINT8) a[31 - ijk];}
+#define ARRAY16_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 16;           ijk++) *(p)++ = (UINT8) a[15 - ijk];}
+#define ARRAY8_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < 8;            ijk++) *(p)++ = (UINT8) a[7 - ijk];}
+#define BDADDR_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN;  ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
+#define LAP_TO_STREAM(p, a)      {register int ijk; for (ijk = 0; ijk < LAP_LEN;      ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
+#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len;        ijk++) *(p)++ = (UINT8) a[ijk];}
+#define REVERSE_ARRAY_TO_STREAM(p, a, len)  {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
+
+#define STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
+#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
+#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
+#define STREAM_TO_BDADDR(a, p)   {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
+#define STREAM_TO_ARRAY32(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY16(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY8(a, p)   {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_LAP(a, p)      {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
+#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
+
+/********************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*/
+#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
+#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
+#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
+#define UINT8_TO_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*/
+#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24);  *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
+#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
+#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
+#define UINT8_TO_BE_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+
+#define BE_STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
+#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
+#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
+#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*/
+#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24);  *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
+#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
+#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
+#define UINT8_TO_BE_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/* Common Bluetooth field definitions */
+#define BD_ADDR_LEN     6                   /* Device address length */
+typedef UINT8 BD_ADDR[BD_ADDR_LEN];         /* Device address */
+typedef UINT8 *BD_ADDR_PTR;                 /* Pointer to Device Address */
+
+#define AMP_KEY_TYPE_GAMP       0
+#define AMP_KEY_TYPE_WIFI       1
+#define AMP_KEY_TYPE_UWB        2
+typedef UINT8 tAMP_KEY_TYPE;
+
+#define BT_OCTET8_LEN    8
+typedef UINT8 BT_OCTET8[BT_OCTET8_LEN];   /* octet array: size 16 */
+
+#define LINK_KEY_LEN    16
+typedef UINT8 LINK_KEY[LINK_KEY_LEN];       /* Link Key */
+
+#define AMP_LINK_KEY_LEN        32
+typedef UINT8 AMP_LINK_KEY[AMP_LINK_KEY_LEN];   /* Dedicated AMP and GAMP Link Keys */
+
+#define BT_OCTET16_LEN    16
+typedef UINT8 BT_OCTET16[BT_OCTET16_LEN];   /* octet array: size 16 */
+
+#define PIN_CODE_LEN    16
+typedef UINT8 PIN_CODE[PIN_CODE_LEN];       /* Pin Code (upto 128 bits) MSB is 0 */
+typedef UINT8 *PIN_CODE_PTR;                /* Pointer to Pin Code */
+
+#define DEV_CLASS_LEN   3
+typedef UINT8 DEV_CLASS[DEV_CLASS_LEN];     /* Device class */
+typedef UINT8 *DEV_CLASS_PTR;               /* Pointer to Device class */
+
+#define EXT_INQ_RESP_LEN   3
+typedef UINT8 EXT_INQ_RESP[EXT_INQ_RESP_LEN];/* Extended Inquiry Response */
+typedef UINT8 *EXT_INQ_RESP_PTR;             /* Pointer to Extended Inquiry Response */
+
+#define BD_NAME_LEN     248
+typedef UINT8 BD_NAME[BD_NAME_LEN + 1];         /* Device name */
+typedef UINT8 *BD_NAME_PTR;                 /* Pointer to Device name */
+
+#define BD_FEATURES_LEN 8
+typedef UINT8 BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */
+
+#define BT_EVENT_MASK_LEN  8
+typedef UINT8 BT_EVENT_MASK[BT_EVENT_MASK_LEN];   /* Event Mask */
+
+#define LAP_LEN         3
+typedef UINT8 LAP[LAP_LEN];                 /* IAC as passed to Inquiry (LAP) */
+typedef UINT8 INQ_LAP[LAP_LEN];             /* IAC as passed to Inquiry (LAP) */
+
+#define RAND_NUM_LEN    16
+typedef UINT8 RAND_NUM[RAND_NUM_LEN];
+
+#define ACO_LEN         12
+typedef UINT8 ACO[ACO_LEN];                 /* Authenticated ciphering offset */
+
+#define COF_LEN         12
+typedef UINT8 COF[COF_LEN];                 /* ciphering offset number */
+
+typedef struct {
+    UINT8               qos_flags;          /* TBD */
+    UINT8               service_type;       /* see below */
+    UINT32              token_rate;         /* bytes/second */
+    UINT32              token_bucket_size;  /* bytes */
+    UINT32              peak_bandwidth;     /* bytes/second */
+    UINT32              latency;            /* microseconds */
+    UINT32              delay_variation;    /* microseconds */
+} FLOW_SPEC;
+
+/* Values for service_type */
+#define NO_TRAFFIC      0
+#define BEST_EFFORT     1
+#define GUARANTEED      2
+
+/* Service class of the CoD */
+#define SERV_CLASS_NETWORKING               (1 << 1)
+#define SERV_CLASS_RENDERING                (1 << 2)
+#define SERV_CLASS_CAPTURING                (1 << 3)
+#define SERV_CLASS_OBJECT_TRANSFER          (1 << 4)
+#define SERV_CLASS_OBJECT_AUDIO             (1 << 5)
+#define SERV_CLASS_OBJECT_TELEPHONY         (1 << 6)
+#define SERV_CLASS_OBJECT_INFORMATION       (1 << 7)
+
+/* Second byte */
+#define SERV_CLASS_LIMITED_DISC_MODE        (0x20)
+
+/* Field size definitions. Note that byte lengths are rounded up. */
+#define ACCESS_CODE_BIT_LEN             72
+#define ACCESS_CODE_BYTE_LEN            9
+#define SHORTENED_ACCESS_CODE_BIT_LEN   68
+
+typedef UINT8 ACCESS_CODE[ACCESS_CODE_BYTE_LEN];
+
+#define SYNTH_TX                1           /* want synth code to TRANSMIT at this freq */
+#define SYNTH_RX                2           /* want synth code to RECEIVE at this freq */
+
+#define SYNC_REPS 1             /* repeats of sync word transmitted to start of burst */
+
+/* Bluetooth CLK27 */
+#define BT_CLK27            (2 << 26)
+
+/* Bluetooth CLK12 is 1.28 sec */
+#define BT_CLK12_TO_MS(x)    ((x) * 1280)
+#define BT_MS_TO_CLK12(x)    ((x) / 1280)
+#define BT_CLK12_TO_SLOTS(x) ((x) << 11)
+
+/* Bluetooth CLK is 0.625 msec */
+#define BT_CLK_TO_MS(x)      (((x) * 5 + 3) / 8)
+#define BT_MS_TO_CLK(x)      (((x) * 8 + 2) / 5)
+
+#define BT_CLK_TO_MICROSECS(x)  (((x) * 5000 + 3) / 8)
+#define BT_MICROSECS_TO_CLK(x)  (((x) * 8 + 2499) / 5000)
+
+/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
+#define MAX_UUID_SIZE              16
+typedef struct
+{
+#define LEN_UUID_16     2
+#define LEN_UUID_32     4
+#define LEN_UUID_128    16
+
+    UINT16          len;
+
+    union
+    {
+        UINT16      uuid16;
+        UINT32      uuid32;
+        UINT8       uuid128[MAX_UUID_SIZE];
+    } uu;
+
+} tBT_UUID;
+
+#define BT_EIR_FLAGS_TYPE                   0x01
+#define BT_EIR_MORE_16BITS_UUID_TYPE        0x02
+#define BT_EIR_COMPLETE_16BITS_UUID_TYPE    0x03
+#define BT_EIR_MORE_32BITS_UUID_TYPE        0x04
+#define BT_EIR_COMPLETE_32BITS_UUID_TYPE    0x05
+#define BT_EIR_MORE_128BITS_UUID_TYPE       0x06
+#define BT_EIR_COMPLETE_128BITS_UUID_TYPE   0x07
+#define BT_EIR_SHORTENED_LOCAL_NAME_TYPE    0x08
+#define BT_EIR_COMPLETE_LOCAL_NAME_TYPE     0x09
+#define BT_EIR_TX_POWER_LEVEL_TYPE          0x0A
+#define BT_EIR_OOB_BD_ADDR_TYPE             0x0C
+#define BT_EIR_OOB_COD_TYPE                 0x0D
+#define BT_EIR_OOB_SSP_HASH_C_TYPE          0x0E
+#define BT_EIR_OOB_SSP_RAND_R_TYPE          0x0F
+#define BT_EIR_MANUFACTURER_SPECIFIC_TYPE   0xFF
+
+#define BT_OOB_COD_SIZE            3
+#define BT_OOB_HASH_C_SIZE         16
+#define BT_OOB_RAND_R_SIZE         16
+
+/* Broadcom proprietary UUIDs and reserved PSMs
+**
+** The lowest 4 bytes byte of the UUID or GUID depends on the feature. Typically,
+** the value of those bytes will be the PSM or SCN, but it is up to the features.
+*/
+#define BRCM_PROPRIETARY_UUID_BASE  0xDA, 0x23, 0x41, 0x02, 0xA3, 0xBB, 0xC1, 0x71, 0xBA, 0x09, 0x6f, 0x21
+#define BRCM_PROPRIETARY_GUID_BASE  0xda23, 0x4102, 0xa3, 0xbb, 0xc1, 0x71, 0xba, 0x09, 0x6f, 0x21
+
+/* We will not allocate a PSM in the reserved range to 3rd party apps
+*/
+#define BRCM_RESERVED_PSM_START	    0x5AE1
+#define BRCM_RESERVED_PSM_END	    0x5AFF
+
+#define BRCM_UTILITY_SERVICE_PSM    0x5AE1
+#define BRCM_MATCHER_PSM            0x5AE3
+
+/* Connection statistics
+*/
+
+/* Structure to hold connection stats */
+#ifndef BT_CONN_STATS_DEFINED
+#define BT_CONN_STATS_DEFINED
+
+/* These bits are used in the bIsConnected field */
+#define BT_CONNECTED_USING_BREDR   1
+#define BT_CONNECTED_USING_AMP     2
+
+typedef struct
+{
+    UINT32   is_connected;
+    INT32    rssi;
+    UINT32   bytes_sent;
+    UINT32   bytes_rcvd;
+    UINT32   duration;
+} tBT_CONN_STATS;
+
+#endif
+
+/* AMP transport selection criteria definitions.
+** NOTE: if underlying L2CAP connection uses basic mode than it can use only BR/EDR.
+**       For such L2CAP connections AMP connection the criteria provided by application
+**       is reset by AMP manager to AMP_USE_AMP_NEVER.
+*/
+#define AMP_USE_AMP_NEVER                      0   /* Connection only via BR/EDR controller, no AMP allowed        */
+#define AMP_USE_AMP_IF_PEER_TRIES_IT           1   /* Allow AMP to be used if the peer tries to use it             */
+#define AMP_USE_AMP_IF_PHY_CONN_EXISTS         2   /* Use AMP if there is already a physical connection (default)  */
+#define AMP_USE_AMP_IF_LC_POWER_ON             3   /* Only try to use AMP if the Local Controller is powered on    */
+#define AMP_USE_AMP_IF_LC_AND_PEER_POWER_ON    4   /* Only try to use AMP if both LC and peer are powered on       */
+#define AMP_USE_AMP_IF_POSSIBLE                5   /* Try to use AMP if at all possible                            */
+#define AMP_USE_AMP_ONLY                       6   /* Only use AMP, never use BR/EDR                               */
+#define AMP_USE_AMP_MAX_DEF            AMP_USE_AMP_ONLY /* Maximum enum defined for AMP Criteria                        */
+
+#define	AMP_AUTOSWITCH_ALLOWED 		           0x80000000  /* flag to indicate that this connection is auto-switch ready */
+#define AMP_USE_CURRENT_CRITERIA               0xFFFFFFFF  /* Flag if previous criteria was to be still used        */
+
+typedef UINT32 tAMP_CRITERIA;
+
+
+/*****************************************************************************
+**                          Low Energy definitions
+**
+** Address types
+*/
+#define BLE_ADDR_PUBLIC         0x00
+#define BLE_ADDR_RANDOM         0x01
+#define BLE_ADDR_TYPE_MASK      (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
+typedef UINT8 tBLE_ADDR_TYPE;
+
+#define BLE_ADDR_IS_STATIC(x)   ((x[0] & 0xC0) == 0xC0)
+
+typedef struct
+{
+    tBLE_ADDR_TYPE      type;
+    BD_ADDR             bda;
+} tBLE_BD_ADDR;
+
+/* Device Types
+*/
+#define BT_DEVICE_TYPE_BREDR   0x01
+#define BT_DEVICE_TYPE_BLE     0x02
+#define BT_DEVICE_TYPE_DUMO    0x03
+typedef UINT8 tBT_DEVICE_TYPE;
+/*****************************************************************************/
+
+
+/* Define trace levels */
+#define BT_TRACE_LEVEL_NONE    0          /* No trace messages to be generated    */
+#define BT_TRACE_LEVEL_ERROR   1          /* Error condition trace messages       */
+#define BT_TRACE_LEVEL_WARNING 2          /* Warning condition trace messages     */
+#define BT_TRACE_LEVEL_API     3          /* API traces                           */
+#define BT_TRACE_LEVEL_EVENT   4          /* Debug messages for events            */
+#define BT_TRACE_LEVEL_DEBUG   5          /* Full debug messages                  */
+
+#define MAX_TRACE_LEVEL        5
+
+
+/* Define New Trace Type Definition */
+/* TRACE_CTRL_TYPE                  0x^^000000*/
+#define TRACE_CTRL_MASK             0xff000000
+#define TRACE_GET_CTRL(x)           ((((UINT32)(x)) & TRACE_CTRL_MASK) >> 24)
+
+#define TRACE_CTRL_GENERAL          0x00000000
+#define TRACE_CTRL_STR_RESOURCE     0x01000000
+#define TRACE_CTRL_SEQ_FLOW         0x02000000
+#define TRACE_CTRL_MAX_NUM          3
+
+/* LAYER SPECIFIC                   0x00^^0000*/
+#define TRACE_LAYER_MASK            0x00ff0000
+#define TRACE_GET_LAYER(x)          ((((UINT32)(x)) & TRACE_LAYER_MASK) >> 16)
+
+#define TRACE_LAYER_NONE            0x00000000
+#define TRACE_LAYER_USB             0x00010000
+#define TRACE_LAYER_SERIAL          0x00020000
+#define TRACE_LAYER_SOCKET          0x00030000
+#define TRACE_LAYER_RS232           0x00040000
+#define TRACE_LAYER_TRANS_MAX_NUM   5
+#define TRACE_LAYER_TRANS_ALL       0x007f0000
+#define TRACE_LAYER_LC              0x00050000
+#define TRACE_LAYER_LM              0x00060000
+#define TRACE_LAYER_HCI             0x00070000
+#define TRACE_LAYER_L2CAP           0x00080000
+#define TRACE_LAYER_RFCOMM          0x00090000
+#define TRACE_LAYER_SDP             0x000a0000
+#define TRACE_LAYER_TCS             0x000b0000
+#define TRACE_LAYER_OBEX            0x000c0000
+#define TRACE_LAYER_BTM             0x000d0000
+#define TRACE_LAYER_GAP             0x000e0000
+#define TRACE_LAYER_DUN             0x000f0000
+#define TRACE_LAYER_GOEP            0x00100000
+#define TRACE_LAYER_ICP             0x00110000
+#define TRACE_LAYER_HSP2            0x00120000
+#define TRACE_LAYER_SPP             0x00130000
+#define TRACE_LAYER_CTP             0x00140000
+#define TRACE_LAYER_BPP             0x00150000
+#define TRACE_LAYER_HCRP            0x00160000
+#define TRACE_LAYER_FTP             0x00170000
+#define TRACE_LAYER_OPP             0x00180000
+#define TRACE_LAYER_BTU             0x00190000
+#define TRACE_LAYER_GKI             0x001a0000
+#define TRACE_LAYER_BNEP            0x001b0000
+#define TRACE_LAYER_PAN             0x001c0000
+#define TRACE_LAYER_HFP             0x001d0000
+#define TRACE_LAYER_HID             0x001e0000
+#define TRACE_LAYER_BIP             0x001f0000
+#define TRACE_LAYER_AVP             0x00200000
+#define TRACE_LAYER_A2D             0x00210000
+#define TRACE_LAYER_SAP             0x00220000
+#define TRACE_LAYER_AMP             0x00230000
+#define TRACE_LAYER_MCA             0x00240000
+#define TRACE_LAYER_ATT             0x00250000
+#define TRACE_LAYER_SMP             0x00260000
+#define TRACE_LAYER_NFC             0x00270000
+#define TRACE_LAYER_NCI             0x00280000
+#define TRACE_LAYER_LLCP            0x00290000
+#define TRACE_LAYER_NDEF            0x002a0000
+#define TRACE_LAYER_RW              0x002b0000
+#define TRACE_LAYER_CE              0x002c0000
+#define TRACE_LAYER_P2P             0x002d0000
+#define TRACE_LAYER_SNEP            0x002e0000
+#define TRACE_LAYER_CHO             0x002f0000
+#define TRACE_LAYER_NFA             0x00300000
+
+#define TRACE_LAYER_MAX_NUM         0x0031
+
+
+/* TRACE_ORIGINATOR                 0x0000^^00*/
+#define TRACE_ORG_MASK              0x0000ff00
+#define TRACE_GET_ORG(x)            ((((UINT32)(x)) & TRACE_ORG_MASK) >> 8)
+
+#define TRACE_ORG_STACK             0x00000000
+#define TRACE_ORG_HCI_TRANS         0x00000100
+#define TRACE_ORG_PROTO_DISP        0x00000200
+#define TRACE_ORG_RPC               0x00000300
+#define TRACE_ORG_GKI               0x00000400
+#define TRACE_ORG_APPL              0x00000500
+#define TRACE_ORG_SCR_WRAPPER       0x00000600
+#define TRACE_ORG_SCR_ENGINE        0x00000700
+#define TRACE_ORG_USER_SCR          0x00000800
+#define TRACE_ORG_TESTER            0x00000900
+#define TRACE_ORG_MAX_NUM           10          /* 32-bit mask; must be < 32 */
+#define TRACE_LITE_ORG_MAX_NUM		6
+#define TRACE_ORG_ALL               0x03ff
+#define TRACE_ORG_RPC_TRANS         0x04
+
+#define TRACE_ORG_REG               0x00000909
+#define TRACE_ORG_REG_SUCCESS       0x0000090a
+
+/* TRACE_TYPE                       0x000000^^*/
+#define TRACE_TYPE_MASK             0x000000ff
+#define TRACE_GET_TYPE(x)           (((UINT32)(x)) & TRACE_TYPE_MASK)
+
+#define TRACE_TYPE_ERROR            0x00000000
+#define TRACE_TYPE_WARNING          0x00000001
+#define TRACE_TYPE_API              0x00000002
+#define TRACE_TYPE_EVENT            0x00000003
+#define TRACE_TYPE_DEBUG            0x00000004
+#define TRACE_TYPE_STACK_ONLY_MAX   TRACE_TYPE_DEBUG
+#define TRACE_TYPE_TX               0x00000005
+#define TRACE_TYPE_RX               0x00000006
+#define TRACE_TYPE_DEBUG_ASSERT     0x00000007
+#define TRACE_TYPE_GENERIC          0x00000008
+#define TRACE_TYPE_REG              0x00000009
+#define TRACE_TYPE_REG_SUCCESS      0x0000000a
+#define TRACE_TYPE_CMD_TX           0x0000000b
+#define TRACE_TYPE_EVT_TX           0x0000000c
+#define TRACE_TYPE_ACL_TX           0x0000000d
+#define TRACE_TYPE_CMD_RX           0x0000000e
+#define TRACE_TYPE_EVT_RX           0x0000000f
+#define TRACE_TYPE_ACL_RX           0x00000010
+#define TRACE_TYPE_TARGET_TRACE     0x00000011
+#define TRACE_TYPE_SCO_TX           0x00000012
+#define TRACE_TYPE_SCO_RX           0x00000013
+
+
+#define TRACE_TYPE_MAX_NUM          20
+#define TRACE_TYPE_ALL              0xffff
+
+/* Define color for script type */
+#define SCR_COLOR_DEFAULT       0
+#define SCR_COLOR_TYPE_COMMENT  1
+#define SCR_COLOR_TYPE_COMMAND  2
+#define SCR_COLOR_TYPE_EVENT    3
+#define SCR_COLOR_TYPE_SELECT   4
+
+/* Define protocol trace flag values */
+#define SCR_PROTO_TRACE_HCI_SUMMARY 0x00000001
+#define SCR_PROTO_TRACE_HCI_DATA    0x00000002
+#define SCR_PROTO_TRACE_L2CAP       0x00000004
+#define SCR_PROTO_TRACE_RFCOMM      0x00000008
+#define SCR_PROTO_TRACE_SDP         0x00000010
+#define SCR_PROTO_TRACE_TCS         0x00000020
+#define SCR_PROTO_TRACE_OBEX        0x00000040
+#define SCR_PROTO_TRACE_OAPP        0x00000080 /* OBEX Application Profile */
+#define SCR_PROTO_TRACE_AMP         0x00000100
+#define SCR_PROTO_TRACE_BNEP        0x00000200
+#define SCR_PROTO_TRACE_AVP         0x00000400
+#define SCR_PROTO_TRACE_MCA         0x00000800
+#define SCR_PROTO_TRACE_ATT         0x00001000
+#define SCR_PROTO_TRACE_SMP         0x00002000
+#define SCR_PROTO_TRACE_NCI         0x00004000
+#define SCR_PROTO_TRACE_LLCP        0x00008000
+#define SCR_PROTO_TRACE_NDEF        0x00010000
+#define SCR_PROTO_TRACE_RW          0x00020000
+#define SCR_PROTO_TRACE_CE          0x00040000
+#define SCR_PROTO_TRACE_SNEP        0x00080000
+#define SCR_PROTO_TRACE_CHO         0x00100000
+#define SCR_PROTO_TRACE_ALL         0x001fffff
+#define SCR_PROTO_TRACE_HCI_LOGGING_VSE 0x0800 /* Brcm vs event for logmsg and protocol traces */
+
+#define MAX_SCRIPT_TYPE             5
+
+#define TCS_PSM_INTERCOM        5
+#define TCS_PSM_CORDLESS        7
+#define BT_PSM_BNEP             0x000F
+/* Define PSMs HID uses */
+#define HID_PSM_CONTROL         0x0011
+#define HID_PSM_INTERRUPT       0x0013
+
+#if defined(UCD_HID_INCLUDED) && (UCD_HID_INCLUDED == TRUE)
+#define UCD_PSM_MIN     0x8003
+#define UCD_PSM_MAX     0x8003
+#define UCD_PSM_HID     0x8003
+#endif
+
+/* Define a function for logging */
+typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...);
+
+#endif
+
diff --git a/halimpl/bcm2079x/include/btdisp_lock.h b/halimpl/bcm2079x/include/btdisp_lock.h
new file mode 100644
index 0000000..97f2cfe
--- /dev/null
+++ b/halimpl/bcm2079x/include/btdisp_lock.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Critical section definitions for btdisp functions.
+ *
+ ******************************************************************************/
+
+#ifndef BTDISP_LOCK
+#define BTDISP_LOCK
+
+
+#ifdef TESTER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// External function declaration
+extern void btdisp_lock();
+extern void btdisp_unlock();
+extern void btdisp_init();
+extern void btdisp_uninit();
+
+#ifdef __cplusplus
+}
+#endif
+
+// Lock Macros
+#define BTDISP_LOCK_LOG()           btdisp_lock();
+#define BTDISP_UNLOCK_LOG()         btdisp_unlock();
+#define BTDISP_INIT_LOCK()          btdisp_init();
+#define BTDISP_UNINIT_LOCK()        btdisp_uninit();
+
+#else
+
+#define BTDISP_LOCK_LOG()
+#define BTDISP_UNLOCK_LOG()
+#define BTDISP_INIT_LOCK()
+#define BTDISP_UNINIT_LOCK()
+
+#endif
+
+
+
+#endif // BTDISP_LOCK
diff --git a/halimpl/bcm2079x/include/buildcfg.h b/halimpl/bcm2079x/include/buildcfg.h
new file mode 100644
index 0000000..d3829cc
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg.h
@@ -0,0 +1,39 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#pragma once
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+#include "data_types.h"
+#include "btdisp_lock.h"
+
+
+#define BTE_APPL_MAX_USERIAL_DEV_NAME           (256)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+
+
+#ifdef	__cplusplus
+};
+#endif
+
diff --git a/halimpl/bcm2079x/include/buildcfg_hal.h b/halimpl/bcm2079x/include/buildcfg_hal.h
new file mode 100644
index 0000000..e987434
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg_hal.h
@@ -0,0 +1,28 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+//override any HAL-specific macros
+#pragma once
+#include "bt_types.h"
+
+//NFC_HAL_TASK=0 is already defined in gki_hal_target.h; it executes the Broadcom HAL
+#define USERIAL_HAL_TASK  1  //execute userial's read thread
+#define GKI_RUNNER_HAL_TASK 2  //execute GKI_run(), which runs forever
+#define GKI_MAX_TASKS  3 //total of 3 tasks
+
+
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY (500)
diff --git a/halimpl/bcm2079x/include/config.h b/halimpl/bcm2079x/include/config.h
new file mode 100644
index 0000000..12f54a4
--- /dev/null
+++ b/halimpl/bcm2079x/include/config.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 __CONFIG_H
+#define __CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int GetStrValue(const char* name, char* p_value, unsigned long len);
+int GetNumValue(const char* name, void* p_value, unsigned long len);
+
+#ifdef __cplusplus
+};
+#endif
+
+#define NAME_USE_NXP_P2P_RC_WORKAROUND  "USE_NXP_P2P_RC_WORKAROUND"
+#define NAME_NFA_DM_ENABLE_SLEEP        "NFA_DM_ENABLE_SLEEP"
+#define NAME_ENABLE_BRCM_EXTRAS_API     "ENABLE_BRCM_EXTRAS_API"
+#define NAME_POLLING_TECH_MASK          "POLLING_TECH_MASK"
+#define NAME_REGISTER_VIRTUAL_SE        "REGISTER_VIRTUAL_SE"
+#define NAME_APPL_TRACE_LEVEL           "APPL_TRACE_LEVEL"
+#define NAME_LPTD_CFG                   "LPTD_CFG"
+#define NAME_SCREEN_OFF_POWER_STATE     "SCREEN_OFF_POWER_STATE"
+#define NAME_UICC_IDLE_TIMEOUT          "UICC_IDLE_TIMEOUT"
+#define NAME_PREINIT_DSP_CFG            "PREINIT_DSP_CFG"
+#define NAME_DTA_START_CFG              "DTA_START_CFG"
+#define NAME_TRANSPORT_DRIVER           "TRANSPORT_DRIVER"
+#define NAME_POWER_CONTROL_DRIVER       "POWER_CONTROL_DRIVER"
+#define NAME_PROTOCOL_TRACE_LEVEL       "PROTOCOL_TRACE_LEVEL"
+#define NAME_UART_PORT                  "UART_PORT"
+#define NAME_UART_BAUD                  "UART_BAUD"
+#define NAME_UART_PARITY                "UART_PARITY"
+#define NAME_UART_STOPBITS              "UART_STOPBITS"
+#define NAME_UART_DATABITS              "UART_DATABITS"
+#define NAME_CLIENT_ADDRESS             "BCMI2CNFC_ADDRESS"
+#define NAME_NFA_DM_START_UP_CFG        "NFA_DM_START_UP_CFG"
+#define NAME_NFA_DM_CFG                 "NFA_DM_CFG"
+#define NAME_NFA_DM_LP_CFG              "NFA_DM_LP_CFG"
+#define NAME_LOW_SPEED_TRANSPORT        "LOW_SPEED_TRANSPORT"
+#define NAME_NFC_WAKE_DELAY             "NFC_WAKE_DELAY"
+#define NAME_NFC_WRITE_DELAY            "NFC_WRITE_DELAY"
+#define NAME_PERF_MEASURE_FREQ          "REPORT_PERFORMANCE_MEASURE"
+#define NAME_READ_MULTI_PACKETS         "READ_MULTIPLE_PACKETS"
+#define NAME_POWER_ON_DELAY             "POWER_ON_DELAY"
+#define NAME_PRE_POWER_OFF_DELAY        "PRE_POWER_OFF_DELAY"
+#define NAME_POST_POWER_OFF_DELAY       "POST_POWER_OFF_DELAY"
+#define NAME_NFA_STORAGE                "NFA_STORAGE"
+#define NAME_NFA_DM_START_UP_VSC_CFG    "NFA_DM_START_UP_VSC_CFG"
+#define NAME_UICC_LISTEN_TECH_MASK      "UICC_LISTEN_TECH_MASK"
+#define NAME_SNOOZE_MODE_CFG            "SNOOZE_MODE_CFG"
+#define NAME_XTAL_FREQUENCY             "XTAL_FREQUENCY"
+#define NAME_SPD_DEBUG                  "SPD_DEBUG"
+#define NAME_SPD_MAXRETRYCOUNT          "SPD_MAX_RETRY_COUNT"
+#define NAME_SPI_NEGOTIATION            "SPI_NEGOTIATION"
+
+#define                     LPTD_PARAM_LEN (40)
+
+// default configuration
+#define default_transport       "/dev/bcm2079x"
+#define default_storage_location "/data/nfc"
+
+struct tUART_CONFIG {
+    int     m_iBaudrate;            // 115200
+    int     m_iDatabits;            // 8
+    int     m_iParity;              // 0 - none, 1 = odd, 2 = even
+    int     m_iStopbits;
+};
+
+extern struct tUART_CONFIG  uartConfig;
+#define MAX_CHIPID_LEN  (16)
+void    readOptionalConfig(const char* option);
+
+/* Snooze mode configuration structure */
+typedef struct
+{
+    unsigned char   snooze_mode;            /* Snooze Mode */
+    unsigned char   idle_threshold_dh;      /* Idle Threshold Host */
+    unsigned char   idle_threshold_nfcc;    /* Idle Threshold NFCC   */
+    unsigned char   nfc_wake_active_mode;   /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+    unsigned char   dh_wake_active_mode;    /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+} tSNOOZE_MODE_CONFIG;
+#endif
diff --git a/halimpl/bcm2079x/include/dyn_mem.h b/halimpl/bcm2079x/include/dyn_mem.h
new file mode 100644
index 0000000..2ee0169
--- /dev/null
+++ b/halimpl/bcm2079x/include/dyn_mem.h
@@ -0,0 +1,191 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 DYN_MEM_H
+#define DYN_MEM_H
+
+/****************************************************************************
+** Define memory usage for GKI (if not defined in buildcfg.h)
+**  The default for GKI is to use static memory allocation for its control
+**  block.
+*/
+#ifndef GKI_DYNAMIC_MEMORY
+#define GKI_DYNAMIC_MEMORY  FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for each CORE component (if not defined in buildcfg.h)
+**  The default for each component is to use static memory allocations.
+*/
+#ifndef BTU_DYNAMIC_MEMORY
+#define BTU_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef BTM_DYNAMIC_MEMORY
+#define BTM_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SDP_DYNAMIC_MEMORY
+#define SDP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef L2C_DYNAMIC_MEMORY
+#define L2C_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef A2MP_DYNAMIC_MEMORY
+#define A2MP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef RFC_DYNAMIC_MEMORY
+#define RFC_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef TCS_DYNAMIC_MEMORY
+#define TCS_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef OBX_DYNAMIC_MEMORY
+#define OBX_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef BNEP_DYNAMIC_MEMORY
+#define BNEP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVDT_DYNAMIC_MEMORY
+#define AVDT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVCT_DYNAMIC_MEMORY
+#define AVCT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef MCA_DYNAMIC_MEMORY
+#define MCA_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef GATT_DYNAMIC_MEMORY
+#define GATT_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SMP_DYNAMIC_MEMORY
+#define SMP_DYNAMIC_MEMORY  FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for each PROFILE component (if not defined in buildcfg.h)
+**  The default for each component is to use static memory allocations.
+*/
+#ifndef A2D_DYNAMIC_MEMORY
+#define A2D_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef VDP_DYNAMIC_MEMORY
+#define VDP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef AVRC_DYNAMIC_MEMORY
+#define AVRC_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BIP_DYNAMIC_MEMORY
+#define BIP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef BPP_DYNAMIC_MEMORY
+#define BPP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef CTP_DYNAMIC_MEMORY
+#define CTP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef DUN_DYNAMIC_MEMORY
+#define DUN_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef FTP_DYNAMIC_MEMORY
+#define FTP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef GAP_DYNAMIC_MEMORY
+#define GAP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef GOEP_DYNAMIC_MEMORY
+#define GOEP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HCRP_DYNAMIC_MEMORY
+#define HCRP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HFP_DYNAMIC_MEMORY
+#define HFP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef HID_DYNAMIC_MEMORY
+#define HID_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef HSP2_DYNAMIC_MEMORY
+#define HSP2_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef ICP_DYNAMIC_MEMORY
+#define ICP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef OPP_DYNAMIC_MEMORY
+#define OPP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef PAN_DYNAMIC_MEMORY
+#define PAN_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SPP_DYNAMIC_MEMORY
+#define SPP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SLIP_DYNAMIC_MEMORY
+#define SLIP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef LLCP_DYNAMIC_MEMORY
+#define LLCP_DYNAMIC_MEMORY  FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for BTA (if not defined in buildcfg.h)
+**  The default for each component is to use static memory allocations.
+*/
+#ifndef BTA_DYNAMIC_MEMORY
+#define BTA_DYNAMIC_MEMORY FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for BT Trace (if not defined in buildcfg.h)
+**  The default is to use static memory allocations.
+*/
+#ifndef BTTRC_DYNAMIC_MEMORY
+#define BTTRC_DYNAMIC_MEMORY FALSE
+#endif
+
+#endif  /* #ifdef DYN_MEM_H */
+
diff --git a/halimpl/bcm2079x/include/gki_target.h b/halimpl/bcm2079x/include/gki_target.h
new file mode 100644
index 0000000..afb4f78
--- /dev/null
+++ b/halimpl/bcm2079x/include/gki_target.h
@@ -0,0 +1,19 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#pragma once
+#include "gki_hal_target.h"
diff --git a/halimpl/bcm2079x/include/hcidefs.h b/halimpl/bcm2079x/include/hcidefs.h
new file mode 100644
index 0000000..cc3b09f
--- /dev/null
+++ b/halimpl/bcm2079x/include/hcidefs.h
@@ -0,0 +1,2377 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 HCIDEFS_H
+#define HCIDEFS_H
+
+#define HCI_PROTO_VERSION     0x01      /* Version for BT spec 1.1          */
+#define HCI_PROTO_VERSION_1_2 0x02      /* Version for BT spec 1.2          */
+#define HCI_PROTO_VERSION_2_0 0x03      /* Version for BT spec 2.0          */
+#define HCI_PROTO_VERSION_2_1 0x04      /* Version for BT spec 2.1 [Lisbon] */
+#define HCI_PROTO_VERSION_3_0 0x05      /* Version for BT spec 3.0          */
+#define HCI_PROTO_REVISION    0x000C    /* Current implementation version   */
+/*
+**  Definitions for HCI groups
+*/
+#define HCI_GRP_LINK_CONTROL_CMDS       (0x01 << 10)            /* 0x0400 */
+#define HCI_GRP_LINK_POLICY_CMDS        (0x02 << 10)            /* 0x0800 */
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10)            /* 0x0C00 */
+#define HCI_GRP_INFORMATIONAL_PARAMS    (0x04 << 10)            /* 0x1000 */
+#define HCI_GRP_STATUS_PARAMS           (0x05 << 10)            /* 0x1400 */
+#define HCI_GRP_TESTING_CMDS            (0x06 << 10)            /* 0x1800 */
+
+#define HCI_GRP_VENDOR_SPECIFIC         (0x3F << 10)            /* 0xFC00 */
+
+/* Group occupies high 6 bits of the HCI command rest is opcode itself */
+#define HCI_OGF(p)  (UINT8)((0xFC00 & (p)) >> 10)
+#define HCI_OCF(p)  ( 0x3FF & (p))
+
+/*
+**  Defentions for Link Control Commands
+*/
+/* Following opcode is used only in command complete event for flow control */
+#define HCI_COMMAND_NONE                0x0000
+
+/* Commands of HCI_GRP_LINK_CONTROL_CMDS group */
+#define HCI_INQUIRY                     (0x0001 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_INQUIRY_CANCEL              (0x0002 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PERIODIC_INQUIRY_MODE       (0x0003 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_EXIT_PERIODIC_INQUIRY_MODE  (0x0004 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_CONNECTION           (0x0005 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT                  (0x0006 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ADD_SCO_CONNECTION          (0x0007 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_CONNECTION_CANCEL    (0x0008 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_CONNECTION_REQUEST   (0x0009 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REJECT_CONNECTION_REQUEST   (0x000A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LINK_KEY_REQUEST_REPLY      (0x000B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY  (0x000C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PIN_CODE_REQUEST_REPLY      (0x000D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY  (0x000E | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CHANGE_CONN_PACKET_TYPE     (0x000F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_AUTHENTICATION_REQUESTED    (0x0011 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SET_CONN_ENCRYPTION         (0x0013 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CHANGE_CONN_LINK_KEY        (0x0015 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_MASTER_LINK_KEY             (0x0017 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RMT_NAME_REQUEST            (0x0019 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RMT_NAME_REQUEST_CANCEL     (0x001A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_FEATURES           (0x001B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_EXT_FEATURES       (0x001C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_VERSION_INFO       (0x001D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_CLOCK_OFFSET       (0x001F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_LMP_HANDLE             (0x0020 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SETUP_ESCO_CONNECTION       (0x0028 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_ESCO_CONNECTION      (0x0029 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REJECT_ESCO_CONNECTION      (0x002A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_IO_CAPABILITY_RESPONSE      (0x002B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_CONF_REQUEST_REPLY     (0x002C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_CONF_VALUE_NEG_REPLY   (0x002D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_PASSKEY_REQ_REPLY      (0x002E | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_PASSKEY_REQ_NEG_REPLY  (0x002F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REM_OOB_DATA_REQ_REPLY      (0x0030 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REM_OOB_DATA_REQ_NEG_REPLY  (0x0033 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_IO_CAP_REQ_NEG_REPLY        (0x0034 | HCI_GRP_LINK_CONTROL_CMDS)
+
+/* AMP HCI */
+#define HCI_CREATE_PHYSICAL_LINK        (0x0035 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_PHYSICAL_LINK        (0x0036 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT_PHYSICAL_LINK    (0x0037 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_LOGICAL_LINK         (0x0038 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_LOGICAL_LINK         (0x0039 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT_LOGICAL_LINK     (0x003A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LOGICAL_LINK_CANCEL         (0x003B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_FLOW_SPEC_MODIFY            (0x003C | HCI_GRP_LINK_CONTROL_CMDS)
+
+#define HCI_LINK_CTRL_CMDS_FIRST        HCI_INQUIRY
+#define HCI_LINK_CTRL_CMDS_LAST         HCI_FLOW_SPEC_MODIFY
+
+/* Commands of HCI_GRP_LINK_POLICY_CMDS */
+#define HCI_HOLD_MODE                   (0x0001 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SNIFF_MODE                  (0x0003 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_EXIT_SNIFF_MODE             (0x0004 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_PARK_MODE                   (0x0005 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_EXIT_PARK_MODE              (0x0006 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_QOS_SETUP                   (0x0007 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_ROLE_DISCOVERY              (0x0009 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SWITCH_ROLE                 (0x000B | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_READ_POLICY_SETTINGS        (0x000C | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_WRITE_POLICY_SETTINGS       (0x000D | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_READ_DEF_POLICY_SETTINGS    (0x000E | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_WRITE_DEF_POLICY_SETTINGS   (0x000F | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_FLOW_SPECIFICATION          (0x0010 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SNIFF_SUB_RATE              (0x0011 | HCI_GRP_LINK_POLICY_CMDS)
+
+#define HCI_LINK_POLICY_CMDS_FIRST      HCI_HOLD_MODE
+#define HCI_LINK_POLICY_CMDS_LAST       HCI_SNIFF_SUB_RATE
+
+
+/* Commands of HCI_GRP_HOST_CONT_BASEBAND_CMDS */
+#define HCI_SET_EVENT_MASK              (0x0001 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_RESET                       (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EVENT_FILTER            (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_FLUSH                       (0x0008 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PIN_TYPE               (0x0009 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PIN_TYPE              (0x000A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_CREATE_NEW_UNIT_KEY         (0x000B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_STORED_LINK_KEY        (0x000D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_STORED_LINK_KEY       (0x0011 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_DELETE_STORED_LINK_KEY      (0x0012 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_CHANGE_LOCAL_NAME           (0x0013 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCAL_NAME             (0x0014 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CONN_ACCEPT_TOUT       (0x0015 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CONN_ACCEPT_TOUT      (0x0016 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGE_TOUT              (0x0017 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGE_TOUT             (0x0018 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SCAN_ENABLE            (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SCAN_ENABLE           (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_CFG           (0x001B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_CFG          (0x001C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQUIRYSCAN_CFG        (0x001D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQUIRYSCAN_CFG       (0x001E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTHENTICATION_ENABLE  (0x001F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTHENTICATION_ENABLE (0x0020 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_ENCRYPTION_MODE        (0x0021 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_ENCRYPTION_MODE       (0x0022 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CLASS_OF_DEVICE        (0x0023 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CLASS_OF_DEVICE       (0x0024 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_VOICE_SETTINGS         (0x0025 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_VOICE_SETTINGS        (0x0026 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTO_FLUSH_TOUT        (0x0027 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTO_FLUSH_TOUT       (0x0028 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_NUM_BCAST_REXMITS      (0x0029 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_NUM_BCAST_REXMITS     (0x002A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_HOLD_MODE_ACTIVITY     (0x002B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_HOLD_MODE_ACTIVITY    (0x002C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_TRANSMIT_POWER_LEVEL   (0x002D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SCO_FLOW_CTRL_ENABLE   (0x002E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SCO_FLOW_CTRL_ENABLE  (0x002F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_HC_TO_HOST_FLOW_CTRL    (0x0031 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_HOST_BUFFER_SIZE            (0x0033 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_HOST_NUM_PACKETS_DONE       (0x0035 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LINK_SUPER_TOUT        (0x0036 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LINK_SUPER_TOUT       (0x0037 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_NUM_SUPPORTED_IAC      (0x0038 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CURRENT_IAC_LAP        (0x0039 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CURRENT_IAC_LAP       (0x003A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_PERIOD_MODE   (0x003B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_PERIOD_MODE  (0x003C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_MODE          (0x003D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_MODE         (0x003E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_AFH_CHANNELS            (0x003F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+#define HCI_READ_INQSCAN_TYPE           (0x0042 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQSCAN_TYPE          (0x0043 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQUIRY_MODE           (0x0044 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQUIRY_MODE          (0x0045 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_TYPE          (0x0046 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_TYPE         (0x0047 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AFH_ASSESSMENT_MODE    (0x0048 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AFH_ASSESSMENT_MODE   (0x0049 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_EXT_INQ_RESPONSE       (0x0051 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_EXT_INQ_RESPONSE      (0x0052 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_REFRESH_ENCRYPTION_KEY      (0x0053 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SIMPLE_PAIRING_MODE    (0x0055 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SIMPLE_PAIRING_MODE   (0x0056 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCAL_OOB_DATA         (0x0057 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQ_TX_POWER_LEVEL     (0x0058 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQ_TX_POWER_LEVEL    (0x0059 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_ERRONEOUS_DATA_RPT     (0x005A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_ERRONEOUS_DATA_RPT    (0x005B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_ENHANCED_FLUSH              (0x005F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SEND_KEYPRESS_NOTIF         (0x0060 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+
+/* AMP HCI */
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT  (0x0061 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT (0x0062 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EVENT_MASK_PAGE_2             (0x0063 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCATION_DATA                (0x0064 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LOCATION_DATA               (0x0065 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_FLOW_CONTROL_MODE            (0x0066 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_FLOW_CONTROL_MODE           (0x0067 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_BE_FLUSH_TOUT                (0x0069 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_BE_FLUSH_TOUT               (0x006A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SHORT_RANGE_MODE                  (0x006B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) /* 802.11 only */
+
+#define HCI_CONT_BASEBAND_CMDS_FIRST    HCI_SET_EVENT_MASK
+#define HCI_CONT_BASEBAND_CMDS_LAST     HCI_SHORT_RANGE_MODE
+
+
+/* Commands of HCI_GRP_INFORMATIONAL_PARAMS group */
+#define HCI_READ_LOCAL_VERSION_INFO     (0x0001 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_SUPPORTED_CMDS   (0x0002 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_FEATURES         (0x0003 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_EXT_FEATURES     (0x0004 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_BUFFER_SIZE            (0x0005 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_COUNTRY_CODE           (0x0007 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_BD_ADDR                (0x0009 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_DATA_BLOCK_SIZE        (0x000A | HCI_GRP_INFORMATIONAL_PARAMS)
+
+#define HCI_INFORMATIONAL_CMDS_FIRST    HCI_READ_LOCAL_VERSION_INFO
+#define HCI_INFORMATIONAL_CMDS_LAST     HCI_READ_BD_ADDR
+
+
+/* Commands of HCI_GRP_STATUS_PARAMS group */
+#define HCI_READ_FAILED_CONTACT_COUNT   (0x0001 | HCI_GRP_STATUS_PARAMS)
+#define HCI_RESET_FAILED_CONTACT_COUNT  (0x0002 | HCI_GRP_STATUS_PARAMS)
+#define HCI_GET_LINK_QUALITY            (0x0003 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_RSSI                   (0x0005 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_AFH_CH_MAP             (0x0006 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_CLOCK                  (0x0007 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_ENCR_KEY_SIZE          (0x0008 | HCI_GRP_STATUS_PARAMS)
+
+/* AMP HCI */
+#define HCI_READ_LOCAL_AMP_INFO         (0x0009 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_LOCAL_AMP_ASSOC        (0x000A | HCI_GRP_STATUS_PARAMS)
+#define HCI_WRITE_REMOTE_AMP_ASSOC      (0x000B | HCI_GRP_STATUS_PARAMS)
+
+#define HCI_STATUS_PARAMS_CMDS_FIRST    HCI_READ_FAILED_CONTACT_COUNT
+#define HCI_STATUS_PARAMS_CMDS_LAST     HCI_WRITE_REMOTE_AMP_ASSOC
+
+/* Commands of HCI_GRP_TESTING_CMDS group */
+#define HCI_READ_LOOPBACK_MODE          (0x0001 | HCI_GRP_TESTING_CMDS)
+#define HCI_WRITE_LOOPBACK_MODE         (0x0002 | HCI_GRP_TESTING_CMDS)
+#define HCI_ENABLE_DEV_UNDER_TEST_MODE  (0x0003 | HCI_GRP_TESTING_CMDS)
+#define HCI_WRITE_SIMP_PAIR_DEBUG_MODE  (0x0004 | HCI_GRP_TESTING_CMDS)
+
+/* AMP HCI */
+#define HCI_ENABLE_AMP_RCVR_REPORTS     (0x0007 | HCI_GRP_TESTING_CMDS)
+#define HCI_AMP_TEST_END                (0x0008 | HCI_GRP_TESTING_CMDS)
+#define HCI_AMP_TEST                    (0x0009 | HCI_GRP_TESTING_CMDS)
+
+#define HCI_TESTING_CMDS_FIRST          HCI_READ_LOOPBACK_MODE
+#define HCI_TESTING_CMDS_LAST           HCI_AMP_TEST
+
+#define HCI_VENDOR_CMDS_FIRST           0x0001
+#define HCI_VENDOR_CMDS_LAST            0xFFFF
+#define HCI_VSC_MULTI_AV_HANDLE         0x0AAA
+#define HCI_VSC_BURST_MODE_HANDLE       0x0BBB
+
+/* BLE HCI */
+#define HCI_GRP_BLE_CMDS                (0x08 << 10)
+/* Commands of BLE Controller setup and configuration */
+#define HCI_BLE_SET_EVENT_MASK          (0x0001 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_BUFFER_SIZE        (0x0002 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_LOCAL_SPT_FEAT     (0x0003 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_LOCAL_SPT_FEAT    (0x0004 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_RANDOM_ADDR       (0x0005 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_PARAMS        (0x0006 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_ADV_CHNL_TX_POWER  (0x0007 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_DATA          (0x0008 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_RSP_DATA     (0x0009 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_ENABLE        (0x000A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_PARAMS       (0x000B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_ENABLE       (0x000C | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_LL_CONN          (0x000D | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_CONN_CANCEL      (0x000E | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_WHITE_LIST_SIZE    (0x000F | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CLEAR_WHITE_LIST        (0x0010 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ADD_WHITE_LIST          (0x0011 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_REMOVE_WHITE_LIST       (0x0012 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_UPD_LL_CONN_PARAMS      (0x0013 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_HOST_CHNL_CLASS     (0x0014 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_CHNL_MAP           (0x0015 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_REMOTE_FEAT        (0x0016 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ENCRYPT                 (0x0017 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_RAND                    (0x0018 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_START_ENC               (0x0019 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_LTK_REQ_REPLY           (0x001A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_LTK_REQ_NEG_REPLY       (0x001B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_SUPPORTED_STATES   (0x001C | HCI_GRP_BLE_CMDS)
+
+#define HCI_BLE_RESET                   (0x0020 | HCI_GRP_BLE_CMDS)
+
+/* LE supported states definition */
+#define HCI_LE_ADV_STATE          0x00000001
+#define HCI_LE_SCAN_STATE         0x00000002
+#define HCI_LE_INIT_STATE         0x00000004
+#define HCI_LE_CONN_SL_STATE      0x00000008
+#define HCI_LE_ADV_SCAN_STATE     0x00000010
+#define HCI_LE_ADV_INIT_STATE     0x00000020
+#define HCI_LE_ADV_MA_STATE       0x00000040
+#define HCI_LE_ADV_SL_STATE       0x00000080
+#define HCI_LE_SCAN_INIT_STATE    0x00000100
+#define HCI_LE_SCAN_MA_STATE      0x00000200
+#define HCI_LE_SCAN_SL_STATE      0x00000400
+#define HCI_LE_INIT_MA_STATE      0x00000800
+
+/* Vendor specific commands for BRCM chipset */
+#define HCI_BRCM_UPDATE_BAUD_RATE_ENCODED_LENGTH        0x02
+#define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH      0x06
+#define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH                12
+#define HCI_BRCM_ENABLE_H4IBSS_LENGTH                   7
+#define HCI_BRCM_CUSTOMER_EXT               (0x0000 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_FM_OPCODE                  (0x0015 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_FMTX_OPCODE                (0x0082 | HCI_GRP_VENDOR_SPECIFIC)  /* FMTX VSC opcode */
+#define HCI_BRCM_UPDATE_BAUDRATE_CMD        (0x0018 | HCI_GRP_VENDOR_SPECIFIC)    /* set baudrate of BCM2035 */
+#define HCI_BRCM_WRITE_SCO_PCM_INT_PARAM    (0x001C | HCI_GRP_VENDOR_SPECIFIC)    /* set SCO interface param */
+#define HCI_BRCM_READ_SCO_PCM_INT_PARAM     (0x001D | HCI_GRP_VENDOR_SPECIFIC)    /* read SCO interface param */
+#define HCI_BRCM_WRITE_SLEEP_MODE           (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_SLEEP_MODE            (0x0028 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_H4IBSS_CMD                 (0x0029 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_DOWNLOAD_MINI_DRV          (0x002E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_USER_DEFINED_NVRAM    (0x0033 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_RADIO               (0x0034 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_DIAGNOSTIC_VALUE      (0x0035 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_GET_HID_DEVICE_LIST        (0x0036 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ADD_HID_DEVICE             (0x0037 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_WRITE_HID_DEVICE_NVRAM     (0x0038 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_DELETE_HID_DEVICE          (0x0039 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_USB_HID_EMULATION   (0x003B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_WRITE_RAM                  (0x004C | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_LAUNCH_RAM                 (0x004E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_BTW_STARTUP                (0x0053 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_SET_ACL_PRIORITY           (0x0057 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_SET_SEC_MODE               (0x0096 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_H4IBSS              (0x00D4 | HCI_GRP_VENDOR_SPECIFIC)
+
+#define HCI_BRCM_SUPER_PEEK_POKE            (0x000A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_ARM_MEM_PEEK                    0x04
+#define HCI_ARM_MEM_POKE                    0x05
+#define HCI_BRCM_SUPER_PEEK_POKE_LENGTH     9
+
+#define HCI_BRCM_WRITE_I2SPCM_INTF_PARAM    (0x006D | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_CONTROLLER_FEATURES   (0x006E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_FEATURE_NFC_MASK           0x10
+#define HCI_BRCM_FEATURE_NFC_OFF            0
+
+#define HCI_BRCM_READ_VERBOSE_CFG_VER_INFO  (0x0079 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* Dual Stack */
+#define HCI_BRCM_PAUSE_TRANSPORT            (0x007A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_TRANSPORT_RESUME           (0x007B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_TRANSPORT_ERROR_EVT        0x0C
+
+#define HCI_BRCM_TX_POWER_OPCODE            (0x007D | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_WBS                 (0x007E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_UIPC_OVER_HCI              (0x008B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_AUDIO_ROUTE_INFO      (0x00A2 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_UIPC_OVER_HCI_EVT          0x1A
+#define HCI_BRCM_ENCAPSULATED_HCI           (0x00A3 | HCI_GRP_VENDOR_SPECIFIC)
+/* VSE subcode - VSE format FF [len] [subcode] [vse params...] */
+#define HCI_BRCM_ENCAPSULATED_HCI_EVT       0x1E
+
+/* PCM2 Setup */
+#define HCI_BRCM_PCM2_SETUP                 (0x00AE | HCI_GRP_VENDOR_SPECIFIC)
+
+/* BRR */
+#define HCI_BRCM_SET_BRR                    (0x00AA | HCI_GRP_VENDOR_SPECIFIC)
+
+/* 3DTV */
+#define HCI_BRCM_3D_CTRL                    (0x00B7 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_3D_OFFSET_DELAY            (0x00D6 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* GPS */
+#define HCI_BRCM_GPS_DATA                   (0x0089 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_GPS_SENSOR_OPCODE          (0x008F | HCI_GRP_VENDOR_SPECIFIC)  /* GPS sensor VSC opcode */
+
+/* MIP: Multicast Individual Polling */
+#define HCI_BRCM_INIT_MIP                   (0x00DC | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_MIP_OPEN_CMD               (0x00DD | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_MIP_CLOSE_CMD              (0x00DE | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_MIP_ENC_KEY_CMD            (0x00DF | HCI_GRP_VENDOR_SPECIFIC)
+
+/* MIP-related definitions */
+#define BRCM_MIP_ROLE_MASTER                0x00
+#define BRCM_MIP_ROLE_SLAVE                 0x01
+
+#define BRCM_MIP_MODE_A2DP                  0x00
+#define BRCM_MIP_MODE_3DG                   0x01
+#define BRCM_MIP_MODE_CMBO                  0x02    /* A2DP + 3DG */
+
+/* Parameter information for HCI_BRCM_SET_ACL_PRIORITY */
+#define HCI_BRCM_ACL_PRIORITY_PARAM_SIZE    3
+#define HCI_BRCM_ACL_PRIORITY_LOW           0x00
+#define HCI_BRCM_ACL_PRIORITY_HIGH          0xFF
+
+#define HCI_BRCM_PAUSE_TRANSPORT_LENGTH     6
+
+/* Parameter information for HCI_BRCM_SCO_PCM_INT_PARAM */
+#define HCI_BRCM_SCO_PCM_PARAM_SIZE         5
+#define HCI_BRCM_SCO_ROUTE_PCM              0
+#define HCI_BRCM_SCO_ROUTE_HCI              1
+
+/* Parameter information for HCI_BRCM_WRITE_I2SPCM_INTF_PARAM */
+#define HCI_BRCM_I2SPCM_PARAM_SIZE          4
+#define HCI_BRCM_I2SPCM_I2S_DISABLE         0
+#define HCI_BRCM_I2SPCM_I2S_ENABLE          1
+#define HCI_BRCM_I2SPCM_IS_SLAVE            0
+#define HCI_BRCM_I2SPCM_IS_MASTER           1
+#define HCI_BRCM_I2SPCM_IS_DEFAULT_ROLE     2
+#define HCI_BRCM_I2SPCM_SAMPLE_8K           0
+#define HCI_BRCM_I2SPCM_SAMPLE_16K          1
+#define HCI_BRCM_I2SPCM_SAMPLE_4K           2
+#define HCI_BRCM_I2SPCM_SAMPLE_DEFAULT      3
+#define HCI_BRCM_I2SPCM_CLOCK_128K          0
+#define HCI_BRCM_I2SPCM_CLOCK_256K          1
+#define HCI_BRCM_I2SPCM_CLOCK_512K          2
+#define HCI_BRCM_I2SPCM_CLOCK_1024K         3
+#define HCI_BRCM_I2SPCM_CLOCK_2048K         4
+#define HCI_BRCM_I2SPCM_CLOCK_DEFAULT       5
+
+/*
+**  Definitions for HCI Events
+*/
+#define HCI_INQUIRY_COMP_EVT                0x01
+#define HCI_INQUIRY_RESULT_EVT              0x02
+#define HCI_CONNECTION_COMP_EVT             0x03
+#define HCI_CONNECTION_REQUEST_EVT          0x04
+#define HCI_DISCONNECTION_COMP_EVT          0x05
+#define HCI_AUTHENTICATION_COMP_EVT         0x06
+#define HCI_RMT_NAME_REQUEST_COMP_EVT       0x07
+#define HCI_ENCRYPTION_CHANGE_EVT           0x08
+#define HCI_CHANGE_CONN_LINK_KEY_EVT        0x09
+#define HCI_MASTER_LINK_KEY_COMP_EVT        0x0A
+#define HCI_READ_RMT_FEATURES_COMP_EVT      0x0B
+#define HCI_READ_RMT_VERSION_COMP_EVT       0x0C
+#define HCI_QOS_SETUP_COMP_EVT              0x0D
+#define HCI_COMMAND_COMPLETE_EVT            0x0E
+#define HCI_COMMAND_STATUS_EVT              0x0F
+#define HCI_HARDWARE_ERROR_EVT              0x10
+#define HCI_FLUSH_OCCURED_EVT               0x11
+#define HCI_ROLE_CHANGE_EVT                 0x12
+#define HCI_NUM_COMPL_DATA_PKTS_EVT         0x13
+#define HCI_MODE_CHANGE_EVT                 0x14
+#define HCI_RETURN_LINK_KEYS_EVT            0x15
+#define HCI_PIN_CODE_REQUEST_EVT            0x16
+#define HCI_LINK_KEY_REQUEST_EVT            0x17
+#define HCI_LINK_KEY_NOTIFICATION_EVT       0x18
+#define HCI_LOOPBACK_COMMAND_EVT            0x19
+#define HCI_DATA_BUF_OVERFLOW_EVT           0x1A
+#define HCI_MAX_SLOTS_CHANGED_EVT           0x1B
+#define HCI_READ_CLOCK_OFF_COMP_EVT         0x1C
+#define HCI_CONN_PKT_TYPE_CHANGE_EVT        0x1D
+#define HCI_QOS_VIOLATION_EVT               0x1E
+#define HCI_PAGE_SCAN_MODE_CHANGE_EVT       0x1F
+#define HCI_PAGE_SCAN_REP_MODE_CHNG_EVT     0x20
+#define HCI_FLOW_SPECIFICATION_COMP_EVT     0x21
+#define HCI_INQUIRY_RSSI_RESULT_EVT         0x22
+#define HCI_READ_RMT_EXT_FEATURES_COMP_EVT  0x23
+#define HCI_ESCO_CONNECTION_COMP_EVT        0x2C
+#define HCI_ESCO_CONNECTION_CHANGED_EVT     0x2D
+#define HCI_SNIFF_SUB_RATE_EVT              0x2E
+#define HCI_EXTENDED_INQUIRY_RESULT_EVT     0x2F
+#define HCI_ENCRYPTION_KEY_REFRESH_COMP_EVT 0x30
+#define HCI_IO_CAPABILITY_REQUEST_EVT       0x31
+#define HCI_IO_CAPABILITY_RESPONSE_EVT      0x32
+#define HCI_USER_CONFIRMATION_REQUEST_EVT   0x33
+#define HCI_USER_PASSKEY_REQUEST_EVT        0x34
+#define HCI_REMOTE_OOB_DATA_REQUEST_EVT     0x35
+#define HCI_SIMPLE_PAIRING_COMPLETE_EVT     0x36
+#define HCI_LINK_SUPER_TOUT_CHANGED_EVT     0x38
+#define HCI_ENHANCED_FLUSH_COMPLETE_EVT     0x39
+#define HCI_USER_PASSKEY_NOTIFY_EVT         0x3B
+#define HCI_KEYPRESS_NOTIFY_EVT             0x3C
+#define HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT    0x3D
+
+/*#define HCI_GENERIC_AMP_LINK_KEY_NOTIF_EVT  0x3E Removed from spec */
+#define HCI_PHYSICAL_LINK_COMP_EVT          0x40
+#define HCI_CHANNEL_SELECTED_EVT            0x41
+#define HCI_DISC_PHYSICAL_LINK_COMP_EVT     0x42
+#define HCI_PHY_LINK_LOSS_EARLY_WARNING_EVT 0x43
+#define HCI_PHY_LINK_RECOVERY_EVT           0x44
+#define HCI_LOGICAL_LINK_COMP_EVT           0x45
+#define HCI_DISC_LOGICAL_LINK_COMP_EVT      0x46
+#define HCI_FLOW_SPEC_MODIFY_COMP_EVT       0x47
+#define HCI_NUM_COMPL_DATA_BLOCKS_EVT       0x48
+#define HCI_SHORT_RANGE_MODE_COMPLETE_EVT   0x4C
+#define HCI_AMP_STATUS_CHANGE_EVT           0x4D
+
+/* ULP HCI Event */
+#define HCI_BLE_EVENT                   0x03E
+/* ULP Event sub code */
+#define HCI_BLE_CONN_COMPLETE_EVT           0x01
+#define HCI_BLE_ADV_PKT_RPT_EVT             0x02
+#define HCI_BLE_LL_CONN_PARAM_UPD_EVT       0x03
+#define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT   0x04
+#define HCI_BLE_LTK_REQ_EVT                 0x05
+
+#define HCI_EVENT_RSP_FIRST             HCI_INQUIRY_COMP_EVT
+#define HCI_EVENT_RSP_LAST              HCI_AMP_STATUS_CHANGE_EVT
+
+#define HCI_BRCM_H4IBSS_EVT             0xEF  /* Vendor specific events for H4IBSS */
+#define HCI_VENDOR_SPECIFIC_EVT         0xFF  /* Vendor specific events */
+#define HCI_NAP_TRACE_EVT               0xFF  /* was define 0xFE, 0xFD, change to 0xFF
+                                                 because conflict w/ TCI_EVT and per
+                                                 specification compliant */
+
+
+
+/*
+**  Defentions for HCI Error Codes that are past in the events
+*/
+#define HCI_SUCCESS                                     0x00
+#define HCI_PENDING                                     0x00
+#define HCI_ERR_ILLEGAL_COMMAND                         0x01
+#define HCI_ERR_NO_CONNECTION                           0x02
+#define HCI_ERR_HW_FAILURE                              0x03
+#define HCI_ERR_PAGE_TIMEOUT                            0x04
+#define HCI_ERR_AUTH_FAILURE                            0x05
+#define HCI_ERR_KEY_MISSING                             0x06
+#define HCI_ERR_MEMORY_FULL                             0x07
+#define HCI_ERR_CONNECTION_TOUT                         0x08
+#define HCI_ERR_MAX_NUM_OF_CONNECTIONS                  0x09
+#define HCI_ERR_MAX_NUM_OF_SCOS                         0x0A
+#define HCI_ERR_CONNECTION_EXISTS                       0x0B
+#define HCI_ERR_COMMAND_DISALLOWED                      0x0C
+#define HCI_ERR_HOST_REJECT_RESOURCES                   0x0D
+#define HCI_ERR_HOST_REJECT_SECURITY                    0x0E
+#define HCI_ERR_HOST_REJECT_DEVICE                      0x0F
+#define HCI_ERR_HOST_TIMEOUT                            0x10
+#define HCI_ERR_UNSUPPORTED_VALUE                       0x11
+#define HCI_ERR_ILLEGAL_PARAMETER_FMT                   0x12
+#define HCI_ERR_PEER_USER                               0x13
+#define HCI_ERR_PEER_LOW_RESOURCES                      0x14
+#define HCI_ERR_PEER_POWER_OFF                          0x15
+#define HCI_ERR_CONN_CAUSE_LOCAL_HOST                   0x16
+#define HCI_ERR_REPEATED_ATTEMPTS                       0x17
+#define HCI_ERR_PAIRING_NOT_ALLOWED                     0x18
+#define HCI_ERR_UNKNOWN_LMP_PDU                         0x19
+#define HCI_ERR_UNSUPPORTED_REM_FEATURE                 0x1A
+#define HCI_ERR_SCO_OFFSET_REJECTED                     0x1B
+#define HCI_ERR_SCO_INTERVAL_REJECTED                   0x1C
+#define HCI_ERR_SCO_AIR_MODE                            0x1D
+#define HCI_ERR_INVALID_LMP_PARAM                       0x1E
+#define HCI_ERR_UNSPECIFIED                             0x1F
+#define HCI_ERR_UNSUPPORTED_LMP_FEATURE                 0x20
+#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED                 0x21
+#define HCI_ERR_LMP_RESPONSE_TIMEOUT                    0x22
+#define HCI_ERR_LMP_ERR_TRANS_COLLISION                 0x23
+#define HCI_ERR_LMP_PDU_NOT_ALLOWED                     0x24
+#define HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE               0x25
+#define HCI_ERR_UNIT_KEY_USED                           0x26
+#define HCI_ERR_QOS_NOT_SUPPORTED                       0x27
+#define HCI_ERR_INSTANT_PASSED                          0x28
+#define HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED     0x29
+#define HCI_ERR_DIFF_TRANSACTION_COLLISION              0x2A
+#define HCI_ERR_UNDEFINED_0x2B                          0x2B
+#define HCI_ERR_QOS_UNACCEPTABLE_PARAM                  0x2C
+#define HCI_ERR_QOS_REJECTED                            0x2D
+#define HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED              0x2E
+#define HCI_ERR_INSUFFCIENT_SECURITY                    0x2F
+#define HCI_ERR_PARAM_OUT_OF_RANGE                      0x30
+#define HCI_ERR_UNDEFINED_0x31                          0x31
+#define HCI_ERR_ROLE_SWITCH_PENDING                     0x32
+#define HCI_ERR_UNDEFINED_0x33                          0x33
+#define HCI_ERR_RESERVED_SLOT_VIOLATION                 0x34
+#define HCI_ERR_ROLE_SWITCH_FAILED                      0x35
+#define HCI_ERR_INQ_RSP_DATA_TOO_LARGE                  0x36
+#define HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED            0x37
+#define HCI_ERR_HOST_BUSY_PAIRING                       0x38
+#define HCI_ERR_REJ_NO_SUITABLE_CHANNEL                 0x39
+#define HCI_ERR_CONTROLLER_BUSY                         0x3A
+#define HCI_ERR_UNACCEPT_CONN_INTERVAL                  0x3B
+#define HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT            0x3C
+#define HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE            0x3D
+#define HCI_ERR_CONN_FAILED_ESTABLISHMENT               0x3E
+#define HCI_ERR_MAC_CONNECTION_FAILED                   0x3F
+
+#define HCI_ERR_MAX_ERR                                 0x40
+
+#define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK              0xFF
+
+/*
+** Definitions for HCI enable event
+*/
+#define HCI_INQUIRY_COMPLETE_EV(p)          (*((UINT32 *)(p)) & 0x00000001)
+#define HCI_INQUIRY_RESULT_EV(p)            (*((UINT32 *)(p)) & 0x00000002)
+#define HCI_CONNECTION_COMPLETE_EV(p)       (*((UINT32 *)(p)) & 0x00000004)
+#define HCI_CONNECTION_REQUEST_EV(p)        (*((UINT32 *)(p)) & 0x00000008)
+#define HCI_DISCONNECTION_COMPLETE_EV(p)    (*((UINT32 *)(p)) & 0x00000010)
+#define HCI_AUTHENTICATION_COMPLETE_EV(p)   (*((UINT32 *)(p)) & 0x00000020)
+#define HCI_RMT_NAME_REQUEST_COMPL_EV(p)    (*((UINT32 *)(p)) & 0x00000040)
+#define HCI_CHANGE_CONN_ENCRPT_ENABLE_EV(p) (*((UINT32 *)(p)) & 0x00000080)
+#define HCI_CHANGE_CONN_LINK_KEY_EV(p)      (*((UINT32 *)(p)) & 0x00000100)
+#define HCI_MASTER_LINK_KEY_COMPLETE_EV(p)  (*((UINT32 *)(p)) & 0x00000200)
+#define HCI_READ_RMT_FEATURES_COMPL_EV(p)   (*((UINT32 *)(p)) & 0x00000400)
+#define HCI_READ_RMT_VERSION_COMPL_EV(p)    (*((UINT32 *)(p)) & 0x00000800)
+#define HCI_QOS_SETUP_COMPLETE_EV(p)        (*((UINT32 *)(p)) & 0x00001000)
+#define HCI_COMMAND_COMPLETE_EV(p)          (*((UINT32 *)(p)) & 0x00002000)
+#define HCI_COMMAND_STATUS_EV(p)            (*((UINT32 *)(p)) & 0x00004000)
+#define HCI_HARDWARE_ERROR_EV(p)            (*((UINT32 *)(p)) & 0x00008000)
+#define HCI_FLASH_OCCURED_EV(p)             (*((UINT32 *)(p)) & 0x00010000)
+#define HCI_ROLE_CHANGE_EV(p)               (*((UINT32 *)(p)) & 0x00020000)
+#define HCI_NUM_COMPLETED_PKTS_EV(p)        (*((UINT32 *)(p)) & 0x00040000)
+#define HCI_MODE_CHANGE_EV(p)               (*((UINT32 *)(p)) & 0x00080000)
+#define HCI_RETURN_LINK_KEYS_EV(p)          (*((UINT32 *)(p)) & 0x00100000)
+#define HCI_PIN_CODE_REQUEST_EV(p)          (*((UINT32 *)(p)) & 0x00200000)
+#define HCI_LINK_KEY_REQUEST_EV(p)          (*((UINT32 *)(p)) & 0x00400000)
+#define HCI_LINK_KEY_NOTIFICATION_EV(p)     (*((UINT32 *)(p)) & 0x00800000)
+#define HCI_LOOPBACK_COMMAND_EV(p)          (*((UINT32 *)(p)) & 0x01000000)
+#define HCI_DATA_BUF_OVERFLOW_EV(p)         (*((UINT32 *)(p)) & 0x02000000)
+#define HCI_MAX_SLOTS_CHANGE_EV(p)          (*((UINT32 *)(p)) & 0x04000000)
+#define HCI_READ_CLOCK_OFFSET_COMP_EV(p)    (*((UINT32 *)(p)) & 0x08000000)
+#define HCI_CONN_PKT_TYPE_CHANGED_EV(p)     (*((UINT32 *)(p)) & 0x10000000)
+#define HCI_QOS_VIOLATION_EV(p)             (*((UINT32 *)(p)) & 0x20000000)
+#define HCI_PAGE_SCAN_MODE_CHANGED_EV(p)    (*((UINT32 *)(p)) & 0x40000000)
+#define HCI_PAGE_SCAN_REP_MODE_CHNG_EV(p)   (*((UINT32 *)(p)) & 0x80000000)
+
+/* the default event mask for 2.1+EDR (Lisbon) does not include Lisbon events */
+#define HCI_DEFAULT_EVENT_MASK_0            0xFFFFFFFF
+#define HCI_DEFAULT_EVENT_MASK_1            0x00001FFF
+
+/* the event mask for 2.0 + EDR and later (includes Lisbon events) */
+#define HCI_LISBON_EVENT_MASK_0             0xFFFFFFFF
+#define HCI_LISBON_EVENT_MASK_1             0x1DBFFFFF
+#define HCI_LISBON_EVENT_MASK               "\x0D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+#define HCI_LISBON_EVENT_MASK_EXT           "\x1D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+#define HCI_DUMO_EVENT_MASK_EXT             "\x3D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+/*  0x00001FFF FFFFFFFF Default - no Lisbon events
+    0x00000800 00000000 Synchronous Connection Complete Event
+    0x00001000 00000000 Synchronous Connection Changed Event
+    0x00002000 00000000 Sniff Subrate Event
+    0x00004000 00000000 Extended Inquiry Result Event
+    0x00008000 00000000 Encryption Key Refresh Complete Event
+    0x00010000 00000000 IO Capability Request Event
+    0x00020000 00000000 IO Capability Response Event
+    0x00040000 00000000 User Confirmation Request Event
+    0x00080000 00000000 User Passkey Request Event
+    0x00100000 00000000 Remote OOB Data Request Event
+    0x00200000 00000000 Simple Pairing Complete Event
+    0x00400000 00000000 Generic AMP Link Key Notification Event
+    0x00800000 00000000 Link Supervision Timeout Changed Event
+    0x01000000 00000000 Enhanced Flush Complete Event
+    0x04000000 00000000 User Passkey Notification Event
+    0x08000000 00000000 Keypress Notification Event
+    0x10000000 00000000 Remote Host Supported Features Notification Event
+    0x20000000 00000000 LE Meta Event
+ */
+
+
+/* the event mask for AMP controllers */
+#define HCI_AMP_EVENT_MASK_3_0               "\x00\x00\x00\x00\x00\x00\x3F\xFF"
+
+/*  0x0000000000000000 No events specified (default)
+    0x0000000000000001 Physical Link Complete Event
+    0x0000000000000002 Channel Selected Event
+    0x0000000000000004 Disconnection Physical Link Event
+    0x0000000000000008 Physical Link Loss Early Warning Event
+    0x0000000000000010 Physical Link Recovery Event
+    0x0000000000000020 Logical Link Complete Event
+    0x0000000000000040 Disconnection Logical Link Complete Event
+    0x0000000000000080 Flow Spec Modify Complete Event
+    0x0000000000000100 Number of Completed Data Blocks Event
+    0x0000000000000200 AMP Start Test Event
+    0x0000000000000400 AMP Test End Event
+    0x0000000000000800 AMP Receiver Report Event
+    0x0000000000001000 Short Range Mode Change Complete Event
+    0x0000000000002000 AMP Status Change Event
+*/
+
+
+/*
+** Definitions for packet type masks (BT1.2 and BT2.0 definitions)
+*/
+#define HCI_PKT_TYPES_MASK_NO_2_DH1         0x0002
+#define HCI_PKT_TYPES_MASK_NO_3_DH1         0x0004
+#define HCI_PKT_TYPES_MASK_DM1              0x0008
+#define HCI_PKT_TYPES_MASK_DH1              0x0010
+#define HCI_PKT_TYPES_MASK_HV1              0x0020
+#define HCI_PKT_TYPES_MASK_HV2              0x0040
+#define HCI_PKT_TYPES_MASK_HV3              0x0080
+#define HCI_PKT_TYPES_MASK_NO_2_DH3         0x0100
+#define HCI_PKT_TYPES_MASK_NO_3_DH3         0x0200
+#define HCI_PKT_TYPES_MASK_DM3              0x0400
+#define HCI_PKT_TYPES_MASK_DH3              0x0800
+#define HCI_PKT_TYPES_MASK_NO_2_DH5         0x1000
+#define HCI_PKT_TYPES_MASK_NO_3_DH5         0x2000
+#define HCI_PKT_TYPES_MASK_DM5              0x4000
+#define HCI_PKT_TYPES_MASK_DH5              0x8000
+
+/* Packet type should be one of valid but at least one should be specified */
+#define HCI_VALID_SCO_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_HV1       \
+                                           |  HCI_PKT_TYPES_MASK_HV2       \
+                                           |  HCI_PKT_TYPES_MASK_HV3)) == 0)) \
+                                    && ((t) != 0))
+
+
+
+
+
+/* Packet type should not be invalid and at least one should be specified */
+#define HCI_VALID_ACL_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_DM1        \
+                                           |  HCI_PKT_TYPES_MASK_DH1        \
+                                           |  HCI_PKT_TYPES_MASK_DM3        \
+                                           |  HCI_PKT_TYPES_MASK_DH3        \
+                                           |  HCI_PKT_TYPES_MASK_DM5        \
+                                           |  HCI_PKT_TYPES_MASK_DH5        \
+                                           |  HCI_PKT_TYPES_MASK_NO_2_DH1   \
+                                           |  HCI_PKT_TYPES_MASK_NO_3_DH1   \
+                                           |  HCI_PKT_TYPES_MASK_NO_2_DH3   \
+                                           |  HCI_PKT_TYPES_MASK_NO_3_DH3   \
+                                           |  HCI_PKT_TYPES_MASK_NO_2_DH5   \
+                                           |  HCI_PKT_TYPES_MASK_NO_3_DH5  )) == 0)) \
+                                    && (((t) &  (HCI_PKT_TYPES_MASK_DM1        \
+                                              |  HCI_PKT_TYPES_MASK_DH1        \
+                                              |  HCI_PKT_TYPES_MASK_DM3        \
+                                              |  HCI_PKT_TYPES_MASK_DH3        \
+                                              |  HCI_PKT_TYPES_MASK_DM5        \
+                                              |  HCI_PKT_TYPES_MASK_DH5)) != 0))
+
+/*
+** Definitions for eSCO packet type masks (BT1.2 and BT2.0 definitions)
+*/
+#define HCI_ESCO_PKT_TYPES_MASK_HV1         0x0001
+#define HCI_ESCO_PKT_TYPES_MASK_HV2         0x0002
+#define HCI_ESCO_PKT_TYPES_MASK_HV3         0x0004
+#define HCI_ESCO_PKT_TYPES_MASK_EV3         0x0008
+#define HCI_ESCO_PKT_TYPES_MASK_EV4         0x0010
+#define HCI_ESCO_PKT_TYPES_MASK_EV5         0x0020
+#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3    0x0040
+#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3    0x0080
+#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5    0x0100
+#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5    0x0200
+
+/* Packet type should be one of valid but at least one should be specified for 1.2 */
+#define HCI_VALID_ESCO_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_EV3       \
+                                           |   HCI_ESCO_PKT_TYPES_MASK_EV4       \
+                                           |   HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \
+                                    && ((t) != 0))/* Packet type should be one of valid but at least one should be specified */
+
+#define HCI_VALID_ESCO_SCOPKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV2       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV3)) == 0)) \
+                                    && ((t) != 0))
+
+#define HCI_VALID_SCO_ALL_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV2       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV3       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_EV3       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_EV4       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \
+                                    && ((t) != 0))
+
+/*
+** Define parameters to allow role switch during create connection
+*/
+#define HCI_CR_CONN_NOT_ALLOW_SWITCH    0x00
+#define HCI_CR_CONN_ALLOW_SWITCH        0x01
+
+/*
+** Hold Mode command destination
+*/
+#define HOLD_MODE_DEST_LOCAL_DEVICE     0x00
+#define HOLD_MODE_DEST_RMT_DEVICE       0x01
+
+/*
+**  Definitions for different HCI parameters
+*/
+#define HCI_PER_INQ_MIN_MAX_PERIOD      0x0003
+#define HCI_PER_INQ_MAX_MAX_PERIOD      0xFFFF
+#define HCI_PER_INQ_MIN_MIN_PERIOD      0x0002
+#define HCI_PER_INQ_MAX_MIN_PERIOD      0xFFFE
+
+#define HCI_MAX_INQUIRY_LENGTH          0x30
+
+#define HCI_MIN_INQ_LAP                 0x9E8B00
+#define HCI_MAX_INQ_LAP                 0x9E8B3F
+
+/* HCI role defenitions */
+#define HCI_ROLE_MASTER                 0x00
+#define HCI_ROLE_SLAVE                  0x01
+#define HCI_ROLE_UNKNOWN                0xff
+
+/* HCI mode defenitions */
+#define HCI_MODE_ACTIVE                 0x00
+#define HCI_MODE_HOLD                   0x01
+#define HCI_MODE_SNIFF                  0x02
+#define HCI_MODE_PARK                   0x03
+
+/* HCI Flow Control Mode defenitions */
+#define HCI_PACKET_BASED_FC_MODE        0x00
+#define HCI_BLOCK_BASED_FC_MODE         0x01
+
+/* Define Packet types as requested by the Host */
+#define HCI_ACL_PKT_TYPE_NONE           0x0000
+#define HCI_ACL_PKT_TYPE_DM1            0x0008
+#define HCI_ACL_PKT_TYPE_DH1            0x0010
+#define HCI_ACL_PKT_TYPE_AUX1           0x0200
+#define HCI_ACL_PKT_TYPE_DM3            0x0400
+#define HCI_ACL_PKT_TYPE_DH3            0x0800
+#define HCI_ACL_PKT_TYPE_DM5            0x4000
+#define HCI_ACL_PKT_TYPE_DH5            0x8000
+
+/* Define key type in the Master Link Key command */
+#define HCI_USE_SEMI_PERMANENT_KEY      0x00
+#define HCI_USE_TEMPORARY_KEY           0x01
+
+/* Page scan period modes */
+#define HCI_PAGE_SCAN_REP_MODE_R0       0x00
+#define HCI_PAGE_SCAN_REP_MODE_R1       0x01
+#define HCI_PAGE_SCAN_REP_MODE_R2       0x02
+
+/* Define limits for page scan repetition modes */
+#define HCI_PAGE_SCAN_R1_LIMIT          0x0800
+#define HCI_PAGE_SCAN_R2_LIMIT          0x1000
+
+/* Page scan period modes */
+#define HCI_PAGE_SCAN_PER_MODE_P0       0x00
+#define HCI_PAGE_SCAN_PER_MODE_P1       0x01
+#define HCI_PAGE_SCAN_PER_MODE_P2       0x02
+
+/* Page scan modes */
+#define HCI_MANDATARY_PAGE_SCAN_MODE    0x00
+#define HCI_OPTIONAL_PAGE_SCAN_MODE1    0x01
+#define HCI_OPTIONAL_PAGE_SCAN_MODE2    0x02
+#define HCI_OPTIONAL_PAGE_SCAN_MODE3    0x03
+
+/* Page and inquiry scan types */
+#define HCI_SCAN_TYPE_STANDARD          0x00
+#define HCI_SCAN_TYPE_INTERLACED        0x01       /* 1.2 devices or later */
+#define HCI_DEF_SCAN_TYPE               HCI_SCAN_TYPE_STANDARD
+
+/* Definitions for quality of service service types */
+#define HCI_SERVICE_NO_TRAFFIC          0x00
+#define HCI_SERVICE_BEST_EFFORT         0x01
+#define HCI_SERVICE_GUARANTEED          0x02
+
+#define HCI_QOS_LATENCY_DO_NOT_CARE     0xFFFFFFFF
+#define HCI_QOS_DELAY_DO_NOT_CARE       0xFFFFFFFF
+
+/* Definitions for Flow Specification */
+#define HCI_FLOW_SPEC_LATENCY_DO_NOT_CARE 0xFFFFFFFF
+
+/* Definitions for AFH Channel Map */
+#define HCI_AFH_CHANNEL_MAP_LEN         10
+
+/* Definitions for Extended Inquiry Response */
+#define HCI_EXT_INQ_RESPONSE_LEN        240
+#define HCI_EIR_FLAGS_TYPE                   BT_EIR_FLAGS_TYPE
+#define HCI_EIR_MORE_16BITS_UUID_TYPE        BT_EIR_MORE_16BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_16BITS_UUID_TYPE    BT_EIR_COMPLETE_16BITS_UUID_TYPE
+#define HCI_EIR_MORE_32BITS_UUID_TYPE        BT_EIR_MORE_32BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_32BITS_UUID_TYPE    BT_EIR_COMPLETE_32BITS_UUID_TYPE
+#define HCI_EIR_MORE_128BITS_UUID_TYPE       BT_EIR_MORE_128BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_128BITS_UUID_TYPE   BT_EIR_COMPLETE_128BITS_UUID_TYPE
+#define HCI_EIR_SHORTENED_LOCAL_NAME_TYPE    BT_EIR_SHORTENED_LOCAL_NAME_TYPE
+#define HCI_EIR_COMPLETE_LOCAL_NAME_TYPE     BT_EIR_COMPLETE_LOCAL_NAME_TYPE
+#define HCI_EIR_TX_POWER_LEVEL_TYPE          BT_EIR_TX_POWER_LEVEL_TYPE
+#define HCI_EIR_MANUFACTURER_SPECIFIC_TYPE   BT_EIR_MANUFACTURER_SPECIFIC_TYPE
+#define HCI_EIR_OOB_BD_ADDR_TYPE             BT_EIR_OOB_BD_ADDR_TYPE
+#define HCI_EIR_OOB_COD_TYPE                 BT_EIR_OOB_COD_TYPE
+#define HCI_EIR_OOB_SSP_HASH_C_TYPE          BT_EIR_OOB_SSP_HASH_C_TYPE
+#define HCI_EIR_OOB_SSP_RAND_R_TYPE          BT_EIR_OOB_SSP_RAND_R_TYPE
+
+/* Definitions for Write Simple Pairing Mode */
+#define HCI_SP_MODE_UNDEFINED           0x00
+#define HCI_SP_MODE_ENABLED             0x01
+
+/* Definitions for Write Simple Pairing Debug Mode */
+#define HCI_SPD_MODE_DISABLED           0x00
+#define HCI_SPD_MODE_ENABLED            0x01
+
+/* Definitions for IO Capability Response/Command */
+#define HCI_IO_CAP_DISPLAY_ONLY         0x00
+#define HCI_IO_CAP_DISPLAY_YESNO        0x01
+#define HCI_IO_CAP_KEYBOARD_ONLY        0x02
+#define HCI_IO_CAP_NO_IO                0x03
+
+#define HCI_OOB_AUTH_DATA_NOT_PRESENT   0x00
+#define HCI_OOB_REM_AUTH_DATA_PRESENT   0x01
+
+#define HCI_MITM_PROTECT_NOT_REQUIRED  0x00
+#define HCI_MITM_PROTECT_REQUIRED      0x01
+
+
+/* Policy settings status */
+#define HCI_DISABLE_ALL_LM_MODES        0x0000
+#define HCI_ENABLE_MASTER_SLAVE_SWITCH  0x0001
+#define HCI_ENABLE_HOLD_MODE            0x0002
+#define HCI_ENABLE_SNIFF_MODE           0x0004
+#define HCI_ENABLE_PARK_MODE            0x0008
+
+/* By default allow switch, because host can not allow that */
+/* that until he created the connection */
+#define HCI_DEFAULT_POLICY_SETTINGS     HCI_DISABLE_ALL_LM_MODES
+
+/* Filters that are sent in set filter command */
+#define HCI_FILTER_TYPE_CLEAR_ALL       0x00
+#define HCI_FILTER_INQUIRY_RESULT       0x01
+#define HCI_FILTER_CONNECTION_SETUP     0x02
+
+#define HCI_FILTER_COND_NEW_DEVICE      0x00
+#define HCI_FILTER_COND_DEVICE_CLASS    0x01
+#define HCI_FILTER_COND_BD_ADDR         0x02
+
+#define HCI_DO_NOT_AUTO_ACCEPT_CONNECT  1
+#define HCI_DO_AUTO_ACCEPT_CONNECT      2   /* role switch disabled */
+#define HCI_DO_AUTO_ACCEPT_CONNECT_RS   3   /* role switch enabled (1.1 errata 1115) */
+
+/* Auto accept flags */
+#define HCI_AUTO_ACCEPT_OFF             0x00
+#define HCI_AUTO_ACCEPT_ACL_CONNECTIONS 0x01
+#define HCI_AUTO_ACCEPT_SCO_CONNECTIONS 0x02
+
+/* PIN type */
+#define HCI_PIN_TYPE_VARIABLE           0
+#define HCI_PIN_TYPE_FIXED              1
+
+/* Loopback Modes */
+#define HCI_LOOPBACK_MODE_DISABLED      0
+#define HCI_LOOPBACK_MODE_LOCAL         1
+#define HCI_LOOPBACK_MODE_REMOTE        2
+
+#define SLOTS_PER_10MS                  16      /* 0.625 ms slots in a 10 ms tick */
+
+/* Maximum connection accept timeout in 0.625msec */
+#define HCI_MAX_CONN_ACCEPT_TOUT        0xB540  /* 29 sec */
+#define HCI_DEF_CONN_ACCEPT_TOUT        0x1F40  /* 5 sec */
+
+/* Page timeout is used in LC only and LC is counting down slots not using OS */
+#define HCI_DEFAULT_PAGE_TOUT           0x2000  /* 5.12 sec (in slots) */
+
+/* Scan enable flags */
+#define HCI_NO_SCAN_ENABLED             0x00
+#define HCI_INQUIRY_SCAN_ENABLED        0x01
+#define HCI_PAGE_SCAN_ENABLED           0x02
+
+/* Pagescan timer definitions in 0.625 ms */
+#define HCI_MIN_PAGESCAN_INTERVAL       0x12    /* 11.25 ms */
+#define HCI_MAX_PAGESCAN_INTERVAL       0x1000  /* 2.56 sec */
+#define HCI_DEF_PAGESCAN_INTERVAL       0x0800  /* 1.28 sec */
+
+/* Parameter for pagescan window is passed to LC and is kept in slots */
+#define HCI_MIN_PAGESCAN_WINDOW         0x11    /* 10.625 ms */
+#define HCI_MAX_PAGESCAN_WINDOW         0x1000  /* 2.56  sec */
+#define HCI_DEF_PAGESCAN_WINDOW         0x12    /* 11.25 ms  */
+
+/* Inquiryscan timer definitions in 0.625 ms */
+#define HCI_MIN_INQUIRYSCAN_INTERVAL    0x12    /* 11.25 ms */
+#define HCI_MAX_INQUIRYSCAN_INTERVAL    0x1000  /* 2.56 sec */
+#define HCI_DEF_INQUIRYSCAN_INTERVAL    0x1000  /* 2.56 sec */
+
+/* Parameter for inquiryscan window is passed to LC and is kept in slots */
+#define HCI_MIN_INQUIRYSCAN_WINDOW      0x11    /* 10.625 ms */
+#define HCI_MAX_INQUIRYSCAN_WINDOW      0x1000  /* 2.56 sec */
+#define HCI_DEF_INQUIRYSCAN_WINDOW      0x12    /* 11.25 ms */
+
+/* Encryption modes */
+#define HCI_ENCRYPT_MODE_DISABLED       0x00
+#define HCI_ENCRYPT_MODE_POINT_TO_POINT 0x01
+#define HCI_ENCRYPT_MODE_ALL            0x02
+
+/* Voice settings */
+#define HCI_INP_CODING_LINEAR           0x0000 /* 0000000000 */
+#define HCI_INP_CODING_U_LAW            0x0100 /* 0100000000 */
+#define HCI_INP_CODING_A_LAW            0x0200 /* 1000000000 */
+#define HCI_INP_CODING_MASK             0x0300 /* 1100000000 */
+
+#define HCI_INP_DATA_FMT_1S_COMPLEMENT  0x0000 /* 0000000000 */
+#define HCI_INP_DATA_FMT_2S_COMPLEMENT  0x0040 /* 0001000000 */
+#define HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 /* 0010000000 */
+#define HCI_INP_DATA_FMT_UNSIGNED       0x00c0 /* 0011000000 */
+#define HCI_INP_DATA_FMT_MASK           0x00c0 /* 0011000000 */
+
+#define HCI_INP_SAMPLE_SIZE_8BIT        0x0000 /* 0000000000 */
+#define HCI_INP_SAMPLE_SIZE_16BIT       0x0020 /* 0000100000 */
+#define HCI_INP_SAMPLE_SIZE_MASK        0x0020 /* 0000100000 */
+
+#define HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c /* 0000011100 */
+#define HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
+
+#define HCI_AIR_CODING_FORMAT_CVSD      0x0000 /* 0000000000 */
+#define HCI_AIR_CODING_FORMAT_U_LAW     0x0001 /* 0000000001 */
+#define HCI_AIR_CODING_FORMAT_A_LAW     0x0002 /* 0000000010 */
+#define HCI_AIR_CODING_FORMAT_TRANSPNT  0x0003 /* 0000000011 */
+#define HCI_AIR_CODING_FORMAT_MASK      0x0003 /* 0000000011 */
+
+/* default                                        0001100000 */
+#define HCI_DEFAULT_VOICE_SETTINGS    (HCI_INP_CODING_LINEAR \
+                                     | HCI_INP_DATA_FMT_2S_COMPLEMENT \
+                                     | HCI_INP_SAMPLE_SIZE_16BIT \
+                                     | HCI_AIR_CODING_FORMAT_CVSD)
+
+#define HCI_CVSD_SUPPORTED(x)       (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_CVSD)
+#define HCI_U_LAW_SUPPORTED(x)      (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_U_LAW)
+#define HCI_A_LAW_SUPPORTED(x)      (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_A_LAW)
+#define HCI_TRANSPNT_SUPPORTED(x)   (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_TRANSPNT)
+
+/* Retransmit timer definitions in 0.625 */
+#define HCI_MAX_AUTO_FLUSH_TOUT         0x07FF
+#define HCI_DEFAULT_AUTO_FLUSH_TOUT     0       /* No auto flush */
+
+/* Broadcast retransmitions */
+#define HCI_DEFAULT_NUM_BCAST_RETRAN    1
+
+/* Define broadcast data types as passed in the hci data packet */
+#define HCI_DATA_POINT_TO_POINT         0x00
+#define HCI_DATA_ACTIVE_BCAST           0x01
+#define HCI_DATA_PICONET_BCAST          0x02
+
+/* Hold mode activity */
+#define HCI_MAINTAIN_CUR_POWER_STATE    0x00
+#define HCI_SUSPEND_PAGE_SCAN           0x01
+#define HCI_SUSPEND_INQUIRY_SCAN        0x02
+#define HCI_SUSPEND_PERIODIC_INQUIRIES  0x04
+
+/* Default Link Supervision timeoout */
+#define HCI_DEFAULT_INACT_TOUT          0x7D00  /* BR/EDR (20 seconds) */
+#define HCI_DEFAULT_AMP_INACT_TOUT      0x3E80  /* AMP    (10 seconds) */
+
+/* Read transmit power level parameter */
+#define HCI_READ_CURRENT                0x00
+#define HCI_READ_MAXIMUM                0x01
+
+/* Link types for connection complete event */
+#define HCI_LINK_TYPE_SCO               0x00
+#define HCI_LINK_TYPE_ACL               0x01
+#define HCI_LINK_TYPE_ESCO              0x02
+
+/* Link Key Notification Event (Key Type) definitions */
+#define HCI_LKEY_TYPE_COMBINATION       0x00
+#define HCI_LKEY_TYPE_LOCAL_UNIT        0x01
+#define HCI_LKEY_TYPE_REMOTE_UNIT       0x02
+#define HCI_LKEY_TYPE_DEBUG_COMB        0x03
+#define HCI_LKEY_TYPE_UNAUTH_COMB       0x04
+#define HCI_LKEY_TYPE_AUTH_COMB         0x05
+#define HCI_LKEY_TYPE_CHANGED_COMB      0x06
+
+/* Internal definitions - not used over HCI */
+#define HCI_LKEY_TYPE_AMP_WIFI          0x80
+#define HCI_LKEY_TYPE_AMP_UWB           0x81
+#define HCI_LKEY_TYPE_UNKNOWN           0xff
+
+/* Read Local Version HCI Version return values (Command Complete Event) */
+#define HCI_VERSION_1_0B                0x00
+#define HCI_VERSION_1_1                 0x01
+
+/* Define an invalid value for a handle */
+#define HCI_INVALID_HANDLE              0xFFFF
+
+/* Define max ammount of data in the HCI command */
+#define HCI_COMMAND_SIZE        255
+
+/* Define the preamble length for all HCI Commands.
+** This is 2-bytes for opcode and 1 byte for length
+*/
+#define HCIC_PREAMBLE_SIZE      3
+
+/* Define the preamble length for all HCI Events
+** This is 1-byte for opcode and 1 byte for length
+*/
+#define HCIE_PREAMBLE_SIZE      2
+#define HCI_SCO_PREAMBLE_SIZE   3
+#define HCI_DATA_PREAMBLE_SIZE  4
+
+/* local Bluetooth controller id for AMP HCI */
+#define LOCAL_BR_EDR_CONTROLLER_ID      0
+
+/* controller id types for AMP HCI */
+#define HCI_CONTROLLER_TYPE_BR_EDR      0
+#define HCI_CONTROLLER_TYPE_802_11      1
+#define HCI_CONTROLLER_TYPE_ECMA        2
+#define HCI_MAX_CONTROLLER_TYPES        3
+
+
+
+
+/* AMP Controller Status codes
+*/
+#define HCI_AMP_CTRLR_PHYSICALLY_DOWN   0
+#define HCI_AMP_CTRLR_USABLE_BY_BT      1
+#define HCI_AMP_CTRLR_UNUSABLE_FOR_BT   2
+#define HCI_AMP_CTRLR_LOW_CAP_FOR_BT    3
+#define HCI_AMP_CTRLR_MED_CAP_FOR_BT    4
+#define HCI_AMP_CTRLR_HIGH_CAP_FOR_BT   5
+#define HCI_AMP_CTRLR_FULL_CAP_FOR_BT   6
+
+#define HCI_MAX_AMP_STATUS_TYPES        7
+
+
+/* Define the extended flow specification fields used by AMP */
+typedef struct
+{
+    UINT8       id;
+    UINT8       stype;
+    UINT16      max_sdu_size;
+    UINT32      sdu_inter_time;
+    UINT32      access_latency;
+    UINT32      flush_timeout;
+} tHCI_EXT_FLOW_SPEC;
+
+
+/* HCI message type definitions (for H4 messages) */
+#define HCIT_TYPE_ACL_DATA  2
+#define HCIT_TYPE_SCO_DATA  3
+#define HCIT_TYPE_LM_DIAG   7
+
+#define HCIT_LM_DIAG_LENGTH 63
+
+/* Define values for LMP Test Control parameters
+** Test Scenario, Hopping Mode, Power Control Mode
+*/
+#define LMP_TESTCTL_TESTSC_PAUSE        0
+#define LMP_TESTCTL_TESTSC_TXTEST_0     1
+#define LMP_TESTCTL_TESTSC_TXTEST_1     2
+#define LMP_TESTCTL_TESTSC_TXTEST_1010  3
+#define LMP_TESTCTL_TESTSC_PSRND_BITSEQ 4
+#define LMP_TESTCTL_TESTSC_CLOSEDLB_ACL 5
+#define LMP_TESTCTL_TESTSC_CLOSEDLB_SCO 6
+#define LMP_TESTCTL_TESTSC_ACL_NOWHIT   7
+#define LMP_TESTCTL_TESTSC_SCO_NOWHIT   8
+#define LMP_TESTCTL_TESTSC_TXTEST_11110000  9
+#define LMP_TESTCTL_TESTSC_EXITTESTMODE 255
+
+#define LMP_TESTCTL_HOPMOD_RXTX1FREQ    0
+#define LMP_TESTCTL_HOPMOD_HOP_EURUSA   1
+#define LMP_TESTCTL_HOPMOD_HOP_JAPAN    2
+#define LMP_TESTCTL_HOPMOD_HOP_FRANCE   3
+#define LMP_TESTCTL_HOPMOD_HOP_SPAIN    4
+#define LMP_TESTCTL_HOPMOD_REDUCED_HOP  5
+
+#define LMP_TESTCTL_POWCTL_FIXEDTX_OP   0
+#define LMP_TESTCTL_POWCTL_ADAPTIVE     1
+
+
+/*
+** Define company IDs (from Bluetooth Assigned Numbers v1.1, section 2.2)
+*/
+#define LMP_COMPID_ERICSSON             0
+#define LMP_COMPID_NOKIA                1
+#define LMP_COMPID_INTEL                2
+#define LMP_COMPID_IBM                  3
+#define LMP_COMPID_TOSHIBA              4
+#define LMP_COMPID_3COM                 5
+#define LMP_COMPID_MICROSOFT            6
+#define LMP_COMPID_LUCENT               7
+#define LMP_COMPID_MOTOROLA             8
+#define LMP_COMPID_INFINEON             9
+#define LMP_COMPID_CSR                  10
+#define LMP_COMPID_SILICON_WAVE         11
+#define LMP_COMPID_DIGIANSWER           12
+#define LMP_COMPID_TEXAS_INSTRUMENTS    13
+#define LMP_COMPID_PARTHUS              14
+#define LMP_COMPID_BROADCOM             15
+#define LMP_COMPID_MITEL_SEMI           16
+#define LMP_COMPID_WIDCOMM              17
+#define LMP_COMPID_ZEEVO                18
+#define LMP_COMPID_ATMEL                19
+#define LMP_COMPID_MITSUBISHI           20
+#define LMP_COMPID_RTX_TELECOM          21
+#define LMP_COMPID_KC_TECH              22
+#define LMP_COMPID_NEWLOGIC             23
+#define LMP_COMPID_TRANSILICA           24
+#define LMP_COMPID_ROHDE_SCHWARZ        25
+#define LMP_COMPID_TTPCOM               26
+#define LMP_COMPID_SIGNIA               27
+#define LMP_COMPID_CONEXANT             28
+#define LMP_COMPID_QUALCOMM             29
+#define LMP_COMPID_INVENTEL             30
+#define LMP_COMPID_AVM                  31
+#define LMP_COMPID_BANDSPEED            32
+#define LMP_COMPID_MANSELLA             33
+#define LMP_COMPID_NEC_CORP             34
+#define LMP_COMPID_WAVEPLUS             35
+#define LMP_COMPID_ALCATEL              36
+#define LMP_COMPID_PHILIPS              37
+#define LMP_COMPID_C_TECHNOLOGIES       38
+#define LMP_COMPID_OPEN_INTERFACE       39
+#define LMP_COMPID_RF_MICRO             40
+#define LMP_COMPID_HITACHI              41
+#define LMP_COMPID_SYMBOL_TECH          42
+#define LMP_COMPID_TENOVIS              43
+#define LMP_COMPID_MACRONIX             44
+#define LMP_COMPID_GCT_SEMI             45
+#define LMP_COMPID_NORWOOD_SYSTEMS      46
+#define LMP_COMPID_MEWTEL_TECH          47
+#define LMP_COMPID_STM                  48
+#define LMP_COMPID_SYNOPSYS             49
+#define LMP_COMPID_RED_M_LTD            50
+#define LMP_COMPID_COMMIL_LTD           51
+#define LMP_COMPID_CATC                 52
+#define LMP_COMPID_ECLIPSE              53
+#define LMP_COMPID_RENESAS_TECH         54
+#define LMP_COMPID_MOBILIAN_CORP        55
+#define LMP_COMPID_TERAX                56
+#define LMP_COMPID_ISSC                 57
+#define LMP_COMPID_MATSUSHITA           58
+#define LMP_COMPID_GENNUM_CORP          59
+#define LMP_COMPID_RESEARCH_IN_MOTION   60
+#define LMP_COMPID_IPEXTREME            61
+#define LMP_COMPID_SYSTEMS_AND_CHIPS    62
+#define LMP_COMPID_BLUETOOTH_SIG        63
+#define LMP_COMPID_SEIKO_EPSON_CORP     64
+#define LMP_COMPID_ISS_TAIWAN           65
+#define LMP_COMPID_CONWISE_TECHNOLOGIES 66
+#define LMP_COMPID_PARROT_SA            67
+#define LMP_COMPID_SOCKET_COMM          68
+#define LMP_COMPID_ALTHEROS             69
+#define LMP_COMPID_MEDIATEK             70
+#define LMP_COMPID_BLUEGIGA             71
+#define LMP_COMPID_MARVELL              72
+#define LMP_COMPID_3DSP_CORP            73
+#define LMP_COMPID_ACCEL_SEMICONDUCTOR  74
+#define LMP_COMPID_CONTINENTAL_AUTO     75
+#define LMP_COMPID_APPLE                76
+#define LMP_COMPID_STACCATO             77
+#define LMP_COMPID_AVAGO_TECHNOLOGIES   78
+#define LMP_COMPID_APT_LTD              79
+#define LMP_COMPID_SIRF_TECHNOLOGY      80
+#define LMP_COMPID_TZERO_TECHNOLOGY     81
+#define LMP_COMPID_J_AND_M_CORP         82
+#define LMP_COMPID_FREE_2_MOVE          83
+#define LMP_COMPID_3DIJOY_CORP          84
+#define LMP_COMPID_PLANTRONICS          85
+#define LMP_COMPID_SONY_ERICSSON_MOBILE 86
+#define LMP_COMPID_HARMON_INTL_IND      87
+#define LMP_COMPID_VIZIO                88
+#define LMP_COMPID_NORDIC SEMI          89
+#define LMP_COMPID_EM MICRO             90
+#define LMP_COMPID_RALINK TECH          91
+#define LMP_COMPID_BELKIN INC           92
+#define LMP_COMPID_REALTEK SEMI         93
+#define LMP_COMPID_STONESTREET ONE      94
+#define LMP_COMPID_WICENTRIC            95
+#define LMP_COMPID_RIVIERAWAVES         96
+#define LMP_COMPID_RDA MICRO            97
+#define LMP_COMPID_GIBSON GUITARS       98
+#define LMP_COMPID_MICOMMAND INC        99
+#define LMP_COMPID_BAND XI              100
+#define LMP_COMPID_HP COMPANY           101
+#define LMP_COMPID_9SOLUTIONS OY        102
+#define LMP_COMPID_GN NETCOM            103
+#define LMP_COMPID_GENERAL MOTORS       104
+#define LMP_COMPID_AD ENGINEERING       105
+#define LMP_COMPID_MINDTREE LTD         106
+#define LMP_COMPID_POLAR ELECTRO        107
+#define LMP_COMPID_BEAUTIFUL ENTERPRISE 108
+#define LMP_COMPID_BRIARTEK             109
+#define LMP_COMPID_SUMMIT DATA COMM     110
+#define LMP_COMPID_SOUND ID             111
+#define LMP_COMPID_MONSTER LLC          112
+#define LMP_COMPID_CONNECTBLU           113
+#define LMP_COMPID_MAX_ID               114 /* this is a place holder */
+#define LMP_COMPID_INTERNAL             65535
+
+#define MAX_LMP_COMPID                  (LMP_COMPID_MAX_ID)
+/*
+** Define the packet types in the packet header, and a couple extra
+*/
+#define PKT_TYPE_NULL   0x00
+#define PKT_TYPE_POLL   0x01
+#define PKT_TYPE_FHS    0x02
+#define PKT_TYPE_DM1    0x03
+
+#define PKT_TYPE_DH1    0x04
+#define PKT_TYPE_HV1    0x05
+#define PKT_TYPE_HV2    0x06
+#define PKT_TYPE_HV3    0x07
+#define PKT_TYPE_DV     0x08
+#define PKT_TYPE_AUX1   0x09
+
+#define PKT_TYPE_DM3    0x0a
+#define PKT_TYPE_DH3    0x0b
+
+#define PKT_TYPE_DM5    0x0e
+#define PKT_TYPE_DH5    0x0f
+
+
+#define PKT_TYPE_ID     0x10        /* Internally used packet types */
+#define PKT_TYPE_BAD    0x11
+#define PKT_TYPE_NONE   0x12
+
+/*
+** Define packet size
+*/
+#define HCI_DM1_PACKET_SIZE         17
+#define HCI_DH1_PACKET_SIZE         27
+#define HCI_DM3_PACKET_SIZE         121
+#define HCI_DH3_PACKET_SIZE         183
+#define HCI_DM5_PACKET_SIZE         224
+#define HCI_DH5_PACKET_SIZE         339
+#define HCI_AUX1_PACKET_SIZE        29
+#define HCI_HV1_PACKET_SIZE         10
+#define HCI_HV2_PACKET_SIZE         20
+#define HCI_HV3_PACKET_SIZE         30
+#define HCI_DV_PACKET_SIZE          9
+#define HCI_EDR2_DH1_PACKET_SIZE    54
+#define HCI_EDR2_DH3_PACKET_SIZE    367
+#define HCI_EDR2_DH5_PACKET_SIZE    679
+#define HCI_EDR3_DH1_PACKET_SIZE    83
+#define HCI_EDR3_DH3_PACKET_SIZE    552
+#define HCI_EDR3_DH5_PACKET_SIZE    1021
+
+/*
+**   Features encoding - page 0
+*/
+#define HCI_NUM_FEATURE_BYTES           8
+#define HCI_FEATURES_KNOWN(x) ((x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | x[6] | x[7]) != 0)
+
+#define HCI_FEATURE_3_SLOT_PACKETS_MASK 0x01
+#define HCI_FEATURE_3_SLOT_PACKETS_OFF  0
+#define HCI_3_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_PACKETS_OFF] & HCI_FEATURE_3_SLOT_PACKETS_MASK)
+
+#define HCI_FEATURE_5_SLOT_PACKETS_MASK 0x02
+#define HCI_FEATURE_5_SLOT_PACKETS_OFF  0
+#define HCI_5_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_PACKETS_OFF] & HCI_FEATURE_5_SLOT_PACKETS_MASK)
+
+#define HCI_FEATURE_ENCRYPTION_MASK     0x04
+#define HCI_FEATURE_ENCRYPTION_OFF      0
+#define HCI_ENCRYPTION_SUPPORTED(x)     ((x)[HCI_FEATURE_ENCRYPTION_OFF] & HCI_FEATURE_ENCRYPTION_MASK)
+
+#define HCI_FEATURE_SLOT_OFFSET_MASK    0x08
+#define HCI_FEATURE_SLOT_OFFSET_OFF     0
+#define HCI_SLOT_OFFSET_SUPPORTED(x)    ((x)[HCI_FEATURE_SLOT_OFFSET_OFF] & HCI_FEATURE_SLOT_OFFSET_MASK)
+
+#define HCI_FEATURE_TIMING_ACC_MASK     0x10
+#define HCI_FEATURE_TIMING_ACC_OFF      0
+#define HCI_TIMING_ACC_SUPPORTED(x)     ((x)[HCI_FEATURE_TIMING_ACC_OFF] & HCI_FEATURE_TIMING_ACC_MASK)
+
+#define HCI_FEATURE_SWITCH_MASK         0x20
+#define HCI_FEATURE_SWITCH_OFF          0
+#define HCI_SWITCH_SUPPORTED(x)         ((x)[HCI_FEATURE_SWITCH_OFF] & HCI_FEATURE_SWITCH_MASK)
+
+#define HCI_FEATURE_HOLD_MODE_MASK      0x40
+#define HCI_FEATURE_HOLD_MODE_OFF       0
+#define HCI_HOLD_MODE_SUPPORTED(x)      ((x)[HCI_FEATURE_HOLD_MODE_OFF] & HCI_FEATURE_HOLD_MODE_MASK)
+
+#define HCI_FEATURE_SNIFF_MODE_MASK     0x80
+#define HCI_FEATURE_SNIFF_MODE_OFF      0
+#define HCI_SNIFF_MODE_SUPPORTED(x)      ((x)[HCI_FEATURE_SNIFF_MODE_OFF] & HCI_FEATURE_SNIFF_MODE_MASK)
+
+#define HCI_FEATURE_PARK_MODE_MASK      0x01
+#define HCI_FEATURE_PARK_MODE_OFF       1
+#define HCI_PARK_MODE_SUPPORTED(x)      ((x)[HCI_FEATURE_PARK_MODE_OFF] & HCI_FEATURE_PARK_MODE_MASK)
+
+#define HCI_FEATURE_RSSI_MASK           0x02
+#define HCI_FEATURE_RSSI_OFF            1
+#define HCI_RSSI_SUPPORTED(x)           ((x)[HCI_FEATURE_RSSI_OFF] & HCI_FEATURE_RSSI_MASK)
+
+#define HCI_FEATURE_CQM_DATA_RATE_MASK  0x04
+#define HCI_FEATURE_CQM_DATA_RATE_OFF   1
+#define HCI_CQM_DATA_RATE_SUPPORTED(x)  ((x)[HCI_FEATURE_CQM_DATA_RATE_OFF] & HCI_FEATURE_CQM_DATA_RATE_MASK)
+
+#define HCI_FEATURE_SCO_LINK_MASK       0x08
+#define HCI_FEATURE_SCO_LINK_OFF        1
+#define HCI_SCO_LINK_SUPPORTED(x)       ((x)[HCI_FEATURE_SCO_LINK_OFF] & HCI_FEATURE_SCO_LINK_MASK)
+
+#define HCI_FEATURE_HV2_PACKETS_MASK    0x10
+#define HCI_FEATURE_HV2_PACKETS_OFF     1
+#define HCI_HV2_PACKETS_SUPPORTED(x)    ((x)[HCI_FEATURE_HV2_PACKETS_OFF] & HCI_FEATURE_HV2_PACKETS_MASK)
+
+#define HCI_FEATURE_HV3_PACKETS_MASK    0x20
+#define HCI_FEATURE_HV3_PACKETS_OFF     1
+#define HCI_HV3_PACKETS_SUPPORTED(x)    ((x)[HCI_FEATURE_HV3_PACKETS_OFF] & HCI_FEATURE_HV3_PACKETS_MASK)
+
+#define HCI_FEATURE_U_LAW_MASK          0x40
+#define HCI_FEATURE_U_LAW_OFF           1
+#define HCI_LMP_U_LAW_SUPPORTED(x)      ((x)[HCI_FEATURE_U_LAW_OFF] & HCI_FEATURE_U_LAW_MASK)
+
+#define HCI_FEATURE_A_LAW_MASK          0x80
+#define HCI_FEATURE_A_LAW_OFF           1
+#define HCI_LMP_A_LAW_SUPPORTED(x)      ((x)[HCI_FEATURE_A_LAW_OFF] & HCI_FEATURE_A_LAW_MASK)
+
+#define HCI_FEATURE_CVSD_MASK           0x01
+#define HCI_FEATURE_CVSD_OFF            2
+#define HCI_LMP_CVSD_SUPPORTED(x)       ((x)[HCI_FEATURE_CVSD_OFF] & HCI_FEATURE_CVSD_MASK)
+
+#define HCI_FEATURE_PAGING_SCHEME_MASK  0x02
+#define HCI_FEATURE_PAGING_SCHEME_OFF   2
+#define HCI_PAGING_SCHEME_SUPPORTED(x) ((x)[HCI_FEATURE_PAGING_SCHEME_OFF] & HCI_FEATURE_PAGING_SCHEME_MASK)
+
+#define HCI_FEATURE_POWER_CTRL_MASK     0x04
+#define HCI_FEATURE_POWER_CTRL_OFF      2
+#define HCI_POWER_CTRL_SUPPORTED(x)     ((x)[HCI_FEATURE_POWER_CTRL_OFF] & HCI_FEATURE_POWER_CTRL_MASK)
+
+#define HCI_FEATURE_TRANSPNT_MASK       0x08
+#define HCI_FEATURE_TRANSPNT_OFF        2
+#define HCI_LMP_TRANSPNT_SUPPORTED(x)   ((x)[HCI_FEATURE_TRANSPNT_OFF] & HCI_FEATURE_TRANSPNT_MASK)
+
+#define HCI_FEATURE_FLOW_CTRL_LAG_MASK  0x70
+#define HCI_FEATURE_FLOW_CTRL_LAG_OFF   2
+#define HCI_FLOW_CTRL_LAG_VALUE(x)      (((x)[HCI_FEATURE_FLOW_CTRL_LAG_OFF] & HCI_FEATURE_FLOW_CTRL_LAG_MASK) >> 4)
+
+#define HCI_FEATURE_BROADCAST_ENC_MASK  0x80
+#define HCI_FEATURE_BROADCAST_ENC_OFF   2
+#define HCI_LMP_BCAST_ENC_SUPPORTED(x)  ((x)[HCI_FEATURE_BROADCAST_ENC_OFF] & HCI_FEATURE_BROADCAST_ENC_MASK)
+
+#define HCI_FEATURE_SCATTER_MODE_MASK   0x01
+#define HCI_FEATURE_SCATTER_MODE_OFF    3
+#define HCI_LMP_SCATTER_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_SCATTER_MODE_OFF] & HCI_FEATURE_SCATTER_MODE_MASK)
+
+#define HCI_FEATURE_EDR_ACL_2MPS_MASK   0x02
+#define HCI_FEATURE_EDR_ACL_2MPS_OFF    3
+#define HCI_EDR_ACL_2MPS_SUPPORTED(x)   ((x)[HCI_FEATURE_EDR_ACL_2MPS_OFF] & HCI_FEATURE_EDR_ACL_2MPS_MASK)
+
+#define HCI_FEATURE_EDR_ACL_3MPS_MASK   0x04
+#define HCI_FEATURE_EDR_ACL_3MPS_OFF    3
+#define HCI_EDR_ACL_3MPS_SUPPORTED(x)   ((x)[HCI_FEATURE_EDR_ACL_3MPS_OFF] & HCI_FEATURE_EDR_ACL_3MPS_MASK)
+
+#define HCI_FEATURE_ENHANCED_INQ_MASK   0x08
+#define HCI_FEATURE_ENHANCED_INQ_OFF    3
+#define HCI_ENHANCED_INQ_SUPPORTED(x)   ((x)[HCI_FEATURE_ENHANCED_INQ_OFF] & HCI_FEATURE_ENHANCED_INQ_MASK)
+
+#define HCI_FEATURE_INTERLACED_INQ_SCAN_MASK   0x10
+#define HCI_FEATURE_INTERLACED_INQ_SCAN_OFF    3
+#define HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_INQ_SCAN_OFF] & HCI_FEATURE_INTERLACED_INQ_SCAN_MASK)
+
+#define HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK  0x20
+#define HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF   3
+#define HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF] & HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK)
+
+#define HCI_FEATURE_INQ_RSSI_MASK       0x40
+#define HCI_FEATURE_INQ_RSSI_OFF        3
+#define HCI_LMP_INQ_RSSI_SUPPORTED(x)   ((x)[HCI_FEATURE_INQ_RSSI_OFF] & HCI_FEATURE_INQ_RSSI_MASK)
+
+#define HCI_FEATURE_ESCO_EV3_MASK       0x80
+#define HCI_FEATURE_ESCO_EV3_OFF        3
+#define HCI_ESCO_EV3_SUPPORTED(x)       ((x)[HCI_FEATURE_ESCO_EV3_OFF] & HCI_FEATURE_ESCO_EV3_MASK)
+
+#define HCI_FEATURE_ESCO_EV4_MASK       0x01
+#define HCI_FEATURE_ESCO_EV4_OFF        4
+#define HCI_ESCO_EV4_SUPPORTED(x)       ((x)[HCI_FEATURE_ESCO_EV4_OFF] & HCI_FEATURE_ESCO_EV4_MASK)
+
+#define HCI_FEATURE_ESCO_EV5_MASK       0x02
+#define HCI_FEATURE_ESCO_EV5_OFF        4
+#define HCI_ESCO_EV5_SUPPORTED(x)       ((x)[HCI_FEATURE_ESCO_EV5_OFF] & HCI_FEATURE_ESCO_EV5_MASK)
+
+#define HCI_FEATURE_ABSENCE_MASKS_MASK  0x04
+#define HCI_FEATURE_ABSENCE_MASKS_OFF   4
+#define HCI_LMP_ABSENCE_MASKS_SUPPORTED(x) ((x)[HCI_FEATURE_ABSENCE_MASKS_OFF] & HCI_FEATURE_ABSENCE_MASKS_MASK)
+
+#define HCI_FEATURE_AFH_CAP_SLAVE_MASK  0x08
+#define HCI_FEATURE_AFH_CAP_SLAVE_OFF   4
+#define HCI_LMP_AFH_CAP_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_SLAVE_OFF] & HCI_FEATURE_AFH_CAP_SLAVE_MASK)
+
+#define HCI_FEATURE_AFH_CLASS_SLAVE_MASK 0x10
+#define HCI_FEATURE_AFH_CLASS_SLAVE_OFF  4
+#define HCI_LMP_AFH_CLASS_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_SLAVE_OFF] & HCI_FEATURE_AFH_CLASS_SLAVE_MASK)
+
+#define HCI_FEATURE_ALIAS_AUTH_MASK     0x20
+#define HCI_FEATURE_ALIAS_AUTH_OFF      4
+#define HCI_LMP_ALIAS_AUTH_SUPPORTED(x) ((x)[HCI_FEATURE_ALIAS_AUTH_OFF] & HCI_FEATURE_ALIAS_AUTH_MASK)
+
+#define HCI_FEATURE_ANON_MODE_MASK      0x40
+#define HCI_FEATURE_ANON_MODE_OFF       4
+#define HCI_LMP_ANON_MODE_SUPPORTED(x)  ((x)[HCI_FEATURE_ANON_MODE_OFF] & HCI_FEATURE_ANON_MODE_MASK)
+
+#define HCI_FEATURE_3_SLOT_EDR_ACL_MASK 0x80
+#define HCI_FEATURE_3_SLOT_EDR_ACL_OFF  4
+#define HCI_3_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ACL_OFF] & HCI_FEATURE_3_SLOT_EDR_ACL_MASK)
+
+#define HCI_FEATURE_5_SLOT_EDR_ACL_MASK 0x01
+#define HCI_FEATURE_5_SLOT_EDR_ACL_OFF  5
+#define HCI_5_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_EDR_ACL_OFF] & HCI_FEATURE_5_SLOT_EDR_ACL_MASK)
+
+#define HCI_FEATURE_SNIFF_SUB_RATE_MASK 0x02
+#define HCI_FEATURE_SNIFF_SUB_RATE_OFF  5
+#define HCI_SNIFF_SUB_RATE_SUPPORTED(x) ((x)[HCI_FEATURE_SNIFF_SUB_RATE_OFF] & HCI_FEATURE_SNIFF_SUB_RATE_MASK)
+
+#define HCI_FEATURE_ATOMIC_ENCRYPT_MASK 0x04
+#define HCI_FEATURE_ATOMIC_ENCRYPT_OFF  5
+#define HCI_ATOMIC_ENCRYPT_SUPPORTED(x) ((x)[HCI_FEATURE_ATOMIC_ENCRYPT_OFF] & HCI_FEATURE_ATOMIC_ENCRYPT_MASK)
+
+#define HCI_FEATURE_AFH_CAP_MASTR_MASK  0x08
+#define HCI_FEATURE_AFH_CAP_MASTR_OFF   5
+#define HCI_LMP_AFH_CAP_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_MASTR_OFF] & HCI_FEATURE_AFH_CAP_MASTR_MASK)
+
+#define HCI_FEATURE_AFH_CLASS_MASTR_MASK 0x10
+#define HCI_FEATURE_AFH_CLASS_MASTR_OFF  5
+#define HCI_LMP_AFH_CLASS_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_MASTR_OFF] & HCI_FEATURE_AFH_CLASS_MASTR_MASK)
+
+#define HCI_FEATURE_EDR_ESCO_2MPS_MASK  0x20
+#define HCI_FEATURE_EDR_ESCO_2MPS_OFF   5
+#define HCI_EDR_ESCO_2MPS_SUPPORTED(x)  ((x)[HCI_FEATURE_EDR_ESCO_2MPS_OFF] & HCI_FEATURE_EDR_ESCO_2MPS_MASK)
+
+#define HCI_FEATURE_EDR_ESCO_3MPS_MASK  0x40
+#define HCI_FEATURE_EDR_ESCO_3MPS_OFF   5
+#define HCI_EDR_ESCO_3MPS_SUPPORTED(x)  ((x)[HCI_FEATURE_EDR_ESCO_3MPS_OFF] & HCI_FEATURE_EDR_ESCO_3MPS_MASK)
+
+#define HCI_FEATURE_3_SLOT_EDR_ESCO_MASK 0x80
+#define HCI_FEATURE_3_SLOT_EDR_ESCO_OFF  5
+#define HCI_3_SLOT_EDR_ESCO_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ESCO_OFF] & HCI_FEATURE_3_SLOT_EDR_ESCO_MASK)
+
+#define HCI_FEATURE_EXT_INQ_RSP_MASK    0x01
+#define HCI_FEATURE_EXT_INQ_RSP_OFF     6
+#define HCI_EXT_INQ_RSP_SUPPORTED(x)    ((x)[HCI_FEATURE_EXT_INQ_RSP_OFF] & HCI_FEATURE_EXT_INQ_RSP_MASK)
+
+#define HCI_FEATURE_ANUM_PIN_AWARE_MASK 0x02
+#define HCI_FEATURE_ANUM_PIN_AWARE_OFF  6
+#define HCI_ANUM_PIN_AWARE_SUPPORTED(x) ((x)[HCI_FEATURE_ANUM_PIN_AWARE_OFF] & HCI_FEATURE_ANUM_PIN_AWARE_MASK)
+
+#define HCI_FEATURE_ANUM_PIN_CAP_MASK   0x04
+#define HCI_FEATURE_ANUM_PIN_CAP_OFF    6
+#define HCI_ANUM_PIN_CAP_SUPPORTED(x)   ((x)[HCI_FEATURE_ANUM_PIN_CAP_OFF] & HCI_FEATURE_ANUM_PIN_CAP_MASK)
+
+#define HCI_FEATURE_SIMPLE_PAIRING_MASK 0x08
+#define HCI_FEATURE_SIMPLE_PAIRING_OFF  6
+#define HCI_SIMPLE_PAIRING_SUPPORTED(x) ((x)[HCI_FEATURE_SIMPLE_PAIRING_OFF] & HCI_FEATURE_SIMPLE_PAIRING_MASK)
+
+#define HCI_FEATURE_ENCAP_PDU_MASK      0x10
+#define HCI_FEATURE_ENCAP_PDU_OFF       6
+#define HCI_ENCAP_PDU_SUPPORTED(x)      ((x)[HCI_FEATURE_ENCAP_PDU_OFF] & HCI_FEATURE_ENCAP_PDU_MASK)
+
+#define HCI_FEATURE_ERROR_DATA_MASK     0x20
+#define HCI_FEATURE_ERROR_DATA_OFF      6
+#define HCI_ERROR_DATA_SUPPORTED(x)     ((x)[HCI_FEATURE_ERROR_DATA_OFF] & HCI_FEATURE_ERROR_DATA_MASK)
+
+#define HCI_FEATURE_NON_FLUSHABLE_PB_MASK      0x40
+#define HCI_FEATURE_NON_FLUSHABLE_PB_OFF       6
+#define HCI_NON_FLUSHABLE_PB_SUPPORTED(x)      ((x)[HCI_FEATURE_NON_FLUSHABLE_PB_OFF] & HCI_FEATURE_NON_FLUSHABLE_PB_MASK)
+
+#define HCI_FEATURE_LINK_SUP_TO_EVT_MASK 0x01
+#define HCI_FEATURE_LINK_SUP_TO_EVT_OFF  7
+#define HCI_LINK_SUP_TO_EVT_SUPPORTED(x) ((x)[HCI_FEATURE_LINK_SUP_TO_EVT_OFF] & HCI_FEATURE_LINK_SUP_TO_EVT_MASK)
+
+#define HCI_FEATURE_INQ_RESP_TX_MASK     0x02
+#define HCI_FEATURE_INQ_RESP_TX_OFF      7
+#define HCI_INQ_RESP_TX_SUPPORTED(x)     ((x)[HCI_FEATURE_INQ_RESP_TX_OFF] & HCI_FEATURE_INQ_RESP_TX_MASK)
+
+#define HCI_FEATURE_EXTENDED_MASK       0x80
+#define HCI_FEATURE_EXTENDED_OFF        7
+#define HCI_LMP_EXTENDED_SUPPORTED(x)   ((x)[HCI_FEATURE_EXTENDED_OFF] & HCI_FEATURE_EXTENDED_MASK)
+
+/*
+**   Features encoding - page 1
+*/
+#define HCI_EXT_FEATURE_SSP_HOST_MASK 0x01
+#define HCI_EXT_FEATURE_SSP_HOST_OFF  0
+#define HCI_SSP_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SSP_HOST_OFF] & HCI_EXT_FEATURE_SSP_HOST_MASK)
+
+/*
+**   Local Supported Commands encoding
+*/
+#define HCI_NUM_SUPP_COMMANDS_BYTES           64
+
+#define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01
+#define HCI_SUPP_COMMANDS_INQUIRY_OFF  0
+#define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK 0x02
+#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF  0
+#define HCI_INQUIRY_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF] & HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK     0x04
+#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF      0
+#define HCI_PERIODIC_INQUIRY_SUPPORTED(x)     ((x)[HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK    0x08
+#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF     0
+#define HCI_EXIT_PERIODIC_INQUIRY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_CONN_MASK     0x10
+#define HCI_SUPP_COMMANDS_CREATE_CONN_OFF      0
+#define HCI_CREATE_CONN_SUPPORTED(x)     ((x)[HCI_SUPP_COMMANDS_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CREATE_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_MASK         0x20
+#define HCI_SUPP_COMMANDS_DISCONNECT_OFF          0
+#define HCI_DISCONNECT_SUPPORTED(x)         ((x)[HCI_SUPP_COMMANDS_DISCONNECT_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_MASK)
+
+#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK      0x40
+#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF       0
+#define HCI_ADD_SCO_CONN_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF] & HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK     0x80
+#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF      0
+#define HCI_CANCEL_CREATE_CONN_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK      0x01
+#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF       1
+#define HCI_ACCEPT_CONN_REQUEST_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK           0x02
+#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF            1
+#define HCI_REJECT_CONN_REQUEST_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK  0x04
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF   1
+#define HCI_LINK_KEY_REQUEST_REPLY_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK       0x08
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF        1
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK    0x10
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF     1
+#define HCI_PIN_CODE_REQUEST_REPLY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK    0x20
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF     1
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK          0x40
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF           1
+#define HCI_CHANGE_CONN_PKT_TYPE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK          0x80
+#define HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF           1
+#define HCI_AUTH_REQUEST_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF] & HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK      0x01
+#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF       2
+#define HCI_SET_CONN_ENCRYPTION_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF] & HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK)
+
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK           0x02
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF            2
+#define HCI_CHANGE_CONN_LINK_KEY_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK  0x04
+#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF   2
+#define HCI_MASTER_LINK_KEY_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK       0x08
+#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF        2
+#define HCI_REMOTE_NAME_REQUEST_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK    0x10
+#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF     2
+#define HCI_CANCEL_REMOTE_NAME_REQUEST_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF     2
+#define HCI_READ_REMOTE_SUPP_FEATURES_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF           2
+#define HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF           2
+#define HCI_READ_REMOTE_VER_INFO_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK           0x01
+#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF            3
+#define HCI_READ_CLOCK_OFFSET_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF] & HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK  0x02
+#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF   3
+#define HCI_READ_LMP_HANDLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF] & HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK)
+
+#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK           0x02
+#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF            4
+#define HCI_HOLD_MODE_CMD_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK)
+
+#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK  0x04
+#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF   4
+#define HCI_SNIFF_MODE_CMD_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK       0x08
+#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF        4
+#define HCI_EXIT_SNIFF_MODE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF] & HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_PARK_STATE_MASK    0x10
+#define HCI_SUPP_COMMANDS_PARK_STATE_OFF     4
+#define HCI_PARK_STATE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_PARK_STATE_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK    0x20
+#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF     4
+#define HCI_EXIT_PARK_STATE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK)
+
+#define HCI_SUPP_COMMANDS_QOS_SETUP_MASK          0x40
+#define HCI_SUPP_COMMANDS_QOS_SETUP_OFF           4
+#define HCI_QOS_SETUP_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_QOS_SETUP_OFF] & HCI_SUPP_COMMANDS_QOS_SETUP_MASK)
+
+#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK          0x80
+#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF           4
+#define HCI_ROLE_DISCOVERY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF] & HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK)
+
+#define HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK      0x01
+#define HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF       5
+#define HCI_SWITCH_ROLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF] & HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK           0x02
+#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF            5
+#define HCI_READ_LINK_POLICY_SET_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK  0x04
+#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF   5
+#define HCI_WRITE_LINK_POLICY_SET_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF        5
+#define HCI_READ_DEF_LINK_POLICY_SET_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK    0x10
+#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF     5
+#define HCI_WRITE_DEF_LINK_POLICY_SET_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK    0x20
+#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF     5
+#define HCI_FLOW_SPECIFICATION_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF] & HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK          0x40
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF           5
+#define HCI_SET_EVENT_MASK_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK)
+
+#define HCI_SUPP_COMMANDS_RESET_MASK          0x80
+#define HCI_SUPP_COMMANDS_RESET_OFF           5
+#define HCI_RESET_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_RESET_OFF] & HCI_SUPP_COMMANDS_RESET_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK      0x01
+#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF       6
+#define HCI_SET_EVENT_FILTER_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK)
+
+#define HCI_SUPP_COMMANDS_FLUSH_MASK           0x02
+#define HCI_SUPP_COMMANDS_FLUSH_OFF            6
+#define HCI_FLUSH_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_FLUSH_OFF] & HCI_SUPP_COMMANDS_FLUSH_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF   6
+#define HCI_READ_PIN_TYPE_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF        6
+#define HCI_WRITE_PIN_TYPE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK    0x10
+#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF     6
+#define HCI_CREATE_NEW_UNIT_KEY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF] & HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF     6
+#define HCI_READ_STORED_LINK_KEY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK          0x40
+#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF           6
+#define HCI_WRITE_STORED_LINK_KEY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK          0x80
+#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF           6
+#define HCI_DELETE_STORED_LINK_KEY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK      0x01
+#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF       7
+#define HCI_WRITE_LOCAL_NAME_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK           0x02
+#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF            7
+#define HCI_READ_LOCAL_NAME_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF   7
+#define HCI_READ_CONN_ACCEPT_TOUT_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF        7
+#define HCI_WRITE_CONN_ACCEPT_TOUT_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF     7
+#define HCI_READ_PAGE_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF     7
+#define HCI_WRITE_PAGE_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF           7
+#define HCI_READ_SCAN_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF           7
+#define HCI_WRITE_SCAN_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF       8
+#define HCI_READ_PAGE_SCAN_ACTIVITY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF            8
+#define HCI_WRITE_PAGE_SCAN_ACTIVITY_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF   8
+#define HCI_READ_INQURIY_SCAN_ACTIVITY_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF        8
+#define HCI_WRITE_INQURIY_SCAN_ACTIVITY_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF     8
+#define HCI_READ_AUTH_ENABLE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF     8
+#define HCI_WRITE_AUTH_ENABLE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF           8
+#define HCI_READ_ENCRYPT_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF           8
+#define HCI_WRITE_ENCRYPT_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF       9
+#define HCI_READ_CLASS_DEVICE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF            9
+#define HCI_WRITE_CLASS_DEVICE_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF   9
+#define HCI_READ_VOICE_SETTING_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF        9
+#define HCI_WRITE_VOICE_SETTING_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF     9
+#define HCI_READ_AUTO_FLUSH_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF     9
+#define HCI_WRITE_AUTO_FLUSH_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF           9
+#define HCI_READ_NUM_BROAD_RETRANS_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF           9
+#define HCI_WRITE_NUM_BROAD_RETRANS_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF       10
+#define HCI_READ_HOLD_MODE_ACTIVITY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF            10
+#define HCI_WRITE_HOLD_MODE_ACTIVITY_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF   10
+#define HCI_READ_TRANS_PWR_LEVEL_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF        10
+#define HCI_READ_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK    0x10
+#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF     10
+#define HCI_WRITE_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK    0x20
+#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF     10
+#define HCI_SET_HOST_CTRLR_TO_HOST_FC_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF] & HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK)
+
+#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK          0x40
+#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF           10
+#define HCI_HOST_BUFFER_SIZE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK          0x80
+#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF           10
+#define HCI_HOST_NUM_COMPLETED_PKTS_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF] & HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF       11
+#define HCI_READ_LINK_SUP_TOUT_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF            11
+#define HCI_WRITE_LINK_SUP_TOUT_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF   11
+#define HCI_READ_NUM_SUPP_IAC_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF] & HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF        11
+#define HCI_READ_CURRENT_IAC_LAP_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK    0x10
+#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF     11
+#define HCI_WRITE_CURRENT_IAC_LAP_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF     11
+#define HCI_READ_PAGE_SCAN_PER_MODE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK          0x40
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF           11
+#define HCI_WRITE_PAGE_SCAN_PER_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF           11
+#define HCI_READ_PAGE_SCAN_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK      0x01
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF       12
+#define HCI_WRITE_PAGE_SCAN_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK           0x02
+#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF            12
+#define HCI_SET_AFH_CHNL_CLASS_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF] & HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF     12
+#define HCI_READ_INQUIRY_SCAN_TYPE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF     12
+#define HCI_WRITE_INQUIRY_SCAN_TYPE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF           12
+#define HCI_READ_INQUIRY_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF           12
+#define HCI_WRITE_INQUIRY_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF       13
+#define HCI_READ_PAGE_SCAN_TYPE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF            13
+#define HCI_WRITE_PAGE_SCAN_TYPE_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF   13
+#define HCI_READ_AFH_CHNL_ASSESS_MODE_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF        13
+#define HCI_WRITE_AFH_CHNL_ASSESS_MODE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF        14
+#define HCI_READ_LOCAL_VER_INFO_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK       0x10
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF        14
+#define HCI_READ_LOCAL_SUP_CMDS_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF     14
+#define HCI_READ_LOCAL_SUPP_FEATURES_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF           14
+#define HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF           14
+#define HCI_READ_BUFFER_SIZE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF       15
+#define HCI_READ_COUNTRY_CODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF] & HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK           0x02
+#define HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF            15
+#define HCI_READ_BD_ADDR_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF] & HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF   15
+#define HCI_READ_FAIL_CONTACT_CNTR_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK)
+
+#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK       0x08
+#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF        15
+#define HCI_RESET_FAIL_CONTACT_CNTR_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK)
+
+#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK    0x10
+#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF     15
+#define HCI_GET_LINK_QUALITY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF] & HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_RSSI_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_RSSI_OFF     15
+#define HCI_READ_RSSI_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_RSSI_OFF] & HCI_SUPP_COMMANDS_READ_RSSI_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF           15
+#define HCI_READ_AFH_CH_MAP_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF           15
+#define HCI_READ_BD_CLOCK_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF] & HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF       16
+#define HCI_READ_LOOPBACK_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF            16
+#define HCI_WRITE_LOOPBACK_MODE_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK  0x04
+#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF   16
+#define HCI_ENABLE_DEV_UNDER_TEST_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF] & HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK)
+
+#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK       0x08
+#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF        16
+#define HCI_SETUP_SYNCH_CONN_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK    0x10
+#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF     16
+#define HCI_ACCEPT_SYNCH_CONN_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK    0x20
+#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF     16
+#define HCI_REJECT_SYNCH_CONN_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF    17
+#define HCI_READ_EXT_INQUIRY_RESP_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK  0x02
+#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF   17
+#define HCI_WRITE_EXT_INQUIRY_RESP_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK)
+
+#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK   0x04
+#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF    17
+#define HCI_REFRESH_ENCRYPTION_KEY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF] & HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK)
+
+/* Octet 17, bit 3 is reserved */
+
+#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK       0x10
+#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF        17
+#define HCI_SNIFF_SUB_RATE_CMD_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF] & HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK   0x20
+#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF    17
+#define HCI_READ_SIMPLE_PAIRING_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK   0x40
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF    17
+#define HCI_WRITE_SIMPLE_PAIRING_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK   0x80
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF    17
+#define HCI_READ_LOCAL_OOB_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF    18
+#define HCI_READ_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK   0x02
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF    18
+#define HCI_WRITE_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK   0x04
+#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF    18
+#define HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK   0x08
+#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF    18
+#define HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
+
+#define HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_MASK   0x80
+#define HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_OFF    18
+#define HCI_IO_CAPABILITY_RESPONSE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_OFF] & HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK   0x01
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF    19
+#define HCI_USER_CONFIRMATION_REQUEST_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK   0x02
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF    19
+#define HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK   0x04
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF    19
+#define HCI_USER_PASSKEY_REQUEST_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK   0x08
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF    19
+#define HCI_USER_PASSKEY_REQUEST_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK   0x10
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF    19
+#define HCI_REMOTE_OOB_DATA_REQUEST_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK       0x20
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF        19
+#define HCI_WRITE_SIMPLE_PAIRING_DBG_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK   0x40
+#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF    19
+#define HCI_ENHANCED_FLUSH_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF] & HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK       0x80
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF        19
+#define HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK)
+
+/* Supported Commands (Byte 20) */
+#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK       0x04
+#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF        20
+#define HCI_SEND_NOTIF_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF] & HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK)
+
+#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK      0x08
+#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF       20
+#define HCI_IO_CAP_REQ_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK      0x10
+#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF       20
+#define HCI_READ_ENCR_KEY_SIZE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK)
+
+/* Supported Commands (Byte 21) */
+#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK   0x01
+#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF    21
+#define HCI_CREATE_PHYSICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK   0x02
+#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF    21
+#define HCI_ACCEPT_PHYSICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK   0x04
+#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF    21
+#define HCI_DISCONNECT_PHYSICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK   0x08
+#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF    21
+#define HCI_CREATE_LOGICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK   0x10
+#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF    21
+#define HCI_ACCEPT_LOGICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK   0x20
+#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF    21
+#define HCI_DISCONNECT_LOGICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK   0x40
+#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF    21
+#define HCI_LOGICAL_LINK_CANCEL_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF] & HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK       0x80
+#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF        21
+#define HCI_FLOW_SPEC_MODIFY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF] & HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK)
+
+/* Supported Commands (Byte 22) */
+#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF    22
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK   0x02
+#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF    22
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK   0x04
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF    22
+#define HCI_SET_EVENT_MASK_PAGE_2_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK   0x08
+#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF    22
+#define HCI_READ_LOCATION_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK   0x10
+#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF    22
+#define HCI_WRITE_LOCATION_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK   0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF    22
+#define HCI_READ_LOCAL_AMP_INFO_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK   0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF    22
+#define HCI_READ_LOCAL_AMP_ASSOC_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK   0x80
+#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF    22
+#define HCI_WRITE_REMOTE_AMP_ASSOC_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK)
+
+/* Supported Commands (Byte 23) */
+#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF    23
+#define HCI_READ_FLOW_CONTROL_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK   0x02
+#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF    23
+#define HCI_WRITE_FLOW_CONTROL_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK   0x04
+#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF    23
+#define HCI_READ_DATA_BLOCK_SIZE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK   0x20
+#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF    23
+#define HCI_ENABLE_AMP_RCVR_REPORTS_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF] & HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK)
+
+#define HCI_SUPP_COMMANDS_AMP_TEST_END_MASK   0x40
+#define HCI_SUPP_COMMANDS_AMP_TEST_END_OFF    23
+#define HCI_AMP_TEST_END_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_AMP_TEST_END_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_END_MASK)
+
+#define HCI_SUPP_COMMANDS_AMP_TEST_MASK   0x80
+#define HCI_SUPP_COMMANDS_AMP_TEST_OFF    23
+#define HCI_AMP_TEST_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_AMP_TEST_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_MASK)
+
+/* Supported Commands (Byte 24) */
+#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF    24
+#define HCI_READ_TRANSMIT_POWER_LEVEL_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK   0x04
+#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF    24
+#define HCI_READ_BE_FLUSH_TOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK   0x08
+#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF    24
+#define HCI_WRITE_BE_FLUSH_TOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK   0x10
+#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF    24
+#define HCI_SHORT_RANGE_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF] & HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK)
+
+/* LE commands TBD
+** Supported Commands (Byte 24 continued)
+** Supported Commands (Byte 25)
+** Supported Commands (Byte 26)
+** Supported Commands (Byte 27)
+** Supported Commands (Byte 28)
+*/
+
+/*
+Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator
+*/
+#ifdef _WIDCOMM
+
+#define HCI_SET_HCI_TRACE               (0x0001 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_SET_LM_TRACE                (0x0002 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_WRITE_COUNTRY_CODE          (0x0004 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_READ_LM_HISTORY             (0x0005 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_WRITE_BD_ADDR               (0x0006 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DISABLE_ENCRYPTION          (0x0007 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DISABLE_AUTHENTICATION      (0x0008 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GENERIC_LC_CMD              (0x000A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_INCR_POWER                  (0x000B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DECR_POWER                  (0x000C | HCI_GRP_VENDOR_SPECIFIC)
+
+/* Definitions for the local transactions */
+#define LM_DISCONNECT                  (0x00D0 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_AUTHENTICATION_REQUESTED    (0x00D1 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SET_CONN_ENCRYPTION         (0x00D2 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_START_ENCRYPT_KEY_SIZE      (0x00D3 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_START_ENCRYPTION            (0x00D4 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_STOP_ENCRYPTION             (0x00D5 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_CHANGE_CONN_PACKET_TYPE     (0x00D6 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_RMT_NAME_REQUEST            (0x00D7 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_FEATURES           (0x00D8 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_VERSION_INFO       (0x00D9 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_TIMING_INFO        (0x00DA | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_CLOCK_OFFSET       (0x00DB | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HOLD_MODE                   (0x00DC | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_EXIT_PARK_MODE              (0x00DD | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_SCO_LINK_REQUEST            (0x00E0 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SCO_CHANGE                  (0x00E4 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SCO_REMOVE                  (0x00E8 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_MAX_SLOTS                   (0x00F1 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_MAX_SLOTS_REQUEST           (0x00F2 | HCI_GRP_VENDOR_SPECIFIC)
+
+#ifdef INCLUDE_OPTIONAL_PAGING_SCHEME
+#define LM_OPTIONAL_PAGE_REQUEST       (0x00F3 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_OPTIONAL_PAGESCAN_REQUEST   (0x00F4 | HCI_GRP_VENDOR_SPECIFIC)
+#endif
+
+#define LM_SETUP_COMPLETE              (0x00FF | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_HIST_SEND_LMP_FRAME         (0x0100 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_RECV_LMP_FRAME         (0x0101 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCIT_ERROR             (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_PER_INQ_TOUT           (0x0103 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_INQ_SCAN_TOUT          (0x0104 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_PAGE_SCAN_TOUT         (0x0105 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_RESET_TOUT             (0x0106 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_MANDAT_PSCAN_TOUT      (0x0107 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_START_TRANS        (0x0108 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_HOST_REPLY         (0x0109 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_TIMEOUT            (0x010A | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_TX_COMP            (0x010B | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_HCID_SUSPENDED     (0x010C | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_FAILED             (0x010D | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_COMMAND            (0x010E | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_HIST_HCI_EVENT              (0x010F | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_UPDATA             (0x0110 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_DNDATA             (0x0111 | HCI_GRP_VENDOR_SPECIFIC)
+
+#define HCI_ENTER_TEST_MODE            (0x0300 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_LMP_TEST_CNTRL             (0x0301 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_CMD_MIN           (0x0300 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_CMD_MAX           (0x03FF | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_COMMAND           HCI_DEBUG_LC_CMD_MAX
+
+#endif
+
+
+/* Broadcom Vendor Specific Event sub-codes */
+#define HCI_BRCM_VSE_SUBCODE_AUTOMATIC_PAIRING_REQUEST              0x01
+#define HCI_BRCM_VSE_SUBCODE_RX_COMPLETE                            0x02
+#define HCI_BRCM_VSE_SUBCODE_LINK_QUALITY_REPORT                    0x03
+#define HCI_BRCM_VSE_SUBCODE_IOP_TEST_RX_1_PACKET_REPORT            0x04
+#define HCI_BRCM_VSE_SUBCODE_IOP_TEST_RX_N_PACKETS_REPORT_SUMMARY   0x05
+#define HCI_BRCM_VSE_SUBCODE_MODULE_XRAM_TEST_REPORT_SUMMARY        0x06
+#define HCI_BRCM_VSE_SUBCODE_CONNECTIONLESS_RX_TEST_STATISTICS      0x07
+#define HCI_BRCM_VSE_SUBCODE_FM_INTERRUPT                           0x08
+#define HCI_BRCM_VSE_SUBCODE_TCA_DEBUG_REPORT                       0x0B
+#define HCI_BRCM_VSE_SUBCODE_RAM_ROM_CLOCK_TEST_STATUS              0x0C
+#define HCI_BRCM_VSE_SUBCODE_DEBUG_OUTPUT_STRING                    0x0D
+#define HCI_BRCM_VSE_SUBCODE_PCM_DATA_DUMP                          0x0E
+#define HCI_BRCM_VSE_SUBCODE_PROTOCOL_MESSAGE_DUMP                  0x0F
+#define HCI_BRCM_VSE_SUBCODE_GPS_DATA                               0x10
+#define HCI_BRCM_VSE_SUBCODE_RESERVED_11                            0x11
+#define HCI_BRCM_VSE_SUBCODE_GPS_SENSOR_EVENT                       0x12
+#define HCI_BRCM_VSE_SUBCODE_GPS_SENSOR_SETUP_EVENT                 0x13
+#define HCI_BRCM_VSE_SUBCODE_MEIF_RX_EVENT                          0x14
+#define HCI_BRCM_VSE_SUBCODE_UNDETECTED_CRC_ERROR_EVENT             0x15
+#define HCI_BRCM_VSE_SUBCODE_BFC_DISCONNECT_EVENT                   0x16
+#define HCI_BRCM_VSE_SUBCODE_CUSTOMER_SPECIFIC_CS_ENERGY_DETECTED_EVENTS 0x17
+#define HCI_BRCM_VSE_SUBCODE_BFC_POLLING_INFO_EVENT                 0x18
+#define HCI_BRCM_VSE_SUBCODE_EEPROM_CHIP_ERASE_BY_MINIDRIVER_STATUS_REPORT 0xCE
+
+/* MIP related Vendor Specific Event */
+#define HCI_BRCM_VSE_SUBCODE_MIP_MODE_CHANGE            0x27
+#define HCI_BRCM_VSE_SUBCODE_MIP_DISCONNECT             0x28
+#define HCI_BRCM_VSE_SUBCODE_MIP_EIR_CMPLT              0x29
+#define HCI_BRCM_VSE_SUBCODE_MIP_ENC_KEY                0x2A
+#define HCI_BRCM_VSE_SUBCODE_MIP_DATA_RECEIVED          0x2E
+
+/* AMP VSE events
+*/
+#define AMP_VSE_CHANSPEC_CHAN_MASK      0x00ff
+
+#define AMP_VSE_CHANSPEC_CTL_SB_MASK    0x0300
+#define AMP_VSE_CHANSPEC_CTL_SB_LOWER   0x0100
+#define AMP_VSE_CHANSPEC_CTL_SB_UPPER   0x0200
+#define AMP_VSE_CHANSPEC_CTL_SB_NONE    0x0300
+
+#define AMP_VSE_CHANSPEC_BW_MASK        0x0C00
+#define AMP_VSE_CHANSPEC_BW_10          0x0400
+#define AMP_VSE_CHANSPEC_BW_20          0x0800
+#define AMP_VSE_CHANSPEC_BW_40          0x0C00
+
+#define AMP_VSE_CHANSPEC_BAND_MASK      0xf000
+#define AMP_VSE_CHANSPEC_BAND_5G        0x1000
+#define AMP_VSE_CHANSPEC_BAND_2G        0x2000
+
+/* PCM2 related */
+#define HCI_BRCM_CUSTOMER_EXT_ARC_LEN   4
+#define LOC_AUDIO_ROUTING_CONTROL       0x88
+#define LOC_ARC_CHANNEL_ID              0xF3
+
+#define ARC_INTERFACE_PCMI2S            0x01
+#define ARC_INTERFACE_FM_I2S            0x02
+#define ARC_INTERFACE_SLB               0x03
+
+#define ARC_MODE_NOT_USED               0x00
+#define ARC_MODE_BT_AUDIO               0x01
+#define ARC_MODE_FMRX                   0x02
+#define ARC_MODE_FMTX                   0x03
+#define ARC_MODE_SHARED_BT_FMRX         0x04
+#define ARC_MODE_SHARED_BT_FMTX         0x05
+
+#define BRCM_PCM2_SETUP_READ_SIZE       0x01
+#define BRCM_PCM2_SETUP_WRITE_SIZE      0x1A
+
+#endif
+
diff --git a/halimpl/bcm2079x/include/nfc_target.h b/halimpl/bcm2079x/include/nfc_target.h
new file mode 100644
index 0000000..da72074
--- /dev/null
+++ b/halimpl/bcm2079x/include/nfc_target.h
@@ -0,0 +1,19 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#pragma once
+#include "nfc_hal_target.h"
diff --git a/halimpl/bcm2079x/include/spdhelper.h b/halimpl/bcm2079x/include/spdhelper.h
new file mode 100644
index 0000000..170fe06
--- /dev/null
+++ b/halimpl/bcm2079x/include/spdhelper.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <string>
+
+using namespace std;
+#define DEFAULT_SPD_MAXRETRYCOUNT (3)
+
+class SpdHelper
+{
+public:
+    static bool isPatchBad(UINT8* prm, UINT32 len);
+    static void setPatchAsBad();
+    static void incErrorCount();
+    static bool isSpdDebug();
+
+private:
+    SpdHelper();
+    static SpdHelper& getInstance();
+
+    bool isPatchBadImpl(UINT8* prm, UINT32 len);
+    void setPatchAsBadImpl();
+    void incErrorCountImpl();
+    bool isSpdDebugImpl() {return mSpdDebug;}
+    string mPatchId;
+    int  mErrorCount;
+    int  mMaxErrorCount;
+    bool mIsPatchBad;
+    bool mSpdDebug;
+};
diff --git a/halimpl/bcm2079x/include/userial.h b/halimpl/bcm2079x/include/userial.h
new file mode 100644
index 0000000..120d1ea
--- /dev/null
+++ b/halimpl/bcm2079x/include/userial.h
@@ -0,0 +1,288 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains serial definitions from WIDCOMM's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef USERIAL_H
+#define USERIAL_H
+
+/*******************************************************************************
+** Serial APIs
+*******************************************************************************/
+
+/**** port IDs ****/
+#define USERIAL_PORT_1            0
+#define USERIAL_PORT_2            1
+#define USERIAL_PORT_3            2
+#define USERIAL_PORT_4            3
+#define USERIAL_PORT_5            4
+#define USERIAL_PORT_6            5
+#define USERIAL_PORT_7            6
+#define USERIAL_PORT_8            7
+#define USERIAL_PORT_9            8
+#define USERIAL_PORT_10           9
+#define USERIAL_PORT_11           10
+#define USERIAL_PORT_12           11
+#define USERIAL_PORT_13           12
+#define USERIAL_PORT_14           13
+#define USERIAL_PORT_15           14
+#define USERIAL_PORT_16           15
+#define USERIAL_PORT_17           16
+#define USERIAL_PORT_18           17
+
+typedef UINT8 tUSERIAL_PORT;
+
+/**** baud rates ****/
+#define USERIAL_BAUD_300          0
+#define USERIAL_BAUD_600          1
+#define USERIAL_BAUD_1200         2
+#define USERIAL_BAUD_2400         3
+#define USERIAL_BAUD_9600         4
+#define USERIAL_BAUD_19200        5
+#define USERIAL_BAUD_57600        6
+#define USERIAL_BAUD_115200       7
+#define USERIAL_BAUD_230400       8
+#define USERIAL_BAUD_460800       9
+#define USERIAL_BAUD_921600       10
+#define USERIAL_BAUD_1M           11
+#define USERIAL_BAUD_1_5M         12
+#define USERIAL_BAUD_2M           13
+#define USERIAL_BAUD_3M           14
+#define USERIAL_BAUD_4M           15
+#define USERIAL_BAUD_AUTO         16
+
+/**** Data Format ****/
+
+/* Stop Bits */
+#define USERIAL_STOPBITS_1        1
+#define USERIAL_STOPBITS_1_5      (1<<1)
+#define USERIAL_STOPBITS_2        (1<<2)
+
+/* Parity Bits */
+#define USERIAL_PARITY_NONE       (1<<3)
+#define USERIAL_PARITY_EVEN       (1<<4)
+#define USERIAL_PARITY_ODD        (1<<5)
+
+/* Data Bits */
+#define USERIAL_DATABITS_5        (1<<6)
+#define USERIAL_DATABITS_6        (1<<7)
+#define USERIAL_DATABITS_7        (1<<8)
+#define USERIAL_DATABITS_8        (1<<9)
+
+
+/**** Flow Control ****/
+#define USERIAL_FC_NONE           0
+#define USERIAL_FC_HW             1
+#define USERIAL_FC_SW             2
+
+/**** Data Buffering Mechanism ****/
+#define USERIAL_BUF_BYTE          0
+#define USERIAL_BUF_GKI           1
+
+/**** Signals ****/
+#define USERIAL_SIG_RTSCTS        1
+#define USERIAL_SIG_DSRDTR        (1<<1)
+#define USERIAL_SIG_RI            (1<<2)
+#define USERIAL_SIG_CD            (1<<3)
+#define USERIAL_SIG_DTE_DEVICE    (1<<4)
+
+/**** Errors *****/
+#define USERIAL_ERR_OVERRUN       1
+#define USERIAL_ERR_PARITY        (1<<1)
+#define USERIAL_ERR_FRAMING       (1<<2)
+#define USERIAL_ERR_BREAK         (1<<3)
+
+/**** Serial Operations ****/
+#define USERIAL_OP_FLUSH          0
+#define USERIAL_OP_FLUSH_RX       1
+#define USERIAL_OP_FLUSH_TX       2
+#define USERIAL_OP_BREAK_OFF      3
+#define USERIAL_OP_BREAK_ON       4
+#define USERIAL_OP_BAUD_RD        5
+#define USERIAL_OP_BAUD_WR        6
+#define USERIAL_OP_FMT_RD         7
+#define USERIAL_OP_FMT_WR         8
+#define USERIAL_OP_SIG_RD         9
+#define USERIAL_OP_SIG_WR         10
+#define USERIAL_OP_FC_RD          11
+#define USERIAL_OP_FC_WR          12
+#define USERIAL_OP_CTS_AS_WAKEUP  13    /* H4IBSS */
+#define USERIAL_OP_CTS_AS_FC      14    /* H4IBSS */
+
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+#define USERIAL_OP_SCO_UP         20    /* LINUX SCO */
+#define USERIAL_OP_SCO_DOWN       21    /* LINUX SCO */
+#endif
+
+typedef UINT8 tUSERIAL_OP;
+
+
+/**** Serial feature types ****/
+#define USERIAL_FEAT_PORT_1       0
+#define USERIAL_FEAT_PORT_2       1
+#define USERIAL_FEAT_PORT_3       2
+#define USERIAL_FEAT_PORT_4       3
+#define USERIAL_FEAT_BAUD_AUTO    4
+#define USERIAL_FEAT_BAUD_300     5
+#define USERIAL_FEAT_BAUD_600     6
+#define USERIAL_FEAT_BAUD_1200    7
+#define USERIAL_FEAT_BAUD_2400    8
+#define USERIAL_FEAT_BAUD_9600    9
+#define USERIAL_FEAT_BAUD_19200   10
+#define USERIAL_FEAT_BAUD_57600   11
+#define USERIAL_FEAT_BAUD_115200  12
+#define USERIAL_FEAT_BAUD_230400  13
+#define USERIAL_FEAT_BAUD_460800  14
+#define USERIAL_FEAT_BAUD_921600  15
+#define USERIAL_FEAT_STOPBITS_1   16
+#define USERIAL_FEAT_STOPBITS_1_5 17
+#define USERIAL_FEAT_STOPBITS_2   18
+#define USERIAL_FEAT_PARITY_NONE  19
+#define USERIAL_FEAT_PARITY_EVEN  20
+#define USERIAL_FEAT_PARITY_ODD   21
+#define USERIAL_FEAT_DATABITS_5   22
+#define USERIAL_FEAT_DATABITS_6   23
+#define USERIAL_FEAT_DATABITS_7   24
+#define USERIAL_FEAT_DATABITS_8   25
+#define USERIAL_FEAT_FC_NONE      26
+#define USERIAL_FEAT_FC_HW        27
+#define USERIAL_FEAT_FC_SW        28
+#define USERIAL_FEAT_BUF_BYTE     29
+#define USERIAL_FEAT_BUF_GKI      30
+#define USERIAL_FEAT_SIG_RTS      31
+#define USERIAL_FEAT_SIG_CTS      32
+#define USERIAL_FEAT_SIG_DSR      33
+#define USERIAL_FEAT_SIG_DTR      34
+#define USERIAL_FEAT_SIG_RI       35
+#define USERIAL_FEAT_SIG_CD       36
+#define USERIAL_FEAT_OP_FLUSH     37
+#define USERIAL_FEAT_OP_FLUSH_RX  38
+#define USERIAL_FEAT_OP_FLUSH_TX  39
+#define USERIAL_FEAT_OP_BREAK     40
+#define USERIAL_FEAT_OP_BAUD_RD   41
+#define USERIAL_FEAT_OP_BAUD_WR   42
+#define USERIAL_FEAT_OP_FMT_RD    43
+#define USERIAL_FEAT_OP_FMT_WR    44
+#define USERIAL_FEAT_OP_SIG_RD    45
+#define USERIAL_FEAT_OP_SIG_WR    46
+#define USERIAL_FEAT_OP_FC_RD     47
+#define USERIAL_FEAT_OP_FC_WR     48
+
+typedef UINT8 tUSERIAL_FEATURE;
+
+
+/**** Event types ****/
+#define USERIAL_RX_READY_EVT      0
+#define USERIAL_TX_DONE_EVT       1
+#define USERIAL_SIG_EVT           2
+#define USERIAL_ERR_EVT           3
+#define USERIAL_WAKEUP_EVT        4 /* H4IBSS */
+
+typedef UINT8 tUSERIAL_EVT;
+
+
+/* Structure used to configure serial port during open        */
+typedef struct
+{
+    UINT16 fmt;          /* Data format                       */
+    UINT8  baud;         /* Baud rate                         */
+    UINT8  fc;           /* Flow control                      */
+    UINT8  buf;          /* Data buffering mechanism          */
+    UINT8  pool;         /* GKI buffer pool for received data */
+    UINT16 size;         /* Size of GKI buffer pool           */
+    UINT16 offset;       /* Offset in GKI buffer pool         */
+} tUSERIAL_OPEN_CFG;
+
+/* Union used to pass ioctl arguments */
+typedef union
+{
+    UINT16 fmt;
+    UINT8  baud;
+    UINT8  fc;
+    UINT8  sigs;
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+    UINT16 sco_handle;
+#endif
+} tUSERIAL_IOCTL_DATA;
+
+
+/* Union to pass event data */
+typedef union
+{
+    UINT8 sigs;
+    UINT8 error;
+} tUSERIAL_EVT_DATA;
+
+/* callback for events */
+typedef void (tUSERIAL_CBACK)(tUSERIAL_PORT, tUSERIAL_EVT, tUSERIAL_EVT_DATA *);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void    USERIAL_Init(void *);
+UDRV_API extern void    USERIAL_Open(tUSERIAL_PORT, tUSERIAL_OPEN_CFG *, tUSERIAL_CBACK *);
+UDRV_API extern void    USERIAL_ReadBuf(tUSERIAL_PORT, BT_HDR **);
+UDRV_API extern UINT16  USERIAL_Read(tUSERIAL_PORT, UINT8 *, UINT16);
+UDRV_API extern BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT, BT_HDR *);
+UDRV_API extern UINT16  USERIAL_Write(tUSERIAL_PORT, UINT8 *, UINT16);
+UDRV_API extern void    USERIAL_Ioctl(tUSERIAL_PORT, tUSERIAL_OP, tUSERIAL_IOCTL_DATA *);
+UDRV_API extern void    USERIAL_Close(tUSERIAL_PORT);
+UDRV_API extern BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE);
+UDRV_API extern BOOLEAN USERIAL_IsClosed();
+UDRV_API extern void    USERIAL_PowerupDevice(tUSERIAL_PORT port);
+
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetLineSpeed
+ **
+ ** Description        This function convert USERIAL baud to line speed.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud);
+/*******************************************************************************
+ **
+ ** Function           USERIAL_GetBaud
+ **
+ ** Description        This function convert line speed to USERIAL baud.
+ **
+ ** Output Parameter   None
+ **
+ ** Returns            line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USERIAL_H */
diff --git a/halimpl/bcm2079x/libnfc-brcm.conf b/halimpl/bcm2079x/libnfc-brcm.conf
new file mode 100644
index 0000000..5cf09e7
--- /dev/null
+++ b/halimpl/bcm2079x/libnfc-brcm.conf
@@ -0,0 +1,208 @@
+## this file is used by Broadcom's Hardware Abstraction Layer at external/libnfc-nci/halimpl/
+
+###############################################################################
+# Application options
+APPL_TRACE_LEVEL=0xFF
+PROTOCOL_TRACE_LEVEL=0xFFFFFFFF
+
+###############################################################################
+# performance measurement
+# Change this setting to control how often USERIAL log the performance (throughput)
+# data on read/write/poll
+# defailt is to log performance dara for every 100 read or write
+#REPORT_PERFORMANCE_MEASURE=100
+
+###############################################################################
+# File used for NFA storage
+NFA_STORAGE="/data/nfc"
+
+###############################################################################
+# Snooze Mode Settings
+#
+#  By default snooze mode is enabled.  Set SNOOZE_MODE_CFG byte[0] to 0
+#  to disable.
+#
+#  If SNOOZE_MODE_CFG is not provided, the default settings are used:
+#  They are as follows:
+#       8             Sleep Mode (0=Disabled 1=UART 8=SPI/I2C)
+#       0             Idle Threshold Host
+#       0             Idle Threshold HC
+#       0             NFC Wake active mode (0=ActiveLow 1=ActiveHigh)
+#       1             Host Wake active mode (0=ActiveLow 1=ActiveHigh)
+#
+#SNOOZE_MODE_CFG={08:00:00:00:01}
+
+###############################################################################
+# Insert a delay in milliseconds after NFC_WAKE and before write to NFCC
+NFC_WAKE_DELAY=20
+
+###############################################################################
+# Various Delay settings (in ms) used in USERIAL
+#  POWER_ON_DELAY
+#    Delay after turning on chip, before writing to transport (default 300)
+#  PRE_POWER_OFF_DELAY
+#    Delay after deasserting NFC-Wake before turn off chip (default 0)
+#  POST_POWER_OFF_DELAY
+#    Delay after turning off chip, before USERIAL_close returns (default 0)
+#
+#POWER_ON_DELAY=300
+#PRE_POWER_OFF_DELAY=0
+#POST_POWER_OFF_DELAY=0
+
+###############################################################################
+# LPTD mode configuration
+#  byte[0] is the length of the remaining bytes in this value
+#     if set to 0, LPTD params will NOT be sent to NFCC (i.e. disabled).
+#  byte[1] is the param id it should be set to B9.
+#  byte[2] is the length of the LPTD parameters
+#  byte[3] indicates if LPTD is enabled
+#     if set to 0, LPTD will be disabled (parameters will still be sent).
+#  byte[4-n] are the LPTD parameters.
+#  By default, LPTD is enabled and default settings are used.
+#  See nfc_hal_dm_cfg.c for defaults
+LPTD_CFG={23:B9:21:01:02:FF:FF:04:A0:0F:40:00:80:02:02:10:00:00:00:31:0C:30:00:00:00:00:00:00:00:00:00:00:00:00:00:00}
+
+###############################################################################
+# Startup Configuration (100 bytes maximum)
+#
+# For the 0xCA parameter, byte[9] (marked by 'AA') is for UICC0, and byte[10] (marked by BB) is
+#    for UICC1.  The values are defined as:
+#   0 : UICCx only supports ISO_DEP in low power mode.
+#   2 : UICCx only supports Mifare in low power mode.
+#   3 : UICCx supports both ISO_DEP and Mifare in low power mode.
+#
+#                                                                          AA BB
+NFA_DM_START_UP_CFG={1F:CB:01:01:A5:01:01:CA:14:00:00:00:00:06:E8:03:00:00:00:00:00:00:00:00:00:00:00:00:00:28:01:01}
+
+###############################################################################
+# Startup Vendor Specific Configuration (100 bytes maximum);
+#  byte[0] TLV total len = 0x5
+#  byte[1] NCI_MTS_CMD|NCI_GID_PROP = 0x2f
+#  byte[2] NCI_MSG_FRAME_LOG = 0x9
+#  byte[3] 2
+#  byte[4] 0=turn off RF frame logging; 1=turn on
+#  byte[5] 0=turn off SWP frame logging; 1=turn on
+#  NFA_DM_START_UP_VSC_CFG={05:2F:09:02:01:01}
+
+###############################################################################
+# Configure crystal frequency when internal LPO can't detect the frequency.
+#XTAL_FREQUENCY=0
+
+###############################################################################
+# Firmware patch file
+#  If the value is not set then patch download is disabled.
+FW_PATCH="/vendor/firmware/bcm2079x_firmware.ncd"
+
+###############################################################################
+# Firmware pre-patch file (sent before the above patch file)
+#  If the value is not set then pre-patch is not used.
+FW_PRE_PATCH="/vendor/firmware/bcm2079x_pre_firmware.ncd"
+
+###############################################################################
+# Firmware patch format
+#   1 = HCD
+#   2 = NCD (default)
+#NFA_CONFIG_FORMAT=2
+
+###############################################################################
+# SPD Debug mode
+#  If set to 1, any failure of downloading a patch will trigger a hard-stop
+#SPD_DEBUG=0
+
+###############################################################################
+# SPD Max Retry Count
+#  The number of attempts to download a patch before giving up (defualt is 3).
+#  Note, this resets after a power-cycle.
+#SPD_MAX_RETRY_COUNT=3
+
+###############################################################################
+# transport driver
+#
+# TRANSPORT_DRIVER=<driver>
+#
+#  where <driver> can be, for example:
+#    "/dev/ttyS"        (UART)
+#    "/dev/bcmi2cnfc"   (I2C)
+#    "hwtun"            (HW Tunnel)
+#    "/dev/bcmspinfc"   (SPI)
+#    "/dev/btusb0"      (BT USB)
+TRANSPORT_DRIVER="/dev/bcm2079x"
+
+###############################################################################
+# power control driver
+# Specify a kernel driver that support ioctl commands to control NFC_EN and
+# NFC_WAKE gpio signals.
+#
+# POWER_CONTRL_DRIVER=<driver>
+#  where <driver> can be, for example:
+#    "/dev/nfcpower"
+#    "/dev/bcmi2cnfc"   (I2C)
+#    "/dev/bcmspinfc"   (SPI)
+#    i2c and spi driver may be used to control NFC_EN and NFC_WAKE signal
+POWER_CONTROL_DRIVER="/dev/bcm2079x"
+
+###############################################################################
+# I2C transport driver options
+#
+BCMI2CNFC_ADDRESS=0
+
+###############################################################################
+# I2C transport driver try to read multiple packets in read() if data is available
+# remove the comment below to enable this feature
+#READ_MULTIPLE_PACKETS=1
+
+###############################################################################
+# SPI transport driver options
+#SPI_NEGOTIATION={0A:F0:00:01:00:00:00:FF:FF:00:00}
+
+###############################################################################
+# UART transport driver options
+#
+# PORT=1,2,3,...
+# BAUD=115200, 19200, 9600, 4800,
+# DATABITS=8, 7, 6, 5
+# PARITY="even" | "odd" | "none"
+# STOPBITS="0" | "1" | "1.5" | "2"
+
+#UART_PORT=2
+#UART_BAUD=115200
+#UART_DATABITS=8
+#UART_PARITY="none"
+#UART_STOPBITS="1"
+
+###############################################################################
+# Insert a delay in microseconds per byte after a write to NFCC.
+# after writing a block of data to the NFCC, delay this an amopunt of time before
+# writing next block of data.  the delay is calculated as below
+#   NFC_WRITE_DELAY * (number of byte written) / 1000 milliseconds
+# e.g. after 259 bytes is written, delay (259 * 20 / 1000) 5 ms before next write
+NFC_WRITE_DELAY=20
+
+###############################################################################
+# Maximum Number of Credits to be allowed by the NFCC
+#   This value overrides what the NFCC specifices allowing the host to have
+#   the control to work-around transport limitations.  If this value does
+#   not exist or is set to 0, the NFCC will provide the number of credits.
+MAX_RF_DATA_CREDITS=1
+
+###############################################################################
+# Allow UICC to be powered off if there is no traffic.
+# Timeout is in ms. If set to 0, then UICC will not be powered off.
+UICC_IDLE_TIMEOUT=30000
+
+
+###############################################################################
+# Antenna Configuration - This data is used when setting 0xC8 config item
+# at startup (before discovery is started).  If not used, no value is sent.
+#
+# The settings for this value are documented here:
+# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/
+#   Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx
+# This document is maintained by Paul Forshaw.
+#
+# The values marked as ?? should be tweaked per antenna or customer/app:
+# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04}
+# array[0] = 0x20 is length of the payload from array[1] to the end
+# array[1] = 0xC8 is PREINIT_DSP_CFG
+#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04}
+
diff --git a/halimpl/bcm2079x/nfc_nci.c b/halimpl/bcm2079x/nfc_nci.c
new file mode 100644
index 0000000..850357a
--- /dev/null
+++ b/halimpl/bcm2079x/nfc_nci.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include <errno.h>
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+#include "HalAdaptation.h"
+
+
+/*********************************
+ * NCI HAL method implementations.
+ *********************************/
+
+
+static int hal_open (const struct nfc_nci_device *p_dev, nfc_stack_callback_t *p_hal_cback, nfc_stack_data_callback_t *p_hal_data_callback)
+{
+    int retval = 0;
+    bcm2079x_dev_t *dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiOpen (dev, p_hal_cback, p_hal_data_callback);
+    return retval;
+}
+
+
+static int hal_write (const struct nfc_nci_device *p_dev,
+        uint16_t data_len, const uint8_t *p_data)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiWrite (dev, data_len, p_data);
+    return retval;
+}
+
+
+static int hal_core_initialized (const struct nfc_nci_device *p_dev,
+        uint8_t* p_core_init_rsp_params)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiCoreInitialized (dev, p_core_init_rsp_params);
+    return retval;
+}
+
+
+static int hal_pre_discover (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiPreDiscover (dev);
+    return retval;
+}
+
+
+static int hal_close (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiClose (dev);
+    return retval;
+}
+
+
+static int hal_control_granted (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiControlGranted (dev);
+   return retval;
+}
+
+
+static int hal_power_cycle (const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiPowerCycle (dev);
+    return retval;
+}
+
+
+/*************************************
+ * Generic device handling.
+ *************************************/
+
+
+/* Close an opened nfc device instance */
+static int nfc_close (hw_device_t *dev)
+{
+    int retval = 0;
+    free (dev);
+    retval = HaiTerminateLibrary ();
+    return retval;
+}
+
+
+static int nfc_open (const hw_module_t* module, const char* name, hw_device_t** device)
+{
+    ALOGD ("%s: enter; name=%s", __FUNCTION__, name);
+    int retval = 0; //0 is ok; -1 is error
+
+    if (strcmp (name, NFC_NCI_CONTROLLER) == 0)
+    {
+        bcm2079x_dev_t *dev = calloc (1, sizeof(bcm2079x_dev_t));
+
+        // Common hw_device_t fields
+        dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
+        dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
+        dev->nci_device.common.module = (struct hw_module_t*) module;
+        dev->nci_device.common.close = nfc_close;
+
+        // NCI HAL method pointers
+        dev->nci_device.open = hal_open;
+        dev->nci_device.write = hal_write;
+        dev->nci_device.core_initialized = hal_core_initialized;
+        dev->nci_device.pre_discover = hal_pre_discover;
+        dev->nci_device.close = hal_close;
+        dev->nci_device.control_granted = hal_control_granted;
+        dev->nci_device.power_cycle = hal_power_cycle;
+
+        // Copy in
+        *device = (hw_device_t*) dev;
+
+        retval = HaiInitializeLibrary (dev);
+    }
+    else
+    {
+        retval = -EINVAL;
+    }
+    ALOGD ("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+
+static struct hw_module_methods_t nfc_module_methods =
+{
+    .open = nfc_open,
+};
+
+
+struct nfc_nci_module_t HAL_MODULE_INFO_SYM =
+{
+    .common =
+    {
+        .tag = HARDWARE_MODULE_TAG, .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
+        .hal_api_version = 0x00, // 0 is only valid value
+        .id = NFC_NCI_HARDWARE_MODULE_ID,
+        .name = "Default NFC NCI HW HAL",
+        .author = "The Android Open Source Project",
+        .methods = &nfc_module_methods,
+    },
+};
diff --git a/halimpl/bcm2079x/udrv/include/upio.h b/halimpl/bcm2079x/udrv/include/upio.h
new file mode 100644
index 0000000..77ee4ba
--- /dev/null
+++ b/halimpl/bcm2079x/udrv/include/upio.h
@@ -0,0 +1,366 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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 UPIO_H
+#define UPIO_H
+
+/* Enumeration of UPIO features                                         */
+/* Not all features enumerated here are supported by the hardware.      */
+/* Use UPIO_Feature() to determine support of a particular feature.     */
+enum
+{
+    /* LEDs */
+    UPIO_FEAT_LED1,
+    UPIO_FEAT_LED2,
+    UPIO_FEAT_LED3,
+    UPIO_FEAT_LED4,
+    UPIO_FEAT_LED5,
+    UPIO_FEAT_LED6,
+    UPIO_FEAT_LED7,
+    UPIO_FEAT_LED8,
+
+    /* Switches */
+    UPIO_FEAT_SWITCH1,
+    UPIO_FEAT_SWITCH2,
+    UPIO_FEAT_SWITCH3,
+    UPIO_FEAT_SWITCH4,
+    UPIO_FEAT_SWITCH5,
+    UPIO_FEAT_SWITCH6,
+    UPIO_FEAT_SWITCH7,
+    UPIO_FEAT_SWITCH8,
+    UPIO_FEAT_SWITCH9,
+    UPIO_FEAT_SWITCH10,
+    UPIO_FEAT_SWITCH11,
+    UPIO_FEAT_SWITCH12,
+    UPIO_FEAT_SWITCH13,
+    UPIO_FEAT_SWITCH14,
+    UPIO_FEAT_SWITCH15,
+    UPIO_FEAT_SWITCH16,
+
+    /* Jumpers */
+    UPIO_FEAT_JUMPER1,
+    UPIO_FEAT_JUMPER2,
+    UPIO_FEAT_JUMPER3,
+    UPIO_FEAT_JUMPER4,
+    UPIO_FEAT_JUMPER5,
+    UPIO_FEAT_JUMPER6,
+    UPIO_FEAT_JUMPER7,
+    UPIO_FEAT_JUMPER8,
+
+    /* Push buttons */
+    UPIO_FEAT_BUTTON1,
+    UPIO_FEAT_BUTTON2,
+    UPIO_FEAT_BUTTON3,
+    UPIO_FEAT_BUTTON4,
+    UPIO_FEAT_BUTTON5,
+    UPIO_FEAT_BUTTON6,
+    UPIO_FEAT_BUTTON7,
+    UPIO_FEAT_BUTTON8,
+
+    /* General purpose */
+    UPIO_FEAT_GENERAL1,
+    UPIO_FEAT_GENERAL2,
+    UPIO_FEAT_GENERAL3,
+    UPIO_FEAT_GENERAL4,
+    UPIO_FEAT_GENERAL5,
+    UPIO_FEAT_GENERAL6,
+    UPIO_FEAT_GENERAL7,
+    UPIO_FEAT_GENERAL8,
+    UPIO_FEAT_GENERAL9,
+    UPIO_FEAT_GENERAL10,
+    UPIO_FEAT_GENERAL11,
+    UPIO_FEAT_GENERAL12,
+    UPIO_FEAT_GENERAL13,
+    UPIO_FEAT_GENERAL14,
+    UPIO_FEAT_GENERAL15,
+    UPIO_FEAT_GENERAL16,
+    UPIO_FEAT_GENERAL17,
+    UPIO_FEAT_GENERAL18,
+    UPIO_FEAT_GENERAL19,
+    UPIO_FEAT_GENERAL20,
+    UPIO_FEAT_GENERAL21,
+    UPIO_FEAT_GENERAL22,
+    UPIO_FEAT_GENERAL23,
+    UPIO_FEAT_GENERAL24,
+    UPIO_FEAT_GENERAL25,
+    UPIO_FEAT_GENERAL26,
+    UPIO_FEAT_GENERAL27,
+    UPIO_FEAT_GENERAL28,
+    UPIO_FEAT_GENERAL29,
+    UPIO_FEAT_GENERAL30,
+    UPIO_FEAT_GENERAL31,
+    UPIO_FEAT_GENERAL32,
+
+    UPIO_FEAT_IN_HIGH,          /* Support for input with interrupt on high signal level. */
+    UPIO_FEAT_IN_LOW,           /* Support for input with interrupt on low signal level. */
+    UPIO_FEAT_IN_RISE,          /* Support for input with interrupt on rising edge. */
+    UPIO_FEAT_IN_FALL           /* Support for input with interrupt on falling. */
+
+};
+typedef UINT8 tUPIO_FEATURE;
+
+
+/* Enumeration of UPIO configurations */
+enum
+{
+    UPIO_OUT,
+    UPIO_IN,
+    UPIO_IN_EDGE,
+    UPIO_IN_LEVEL,
+    UPIO_NONE
+};
+typedef UINT8 tUPIO_CONFIG;
+
+
+/* Enumeration of UPIO types */
+enum
+{
+    UPIO_LED,                   /* LED */
+    UPIO_SWITCH,                /* Switch */
+    UPIO_JUMPER,                /* Jumper */
+    UPIO_BUTTON,                /* Push-button switch */
+    UPIO_GENERAL,               /* General purpose I/O */
+
+    UPIO_NUMBER_OF_TYPES
+};
+typedef UINT8 tUPIO_TYPE;
+
+
+/* Enumeration of UPIO states */
+enum
+{
+    UPIO_OFF,
+    UPIO_ON,
+    UPIO_TOGGLE
+};
+typedef UINT8 tUPIO_STATE;
+
+
+enum
+{
+    UPIO_SW_BANK2,
+    UPIO_SW_BANK3
+};
+typedef UINT8 tUPIO_SW_BANK;
+
+/* Jumper masks */
+#define UPIO_JUMPER1    0x00000001
+#define UPIO_JUMPER2    0x00000002
+#define UPIO_JUMPER3    0x00000004
+#define UPIO_JUMPER4    0x00000008
+#define UPIO_JUMPER5    0x00000010
+#define UPIO_JUMPER6    0x00000020
+#define UPIO_JUMPER7    0x00000040
+#define UPIO_JUMPER8    0x00000080
+
+/* General purpose i/o masks */
+#define UPIO_GENERAL1   0x00000001
+#define UPIO_GENERAL2   0x00000002
+#define UPIO_GENERAL3   0x00000004
+#define UPIO_GENERAL4   0x00000008
+#define UPIO_GENERAL5   0x00000010
+#define UPIO_GENERAL6   0x00000020
+#define UPIO_GENERAL7   0x00000040
+#define UPIO_GENERAL8   0x00000080
+#define UPIO_GENERAL9   0x00000100
+#define UPIO_GENERAL10  0x00000200
+#define UPIO_GENERAL11  0x00000400
+#define UPIO_GENERAL12  0x00000800
+#define UPIO_GENERAL13  0x00001000
+#define UPIO_GENERAL14  0x00002000
+#define UPIO_GENERAL15  0x00004000
+#define UPIO_GENERAL16  0x00008000
+#define UPIO_GENERAL17  0x00010000
+#define UPIO_GENERAL18  0x00020000
+#define UPIO_GENERAL19  0x00040000
+#define UPIO_GENERAL20  0x00080000
+#define UPIO_GENERAL21  0x00100000
+#define UPIO_GENERAL22  0x00200000
+#define UPIO_GENERAL23  0x00400000
+#define UPIO_GENERAL24  0x00800000
+#define UPIO_GENERAL25  0x01000000
+#define UPIO_GENERAL26  0x02000000
+#define UPIO_GENERAL27  0x04000000
+#define UPIO_GENERAL28  0x08000000
+#define UPIO_GENERAL29  0x10000000
+#define UPIO_GENERAL30  0x20000000
+#define UPIO_GENERAL31  0x40000000
+#define UPIO_GENERAL32  0x80000000
+
+typedef UINT32 tUPIO;
+
+/* LED masks */
+#define UPIO_LED1       0x00000001
+#define UPIO_LED2       0x00000002
+#define UPIO_LED3       0x00000004
+#define UPIO_LED4       0x00000008
+#define UPIO_LED5       0x00000010
+#define UPIO_LED6       0x00000020
+#define UPIO_LED7       0x00000040
+#define UPIO_LED8       0x00000080
+
+#define UPIO_LED_ALL    (UPIO_LED1 | UPIO_LED2 | UPIO_LED3 | UPIO_LED4 | \
+                        UPIO_LED5 | UPIO_LED6 | UPIO_LED7 | UPIO_LED8)
+
+
+/* Switch masks */
+#define UPIO_SWITCH1    0x00000001
+#define UPIO_SWITCH2    0x00000002
+#define UPIO_SWITCH3    0x00000004
+#define UPIO_SWITCH4    0x00000008
+#define UPIO_SWITCH5    0x00000010
+#define UPIO_SWITCH6    0x00000020
+#define UPIO_SWITCH7    0x00000040
+#define UPIO_SWITCH8    0x00000080
+#define UPIO_SWITCH9    0x00000100
+#define UPIO_SWITCH10   0x00000200
+#define UPIO_SWITCH11   0x00000400
+#define UPIO_SWITCH12   0x00000800
+#define UPIO_SWITCH13   0x00001000
+#define UPIO_SWITCH14   0x00002000
+#define UPIO_SWITCH15   0x00004000
+#define UPIO_SWITCH16   0x00008000
+
+/* Push button masks */
+#define UPIO_BUTTON1    0x00000001
+#define UPIO_BUTTON2    0x00000002
+#define UPIO_BUTTON3    0x00000004
+#define UPIO_BUTTON4    0x00000008
+#define UPIO_BUTTON5    0x00000010
+#define UPIO_BUTTON6    0x00000020
+#define UPIO_BUTTON7    0x00000040
+#define UPIO_BUTTON8    0x00000080
+
+typedef void (tUPIO_CBACK)(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API functions for UPIO driver */
+
+/*****************************************************************************
+**
+** Function         UPIO_Init
+**
+** Description
+**      Initialize the GPIO service.
+**      This function is typically called once upon system startup.
+**
+** Returns          nothing
+**
+*****************************************************************************/
+UDRV_API void UPIO_Init(void *p_cfg);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Set
+**
+** Description
+**      This function sets one or more GPIO devices to the given state.
+**      Multiple GPIOs of the same type can be masked together to set more
+**      than one GPIO. This function can only be used on types UPIO_LED and
+**      UPIO_GENERAL.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      state   The desired state.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Read
+**
+** Description
+**      Read the state of a GPIO. This function can be used for any type of
+**      device. Parameter pio can only indicate a single GPIO; multiple GPIOs
+**      cannot be masked together.
+**
+** Input Parameters:
+**      Type:	The type of device.
+**      pio:    Indicates the particular GUPIO.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      State of GPIO (UPIO_ON or UPIO_OFF).
+**
+*****************************************************************************/
+UDRV_API tUPIO_STATE UPIO_Read(tUPIO_TYPE type, tUPIO pio);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Config
+**
+** Description      - Configure GPIOs of type UPIO_GENERAL as inputs or outputs
+**                  - Configure GPIOs to be polled or interrupt driven
+**
+**                  Currently only support polled GPIOs.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      config
+**      cback
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Config(tUPIO_TYPE type, tUPIO pio, tUPIO_CONFIG config, tUPIO_CBACK *cback);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Feature
+**
+** Description
+**      Checks whether a feature of the pio API is supported
+**
+** Input Parameter:
+**      feature     The feature to check
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      TRUE if feature is supported, FALSE if it is not.
+**
+*****************************************************************************/
+UDRV_API BOOLEAN UPIO_Feature(tUPIO_FEATURE feature);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* ifdef UPIO_H */
diff --git a/src/adaptation/NfcAdaptation.cpp b/src/adaptation/NfcAdaptation.cpp
new file mode 100755
index 0000000..d2c527d
--- /dev/null
+++ b/src/adaptation/NfcAdaptation.cpp
@@ -0,0 +1,631 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "NfcAdaptation.h"
+extern "C"
+{
+    #include "gki.h"
+    #include "nfa_api.h"
+    #include "nfc_int.h"
+}
+#include "config.h"
+
+#define LOG_TAG "NfcAdaptation"
+
+extern "C" void GKI_shutdown();
+extern void resetConfig();
+
+NfcAdaptation* NfcAdaptation::mpInstance = NULL;
+ThreadMutex NfcAdaptation::sLock;
+nfc_nci_device_t* NfcAdaptation::mHalDeviceContext = NULL;
+tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
+tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
+
+UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
+UINT8 appl_trace_level = 0xff;
+char bcm_nfc_location[120];
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::NfcAdaptation()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+NfcAdaptation::NfcAdaptation()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::~NfcAdaptation()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+NfcAdaptation::~NfcAdaptation()
+{
+    mpInstance = NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::GetInstance()
+**
+** Description: access class singleton
+**
+** Returns:     pointer to the singleton object
+**
+*******************************************************************************/
+NfcAdaptation& NfcAdaptation::GetInstance()
+{
+    AutoThreadMutex  a(sLock);
+
+    if (!mpInstance)
+        mpInstance = new NfcAdaptation;
+    return *mpInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::Initialize()
+**
+** Description: class initializer
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::Initialize ()
+{
+    const char* func = "NfcAdaptation::Initialize";
+    ALOGD("%s: enter\n", func);
+    unsigned long num;
+
+    if ( !GetStrValue ( NAME_NFA_STORAGE, bcm_nfc_location, sizeof ( bcm_nfc_location ) ) )
+        strcpy ( bcm_nfc_location, "/data/nfc" );
+    if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
+        ScrProtocolTraceFlag = num;
+    initializeGlobalAppLogLevel ();
+
+    GKI_init ();
+    GKI_enable ();
+    GKI_create_task ((TASKPTR)NFCA_TASK, BTU_TASK, (INT8*)"NFCA_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
+    {
+        AutoThreadMutex guard(mCondVar);
+        GKI_create_task ((TASKPTR)Thread, MMI_TASK, (INT8*)"NFCA_THREAD", 0, 0, (pthread_cond_t*)NULL, NULL);
+        mCondVar.wait();
+    }
+
+    mHalDeviceContext = NULL;
+    mHalCallback =  NULL;
+    memset (&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+    InitializeHalDeviceContext ();
+    ALOGD ("%s: exit", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::Finalize()
+**
+** Description: class finalizer
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::Finalize()
+{
+    const char* func = "NfcAdaptation::Finalize";
+    AutoThreadMutex  a(sLock);
+
+    ALOGD ("%s: enter", func);
+    GKI_shutdown ();
+
+    resetConfig();
+
+    nfc_nci_close(mHalDeviceContext); //close the HAL's device context
+    mHalDeviceContext = NULL;
+    mHalCallback = NULL;
+    memset (&mHalEntryFuncs, 0, sizeof(mHalEntryFuncs));
+
+    ALOGD ("%s: exit", func);
+    delete this;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::signal()
+**
+** Description: signal the CondVar to release the thread that is waiting
+**
+** Returns:     none
+**
+*******************************************************************************/
+void NfcAdaptation::signal ()
+{
+    mCondVar.signal();
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::NFCA_TASK()
+**
+** Description: NFCA_TASK runs the GKI main task
+**
+** Returns:     none
+**
+*******************************************************************************/
+UINT32 NfcAdaptation::NFCA_TASK (UINT32 arg)
+{
+    const char* func = "NfcAdaptation::NFCA_TASK";
+    ALOGD ("%s: enter", func);
+    GKI_run (0);
+    ALOGD ("%s: exit", func);
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::Thread()
+**
+** Description: Creates work threads
+**
+** Returns:     none
+**
+*******************************************************************************/
+UINT32 NfcAdaptation::Thread (UINT32 arg)
+{
+    const char* func = "NfcAdaptation::Thread";
+    unsigned long num;
+    char temp[120];
+    ALOGD ("%s: enter", func);
+
+    {
+        ThreadCondVar    CondVar;
+        AutoThreadMutex  guard(CondVar);
+        GKI_create_task ((TASKPTR)nfc_task, NFC_TASK, (INT8*)"NFC_TASK", 0, 0, (pthread_cond_t*)CondVar, (pthread_mutex_t*)CondVar);
+        CondVar.wait();
+    }
+
+    NfcAdaptation::GetInstance().signal();
+
+    GKI_exit_task (GKI_get_taskid ());
+    ALOGD ("%s: exit", func);
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::GetHalEntryFuncs()
+**
+** Description: Get the set of HAL entry points.
+**
+** Returns:     Functions pointers for HAL entry points.
+**
+*******************************************************************************/
+tHAL_NFC_ENTRY* NfcAdaptation::GetHalEntryFuncs ()
+{
+    return &mHalEntryFuncs;
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::InitializeHalDeviceContext
+**
+** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::InitializeHalDeviceContext ()
+{
+    const char* func = "NfcAdaptation::InitializeHalDeviceContext";
+    ALOGD ("%s: enter", func);
+    int ret = 0; //0 means success
+    const hw_module_t* hw_module = NULL;
+
+    mHalEntryFuncs.initialize = HalInitialize;
+    mHalEntryFuncs.terminate = HalTerminate;
+    mHalEntryFuncs.open = HalOpen;
+    mHalEntryFuncs.close = HalClose;
+    mHalEntryFuncs.core_initialized = HalCoreInitialized;
+    mHalEntryFuncs.write = HalWrite;
+    mHalEntryFuncs.prediscover = HalPrediscover;
+    mHalEntryFuncs.control_granted = HalControlGranted;
+    mHalEntryFuncs.power_cycle = HalPowerCycle;
+
+    ret = hw_get_module (NFC_NCI_HARDWARE_MODULE_ID, &hw_module);
+    if (ret == 0)
+    {
+        ret = nfc_nci_open (hw_module, &mHalDeviceContext);
+        if (ret != 0)
+            ALOGE ("%s: nfc_nci_open fail", func);
+    }
+    else
+        ALOGE ("%s: fail hw_get_module", func);
+    ALOGD ("%s: exit", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalInitialize
+**
+** Description: Not implemented because this function is only needed
+**              within the HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalInitialize ()
+{
+    const char* func = "NfcAdaptation::HalInitialize";
+    ALOGD ("%s", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalTerminate
+**
+** Description: Not implemented because this function is only needed
+**              within the HAL.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalTerminate ()
+{
+    const char* func = "NfcAdaptation::HalTerminate";
+    ALOGD ("%s", func);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalOpen
+**
+** Description: Turn on controller, download firmware.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK* p_data_cback)
+{
+    const char* func = "NfcAdaptation::HalOpen";
+    ALOGD ("%s", func);
+    if (mHalDeviceContext)
+    {
+        mHalCallback = p_hal_cback;
+        mHalDataCallback = p_data_cback;
+        mHalDeviceContext->open (mHalDeviceContext, HalDeviceContextCallback, HalDeviceContextDataCallback);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalClose
+**
+** Description: Turn off controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalClose ()
+{
+    const char* func = "NfcAdaptation::HalClose";
+    ALOGD ("%s", func);
+    if (mHalDeviceContext)
+    {
+        mHalDeviceContext->close (mHalDeviceContext);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalDeviceContextCallback
+**
+** Description: Translate generic Android HAL's callback into Broadcom-specific
+**              callback function.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDeviceContextCallback (nfc_event_t event, nfc_status_t event_status)
+{
+    const char* func = "NfcAdaptation::HalDeviceContextCallback";
+    ALOGD ("%s: event=%u", func, event);
+    if (mHalCallback)
+        mHalCallback (event, (tHAL_NFC_STATUS) event_status);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalDeviceContextDataCallback
+**
+** Description: Translate generic Android HAL's callback into Broadcom-specific
+**              callback function.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalDeviceContextDataCallback (uint16_t data_len, uint8_t* p_data)
+{
+    const char* func = "NfcAdaptation::HalDeviceContextDataCallback";
+    ALOGD ("%s: len=%u", func, data_len);
+    if (mHalDataCallback)
+        mHalDataCallback (data_len, p_data);
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalWrite
+**
+** Description: Write NCI message to the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalWrite (UINT16 data_len, UINT8* p_data)
+{
+    const char* func = "NfcAdaptation::HalWrite";
+    ALOGD ("%s", func);
+    if (mHalDeviceContext)
+    {
+        mHalDeviceContext->write (mHalDeviceContext, data_len, p_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalCoreInitialized
+**
+** Description: Adjust the configurable parameters in the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalCoreInitialized (UINT8* p_core_init_rsp_params)
+{
+    const char* func = "NfcAdaptation::HalCoreInitialized";
+    ALOGD ("%s", func);
+    if (mHalDeviceContext)
+    {
+        mHalDeviceContext->core_initialized (mHalDeviceContext, p_core_init_rsp_params);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalPrediscover
+**
+** Description:     Perform any vendor-specific pre-discovery actions (if needed)
+**                  If any actions were performed TRUE will be returned, and
+**                  HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
+**                  completed.
+**
+** Returns:          TRUE if vendor-specific pre-discovery actions initialized
+**                  FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+BOOLEAN NfcAdaptation::HalPrediscover ()
+{
+    const char* func = "NfcAdaptation::HalPrediscover";
+    ALOGD ("%s", func);
+    BOOLEAN retval = FALSE;
+
+    if (mHalDeviceContext)
+    {
+        mHalDeviceContext->pre_discover (mHalDeviceContext);
+    }
+    return retval;
+}
+
+/*******************************************************************************
+**
+** Function:        HAL_NfcControlGranted
+**
+** Description:     Grant control to HAL control for sending NCI commands.
+**                  Call in response to HAL_REQUEST_CONTROL_EVT.
+**                  Must only be called when there are no NCI commands pending.
+**                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
+**                  needs control of NCI.
+**
+** Returns:         void
+**
+*******************************************************************************/
+void NfcAdaptation::HalControlGranted ()
+{
+    const char* func = "NfcAdaptation::HalControlGranted";
+    ALOGD ("%s", func);
+    if (mHalDeviceContext)
+    {
+        mHalDeviceContext->control_granted (mHalDeviceContext);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    NfcAdaptation::HalPowerCycle
+**
+** Description: Turn off and turn on the controller.
+**
+** Returns:     None.
+**
+*******************************************************************************/
+void NfcAdaptation::HalPowerCycle ()
+{
+    const char* func = "NfcAdaptation::HalPowerCycle";
+    ALOGD ("%s", func);
+    if (mHalDeviceContext)
+    {
+        mHalDeviceContext->power_cycle (mHalDeviceContext);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::ThreadMutex()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadMutex::ThreadMutex()
+{
+    pthread_mutexattr_t mutexAttr;
+
+    pthread_mutexattr_init(&mutexAttr);
+    pthread_mutex_init(&mMutex, &mutexAttr);
+    pthread_mutexattr_destroy(&mutexAttr);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::~ThreadMutex()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadMutex::~ThreadMutex()
+{
+    pthread_mutex_destroy(&mMutex);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::lock()
+**
+** Description: lock kthe mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadMutex::lock()
+{
+    pthread_mutex_lock(&mMutex);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadMutex::unblock()
+**
+** Description: unlock the mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadMutex::unlock()
+{
+    pthread_mutex_unlock(&mMutex);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::ThreadCondVar()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadCondVar::ThreadCondVar()
+{
+    pthread_condattr_t CondAttr;
+
+    pthread_condattr_init(&CondAttr);
+    pthread_cond_init(&mCondVar, &CondAttr);
+
+    pthread_condattr_destroy(&CondAttr);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::~ThreadCondVar()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+ThreadCondVar::~ThreadCondVar()
+{
+    pthread_cond_destroy(&mCondVar);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::wait()
+**
+** Description: wait on the mCondVar
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadCondVar::wait()
+{
+    pthread_cond_wait(&mCondVar, *this);
+    pthread_mutex_unlock(*this);
+}
+
+/*******************************************************************************
+**
+** Function:    ThreadCondVar::signal()
+**
+** Description: signal the mCondVar
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ThreadCondVar::signal()
+{
+    AutoThreadMutex  a(*this);
+    pthread_cond_signal(&mCondVar);
+}
+
+/*******************************************************************************
+**
+** Function:    AutoThreadMutex::AutoThreadMutex()
+**
+** Description: class constructor, automatically lock the mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+AutoThreadMutex::AutoThreadMutex(ThreadMutex &m)
+    : mm(m)
+{
+    mm.lock();
+}
+
+/*******************************************************************************
+**
+** Function:    AutoThreadMutex::~AutoThreadMutex()
+**
+** Description: class destructor, automatically unlock the mutex
+**
+** Returns:     none
+**
+*******************************************************************************/
+AutoThreadMutex::~AutoThreadMutex()
+{
+    mm.unlock();
+}
diff --git a/src/adaptation/OverrideLog.cpp b/src/adaptation/OverrideLog.cpp
new file mode 100644
index 0000000..1dda4c2
--- /dev/null
+++ b/src/adaptation/OverrideLog.cpp
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the ALOGD(), ALOGE(), and other logging macros from
+ *  /system/core/include/cutils/log.h
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include <cutils/properties.h>
+#include "config.h"
+#define LOG_TAG "BrcmNfcJni"
+
+
+/*******************************************************************************
+**
+** Function:        initializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from .conf or
+**                  Android property nfc.app_log_level.  The Android property
+**                  overrides .conf variable.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3        * API traces
+**                  BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char initializeGlobalAppLogLevel ()
+{
+    unsigned long num = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    GetNumValue (NAME_APPL_TRACE_LEVEL, &num, sizeof(num));
+    appl_trace_level = (unsigned char) num;
+
+    int len = property_get ("nfc.app_log_level", valueStr, "");
+    if (len > 0)
+    {
+        //let Android property override .conf variable
+        sscanf (valueStr, "%lu", &num);
+        appl_trace_level = (unsigned char) num;
+    }
+
+    //0xFF is a special value used by the stack to query the current
+    //trace level; it does not change any trace level
+    if (appl_trace_level == 0xFF)
+        appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+    ALOGD ("%s: level=%u", __FUNCTION__, appl_trace_level);
+    return appl_trace_level;
+}
diff --git a/src/adaptation/android_logmsg.cpp b/src/adaptation/android_logmsg.cpp
new file mode 100644
index 0000000..acede64
--- /dev/null
+++ b/src/adaptation/android_logmsg.cpp
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "buildcfg.h"
+#include "bt_types.h"
+#include <cutils/log.h>
+
+
+#ifndef BTE_LOG_BUF_SIZE
+    #define BTE_LOG_BUF_SIZE  1024
+#endif
+#define BTE_LOG_MAX_SIZE  (BTE_LOG_BUF_SIZE - 12)
+
+
+extern "C"
+{
+    void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+}
+
+/*******************************************************************************
+**
+** Function:    ScrLog
+**
+** Description: log a message
+**
+** Returns:     none
+**
+*******************************************************************************/
+void ScrLog (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+    static char buffer[BTE_LOG_BUF_SIZE];
+    va_list ap;
+
+    va_start(ap, fmt_str);
+    vsnprintf(buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+    va_end(ap);
+    __android_log_write(ANDROID_LOG_INFO, "BrcmNci", buffer);
+}
+
+
+/*******************************************************************************
+**
+** Function:    LogMsg
+**
+** Description: log a message
+**
+** Returns:     none
+**
+*******************************************************************************/
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+    static char buffer[BTE_LOG_BUF_SIZE];
+    va_list ap;
+    UINT32 trace_type = trace_set_mask & 0x07; //lower 3 bits contain trace type
+    int android_log_type = ANDROID_LOG_INFO;
+
+    va_start(ap, fmt_str);
+    vsnprintf(buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+    va_end(ap);
+    if (trace_type == TRACE_TYPE_ERROR)
+        android_log_type = ANDROID_LOG_ERROR;
+    __android_log_write(android_log_type, "BrcmNfcNfa", buffer);
+}
+
diff --git a/src/adaptation/bte_logmsg.c b/src/adaptation/bte_logmsg.c
new file mode 100644
index 0000000..c147f28
--- /dev/null
+++ b/src/adaptation/bte_logmsg.c
@@ -0,0 +1,412 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <sys/time.h>
+#include "bt_target.h"
+#include "gki.h"
+
+#define BT_USE_TRACES   TRUE
+
+#if MMI_INCLUDED == TRUE
+#include "mmi.h"
+#endif
+
+volatile UINT8 bte_target_mode;
+
+#if BT_USE_TRACES == TRUE
+
+#ifdef __CYGWIN__
+#undef RPC_INCLUDED
+#define RPC_INCLUDED TRUE
+
+/*******************************************************************************
+**
+** Function:    LogMsg
+**
+** Description: log a message
+**
+** Returns:     none
+**
+*******************************************************************************/
+void
+LogMsg(UINT32 maskTraceSet, const char *strFormat, ...)
+{
+    va_list ap;
+    char buffer[256];
+    struct timeval tv;
+    struct timezone tz;
+    struct tm *tm;
+    time_t t;
+
+
+    gettimeofday(&tv, &tz);
+    time(&t);
+    tm = localtime(&t);
+
+    sprintf(buffer, "%02d:%02d:%02d.%03d ", tm->tm_hour, tm->tm_min, tm->tm_sec,
+        tv.tv_usec / 1000);
+    pth_write(2, buffer, strlen(buffer));
+
+    va_start(ap, strFormat);
+    vsprintf(buffer, strFormat, ap);
+    pth_write(2, buffer, strlen(buffer));
+    pth_write(2, "\n", 1);
+    va_end(ap);
+}
+
+/*******************************************************************************
+**
+** Function:    ScrLog
+**
+** Description: log a message
+**
+** Returns:     none
+**
+*******************************************************************************/
+void
+ScrLog(UINT32 maskTraceSet, const char *strFormat, ...)
+{
+    va_list ap;
+    char buffer[256];
+    struct timeval tv;
+    struct timezone tz;
+    struct tm *tm;
+    time_t t;
+
+    gettimeofday(&tv, &tz);
+    time(&t);
+    tm = localtime(&t);
+
+    sprintf(buffer, "%02d:%02d:%02d.%03d ", tm->tm_hour, tm->tm_min, tm->tm_sec,
+        tv.tv_usec / 1000);
+    pth_write(2, buffer, strlen(buffer));
+
+    va_start(ap, strFormat);
+    vsprintf(buffer, strFormat, ap);
+    pth_write(2, buffer, strlen(buffer));
+    pth_write(2, "\n", 1);
+    va_end(ap);
+}
+#endif
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_0
+**
+**    Purpose:  Encodes a trace message that has no parameter arguments
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_0 (UINT32 maskTraceSet, const char *strFormat)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg(maskTraceSet, strFormat);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg(maskTraceSet, strFormat);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat);
+#endif
+    }
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg(maskTraceSet, strFormat);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat);
+#endif
+
+
+}
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_1
+**
+**    Purpose:  Encodes a trace message that has one parameter argument
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_1 (UINT32 maskTraceSet, const char *strFormat, UINT32 p1)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat, p1);
+#endif
+    }
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg (maskTraceSet, strFormat, p1);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat, p1);
+#endif
+}
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_2
+**
+**    Purpose:  Encodes a trace message that has two parameter arguments
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_2 (UINT32 maskTraceSet, const char *strFormat, UINT32 p1, UINT32 p2)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat, p1, p2);
+#endif
+    }
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg (maskTraceSet, strFormat, p1, p2);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat, p1, p2);
+#endif
+}
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_3
+**
+**    Purpose:  Encodes a trace message that has three parameter arguments
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_3 (UINT32 maskTraceSet, const char *strFormat, UINT32 p1, UINT32 p2, UINT32 p3)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat, p1, p2, p3);
+#endif
+    }
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg (maskTraceSet, strFormat, p1, p2, p3);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat, p1, p2, p3);
+#endif
+}
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_4
+**
+**    Purpose:  Encodes a trace message that has four parameter arguments
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_4 (UINT32 maskTraceSet, const char *strFormat, UINT32 p1, UINT32 p2,
+               UINT32 p3, UINT32 p4)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat, p1, p2, p3, p4);
+#endif
+    }
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat, p1, p2, p3, p4);
+#endif
+}
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_5
+**
+**    Purpose:  Encodes a trace message that has five parameter arguments
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_5 (UINT32 maskTraceSet, const char *strFormat, UINT32 p1, UINT32 p2,
+               UINT32 p3, UINT32 p4, UINT32 p5)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4, p5);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4, p5);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat, p1, p2, p3, p4, p5);
+#endif
+    }
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4, p5);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat, p1, p2, p3, p4, p5);
+#endif
+}
+
+/********************************************************************************
+**
+**    Function Name:   LogMsg_6
+**
+**    Purpose:  Encodes a trace message that has six parameter arguments
+**
+**    Input Parameters:  maskTraceSet: tester trace type.
+**                       strFormat: displayable string.
+**    Returns:
+**                      Nothing.
+**
+*********************************************************************************/
+void LogMsg_6 (UINT32 maskTraceSet, const char *strFormat, UINT32 p1, UINT32 p2,
+               UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6)
+{
+    if (bte_target_mode == BTE_MODE_APPL)
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4, p5, p6);
+#else
+        return; /* No RPC */
+#endif
+    }
+    else if (bte_target_mode == BTE_MODE_SAMPLE_APPS)  /* Using demo sample apps */
+    {
+#if RPC_INCLUDED == TRUE
+        LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4, p5, p6);
+#elif MMI_INCLUDED == TRUE
+        if (mmi_debug_traces)
+            MMI_Echo(strFormat, p1, p2, p3, p4, p5, p6);
+#endif
+    }
+
+
+#if (defined(TRACE_TASK_INCLUDED) && TRACE_TASK_INCLUDED == TRUE)
+    LogMsg (maskTraceSet, strFormat, p1, p2, p3, p4, p5, p6);
+#endif
+
+#if (defined(DONGLE_MODE_INCLUDED) && DONGLE_MODE_INCLUDED == TRUE)
+    else if (bte_target_mode == BTE_MODE_DONGLE)
+        bte_hcisl_send_traces(maskTraceSet, strFormat, p1, p2, p3, p4, p5, p6);
+#endif
+
+}
+
+#endif /* BT_USE_TRACES */
+
diff --git a/src/adaptation/config.cpp b/src/adaptation/config.cpp
new file mode 100755
index 0000000..c7cce1d
--- /dev/null
+++ b/src/adaptation/config.cpp
@@ -0,0 +1,751 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+
+#define LOG_TAG "NfcAdaptation"
+
+#if GENERIC_TARGET
+const char alternative_config_path[] = "/data/nfc/";
+#else
+const char alternative_config_path[] = "";
+#endif
+
+const char transport_config_path[] = "/etc/";
+
+#define config_name             "libnfc-brcm.conf"
+#define extra_config_base       "libnfc-brcm-"
+#define extra_config_ext        ".conf"
+#define     IsStringValue       0x80000000
+
+using namespace::std;
+
+class CNfcParam : public string
+{
+public:
+    CNfcParam();
+    CNfcParam(const char* name, const string& value);
+    CNfcParam(const char* name, unsigned long value);
+    virtual ~CNfcParam();
+    unsigned long numValue() const {return m_numValue;}
+    const char*   str_value() const {return m_str_value.c_str();}
+    size_t        str_len() const   {return m_str_value.length();}
+private:
+    string          m_str_value;
+    unsigned long   m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*>
+{
+public:
+    virtual ~CNfcConfig();
+    static CNfcConfig& GetInstance();
+    friend void readOptionalConfig(const char* optional);
+
+    bool    getValue(const char* name, char* pValue, size_t len) const;
+    bool    getValue(const char* name, unsigned long& rValue) const;
+    bool    getValue(const char* name, unsigned short & rValue) const;
+    const CNfcParam*    find(const char* p_name) const;
+    void    clean();
+private:
+    CNfcConfig();
+    bool    readConfig(const char* name, bool bResetContent);
+    void    moveFromList();
+    void    moveToList();
+    void    add(const CNfcParam* pParam);
+    list<const CNfcParam*> m_list;
+    bool    mValidFile;
+
+    unsigned long   state;
+
+    inline bool Is(unsigned long f) {return (state & f) == f;}
+    inline void Set(unsigned long f) {state |= f;}
+    inline void Reset(unsigned long f) {state &= ~f;}
+};
+
+/*******************************************************************************
+**
+** Function:    isPrintable()
+**
+** Description: detremine if a char is printable
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isPrintable(char c)
+{
+    return  (c >= 'A' && c <= 'Z') ||
+            (c >= 'a' && c <= 'z') ||
+            (c >= '0' && c <= '9') ||
+            c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function:    isDigit()
+**
+** Description: detremine if a char is numeral digit
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return true;
+    if (base == 16)
+    {
+        if (('A' <= c && c <= 'F') ||
+            ('a' <= c && c <= 'f') )
+            return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    getDigitValue()
+**
+** Description: return numercal value of a char
+**
+** Returns:     none
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return c - '0';
+    if (base == 16)
+    {
+        if ('A' <= c && c <= 'F')
+            return c - 'A' + 10;
+        else if ('a' <= c && c <= 'f')
+            return c - 'a' + 10;
+    }
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+**              move the element from linked list to a array at the end
+**
+** Returns:     none
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent)
+{
+    enum {
+        BEGIN_LINE = 1,
+        TOKEN,
+        STR_VALUE,
+        NUM_VALUE,
+        BEGIN_HEX,
+        BEGIN_QUOTE,
+        END_LINE
+    };
+
+    FILE*   fd;
+    string  token;
+    string  strValue;
+    unsigned long    numValue = 0;
+    CNfcParam* pParam = NULL;
+    int     i;
+    int     base;
+    char    c;
+
+    state = BEGIN_LINE;
+    /* open config file, read it into a buffer */
+    if ((fd = fopen(name, "rb")) == NULL)
+    {
+        ALOGD("%s Cannot open config file %s\n", __func__, name);
+        if (bResetContent)
+        {
+            ALOGD("%s Using default value for all settings\n", __func__);
+        mValidFile = false;
+        }
+        return false;
+    }
+    ALOGD("%s Opened %s config %s\n", __func__, (bResetContent ? "base" : "optional"), name);
+
+    mValidFile = true;
+    if (size() > 0)
+    {
+        if (bResetContent)
+        clean();
+        else
+            moveToList();
+    }
+
+    while (!feof(fd) && fread(&c, 1, 1, fd) == 1)
+    {
+        switch (state & 0xff)
+        {
+        case BEGIN_LINE:
+            if (c == '#')
+                state = END_LINE;
+            else if (isPrintable(c))
+            {
+                i = 0;
+                token.erase();
+                strValue.erase();
+                state = TOKEN;
+                token.push_back(c);
+            }
+            break;
+        case TOKEN:
+            if (c == '=')
+            {
+                token.push_back('\0');
+                state = BEGIN_QUOTE;
+            }
+            else if (isPrintable(c))
+                token.push_back(c);
+            else
+                state = END_LINE;
+            break;
+        case BEGIN_QUOTE:
+            if (c == '"')
+            {
+                state = STR_VALUE;
+                base = 0;
+            }
+            else if (c == '0')
+                state = BEGIN_HEX;
+            else if (isDigit(c, 10))
+            {
+                state = NUM_VALUE;
+                base = 10;
+                numValue = getDigitValue(c, base);
+                i = 0;
+            }
+            else if (c == '{')
+            {
+                state = NUM_VALUE;
+                base = 16;
+                i = 0;
+                Set(IsStringValue);
+            }
+            else
+                state = END_LINE;
+            break;
+        case BEGIN_HEX:
+            if (c == 'x' || c == 'X')
+            {
+                state = NUM_VALUE;
+                base = 16;
+                numValue = 0;
+                i = 0;
+                break;
+            }
+            else if (isDigit(c, 10))
+            {
+                state = NUM_VALUE;
+                base = 10;
+                numValue = getDigitValue(c, base);
+                break;
+            }
+            else if (c != '\n' && c != '\r')
+            {
+                state = END_LINE;
+                break;
+            }
+            // fal through to numValue to handle numValue
+
+        case NUM_VALUE:
+            if (isDigit(c, base))
+            {
+                numValue *= base;
+                numValue += getDigitValue(c, base);
+                ++i;
+            }
+            else if (base == 16 && (c == ':' || c == '-' || c == ' ' || c == '}'))
+            {
+                if (i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                    {
+                        unsigned char c = (numValue >> (n * 8))  & 0xFF;
+                        strValue.push_back(c);
+                    }
+                }
+                Set(IsStringValue);
+                numValue = 0;
+                i = 0;
+            }
+            else
+            {
+                if (c == '\n' || c == '\r')
+                    state = BEGIN_LINE;
+                else
+                    state = END_LINE;
+                if (Is(IsStringValue) && base == 16 && i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                        strValue.push_back(((numValue >> (n * 8))  & 0xFF));
+                }
+                if (strValue.length() > 0)
+                    pParam = new CNfcParam(token.c_str(), strValue);
+                else
+                    pParam = new CNfcParam(token.c_str(), numValue);
+                add(pParam);
+                strValue.erase();
+                numValue = 0;
+            }
+            break;
+        case STR_VALUE:
+            if (c == '"')
+            {
+                strValue.push_back('\0');
+                state = END_LINE;
+                pParam = new CNfcParam(token.c_str(), strValue);
+                add(pParam);
+            }
+            else if (isPrintable(c))
+                strValue.push_back(c);
+            break;
+        case END_LINE:
+            if (c == '\n' || c == '\r')
+                state = BEGIN_LINE;
+            break;
+        default:
+            break;
+        }
+    }
+
+    fclose(fd);
+
+    moveFromList();
+    return size() > 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::CNfcConfig()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::CNfcConfig() :
+    mValidFile(true)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance()
+{
+    static CNfcConfig theInstance;
+
+    if (theInstance.size() == 0 && theInstance.mValidFile)
+    {
+        string strPath;
+        if (alternative_config_path[0] != '\0')
+        {
+            strPath.assign(alternative_config_path);
+            strPath += config_name;
+            theInstance.readConfig(strPath.c_str(), true);
+            if (!theInstance.empty())
+            {
+                return theInstance;
+        }
+        }
+        strPath.assign(transport_config_path);
+        strPath += config_name;
+        theInstance.readConfig(strPath.c_str(), true);
+    }
+
+    return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() > 0)
+    {
+        memset(pValue, 0, len);
+        memcpy(pValue, pParam->str_value(), pParam->str_len());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a long numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() == 0)
+    {
+        rValue = static_cast<unsigned long>(pParam->numValue());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a short numerical value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() == 0)
+    {
+        rValue = static_cast<unsigned short>(pParam->numValue());
+        return true;
+    }
+    return false;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::find()
+**
+** Description: search if a setting exist in the setting array
+**
+** Returns:     pointer to the setting object
+**
+*******************************************************************************/
+const CNfcParam* CNfcConfig::find(const char* p_name) const
+{
+    if (size() == 0)
+        return NULL;
+
+    for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+    {
+        if (**it < p_name)
+            continue;
+        else if (**it == p_name)
+        {
+            if((*it)->str_len() > 0)
+                ALOGD("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+            else
+                ALOGD("%s found %s=(0x%X)\n", __func__, p_name, (*it)->numValue());
+            return *it;
+        }
+        else
+            break;
+    }
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::clean()
+**
+** Description: reset the setting array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::clean()
+{
+    if (size() == 0)
+        return;
+
+    for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+        delete *it;
+    clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::Add()
+**
+** Description: add a setting object to the list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::add(const CNfcParam* pParam)
+{
+    if (m_list.size() == 0)
+    {
+        m_list.push_back(pParam);
+        return;
+    }
+    for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+    {
+        if (**it < pParam->c_str())
+            continue;
+        m_list.insert(it, pParam);
+        return;
+    }
+    m_list.push_back(pParam);
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList()
+{
+    if (m_list.size() == 0)
+        return;
+
+    for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+        push_back(*it);
+    m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns:     none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList()
+{
+    if (m_list.size() != 0)
+        m_list.clear();
+
+    for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+        m_list.push_back(*it);
+    clear();
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam() :
+    m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::~CNfcParam()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::~CNfcParam()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name,  const string& value) :
+    string(name),
+    m_str_value(value),
+    m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name,  unsigned long value) :
+    string(name),
+    m_numValue(value)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    GetStrValue
+**
+** Description: API function for getting a string value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetStrValue(const char* name, char* pValue, unsigned long len)
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    return rConfig.getValue(name, pValue, len);
+}
+
+/*******************************************************************************
+**
+** Function:    GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" int GetNumValue(const char* name, void* pValue, unsigned long len)
+{
+    if (!pValue)
+        return false;
+
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+    const CNfcParam* pParam = rConfig.find(name);
+
+    if (pParam == NULL)
+        return false;
+    unsigned long v = pParam->numValue();
+    if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4)
+    {
+        const unsigned char* p = (const unsigned char*)pParam->str_value();
+        for (int i = 0 ; i < pParam->str_len(); ++i)
+        {
+            v *= 256;
+            v += *p++;
+        }
+    }
+    switch (len)
+    {
+    case sizeof(unsigned long):
+        *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+        break;
+    case sizeof(unsigned short):
+        *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+        break;
+    case sizeof(unsigned char):
+        *(static_cast<unsigned char*> (pValue)) = (unsigned char)v;
+        break;
+    default:
+        return false;
+    }
+    return true;
+}
+
+/*******************************************************************************
+**
+** Function:    resetConfig
+**
+** Description: reset settings array
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern void resetConfig()
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function:    readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra)
+{
+    string strPath;
+    strPath.assign(transport_config_path);
+    if (alternative_config_path[0] != '\0')
+        strPath.assign(alternative_config_path);
+
+    strPath += extra_config_base;
+    strPath += extra;
+    strPath += extra_config_ext;
+    CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
diff --git a/src/adaptation/libmain.c b/src/adaptation/libmain.c
new file mode 100755
index 0000000..ad3f6ec
--- /dev/null
+++ b/src/adaptation/libmain.c
@@ -0,0 +1,512 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "buildcfg.h"
+#include "nfa_mem_co.h"
+#include "nfa_nv_co.h"
+#include "nfa_nv_ci.h"
+#include "config.h"
+
+#define LOG_TAG "BrcmNfcNfa"
+#define PRINT(s) __android_log_write(ANDROID_LOG_DEBUG, "BrcmNci", s)
+#define MAX_NCI_PACKET_SIZE  259
+#define MAX_LOGCAT_LINE     4096
+static char log_line[MAX_LOGCAT_LINE];
+
+extern UINT32 ScrProtocolTraceFlag;         // = SCR_PROTO_TRACE_ALL; // 0x017F;
+static const char* sTable = "0123456789abcdef";
+extern char bcm_nfc_location[];
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_alloc
+**
+** Description      allocate a buffer from platform's memory pool
+**
+** Returns:
+**                  pointer to buffer if successful
+**                  NULL otherwise
+**
+*******************************************************************************/
+NFC_API extern void *nfa_mem_co_alloc(UINT32 num_bytes)
+{
+    return malloc(num_bytes);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_free
+**
+** Description      free buffer previously allocated using nfa_mem_co_alloc
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+NFC_API extern void nfa_mem_co_free(void *pBuffer)
+{
+    free(pBuffer);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       pBuffer   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read() is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been read, the end of file has been detected,
+**                        or an error has occurred.
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_co_read(UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
+{
+    char filename[256], filename2[256];
+    strcpy(filename2, bcm_nfc_location);
+    strcat(filename2, "/nfaStorage.bin");
+    if (strlen(filename2) > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    sprintf (filename, "%s%u", filename2, block);
+
+    ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
+    int fileStream = open (filename, O_RDONLY);
+    if (fileStream > 0)
+    {
+        size_t actualRead = read (fileStream, pBuffer, nbytes);
+        if (actualRead > 0)
+        {
+            ALOGD ("%s: read bytes=%u", __FUNCTION__, actualRead);
+            nfa_nv_ci_read (actualRead, NFA_NV_CO_OK, block);
+        }
+        else
+        {
+            ALOGE ("%s: fail to read", __FUNCTION__);
+            nfa_nv_ci_read (actualRead, NFA_NV_CO_FAIL, block);
+        }
+        close (fileStream);
+    }
+    else
+    {
+        ALOGE ("%s: fail to open", __FUNCTION__);
+        nfa_nv_ci_read (0, NFA_NV_CO_FAIL, block);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       pBuffer   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write() is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_co_write(const UINT8 *pBuffer, UINT16 nbytes, UINT8 block)
+{
+    char filename[256], filename2[256];
+    strcpy(filename2, bcm_nfc_location);
+    strcat(filename2, "/nfaStorage.bin");
+    if (strlen(filename2) > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    sprintf (filename, "%s%u", filename2, block);
+    ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
+
+    int fileStream = 0;
+
+    fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+    if (fileStream > 0)
+    {
+        size_t actualWritten = write (fileStream, pBuffer, nbytes);
+        ALOGD ("%s: %d bytes written", __FUNCTION__, actualWritten);
+        if (actualWritten > 0) {
+            nfa_nv_ci_write (NFA_NV_CO_OK);
+        }
+        else
+        {
+            ALOGE ("%s: fail to write", __FUNCTION__);
+            nfa_nv_ci_write (NFA_NV_CO_FAIL);
+        }
+        close (fileStream);
+    }
+    else
+    {
+        ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
+        nfa_nv_ci_write (NFA_NV_CO_FAIL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         byte2hex
+**
+** Description      convert a byte array to hexadecimal string
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+static inline void byte2hex(const char* data, char** str)
+{
+    **str = sTable[(*data >> 4) & 0xf];
+    ++*str;
+    **str = sTable[*data & 0xf];
+    ++*str;
+}
+
+/*******************************************************************************
+**
+** Function         byte2char
+**
+** Description      convert a byte array to displayable text string
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+static inline void byte2char(const char* data, char** str)
+{
+    **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
+    ++(*str);
+}
+
+/*******************************************************************************
+**
+** Function         word2hex
+**
+** Description      Convert a two byte into text string as little-endian WORD
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+static inline void word2hex(const char* data, char** hex)
+{
+    byte2hex(&data[1], hex);
+    byte2hex(&data[0], hex);
+}
+
+/*******************************************************************************
+**
+** Function         dumpbin
+**
+** Description      convert a byte array to a blob of text string for logging
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+void dumpbin(const char* data, int size, UINT32 trace_layer, UINT32 trace_type)
+{
+    char line_buff[256];
+    char *line;
+    int i, j, addr;
+    const int width = 16;
+    if(size <= 0)
+        return;
+#ifdef __RAW_HEADER
+    //write offset
+    line = line_buff;
+    *line++ = ' ';
+    *line++ = ' ';
+    *line++ = ' ';
+    *line++ = ' ';
+    *line++ = ' ';
+    *line++ = ' ';
+    for(j = 0; j < width; j++)
+    {
+        byte2hex((const char*)&j, &line);
+        *line++ = ' ';
+    }
+    *line = 0;
+    PRINT(line_buff);
+#endif
+    for(i = 0; i < size / width; i++)
+    {
+        line = line_buff;
+        //write address:
+        addr = i*width;
+        word2hex((const char*)&addr, &line);
+        *line++ = ':'; *line++ = ' ';
+        //write hex of data
+        for(j = 0; j < width; j++)
+        {
+            byte2hex(&data[j], &line);
+            *line++ = ' ';
+        }
+        //write char of data
+        for(j = 0; j < width; j++)
+            byte2char(data++, &line);
+        //wirte the end of line
+        *line = 0;
+        //output the line
+        PRINT(line_buff);
+    }
+    //last line of left over if any
+    int leftover = size % width;
+    if(leftover > 0)
+    {
+        line = line_buff;
+        //write address:
+        addr = i*width;
+        word2hex((const char*)&addr, &line);
+        *line++ = ':'; *line++ = ' ';
+        //write hex of data
+        for(j = 0; j < leftover; j++)
+        {
+            byte2hex(&data[j], &line);
+            *line++ = ' ';
+        }
+        //write hex padding
+        for(; j < width; j++)
+        {
+            *line++ = ' ';
+            *line++ = ' ';
+            *line++ = ' ';
+        }
+        //write char of data
+        for(j = 0; j < leftover; j++)
+            byte2char(data++, &line);
+        //write the end of line
+        *line = 0;
+        //output the line
+        PRINT(line_buff);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         scru_dump_hex
+**
+** Description      print a text string to log
+**
+** Returns:
+**                  text string
+**
+*******************************************************************************/
+UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
+{
+    if(pTitle && *pTitle)
+        PRINT(pTitle);
+    dumpbin(p, len, layer, type);
+    return p;
+}
+
+/*******************************************************************************
+**
+** Function         DispHciCmd
+**
+** Description      Display a HCI command string
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+void DispHciCmd (BT_HDR *p_buf)
+{
+    int i,j;
+    int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+    UINT8 * data = (UINT8*) p_buf;
+    int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+        return;
+
+    if (nBytes > sizeof(log_line))
+        return;
+
+    for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
+    {
+        log_line[j++] = sTable[(*data >> 4) & 0xf];
+        log_line[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    log_line[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
+}
+
+
+/*******************************************************************************
+**
+** Function         DispHciEvt
+**
+** Description      display a NCI event
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+void DispHciEvt (BT_HDR *p_buf)
+{
+    int i,j;
+    int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+    UINT8 * data = (UINT8*) p_buf;
+    int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+        return;
+
+    if (nBytes > sizeof(log_line))
+        return;
+
+    for(i = 0, j = 0; i < data_len && j < sizeof(log_line)-3; i++)
+    {
+        log_line[j++] = sTable[(*data >> 4) & 0xf];
+        log_line[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    log_line[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
+}
+
+/*******************************************************************************
+**
+** Function         DispNciDump
+**
+** Description      Log raw NCI packet as hex-ascii bytes
+**
+** Returns          None.
+**
+*******************************************************************************/
+void DispNciDump (UINT8 *data, UINT16 len, BOOLEAN is_recv)
+{
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
+        return;
+
+    char line_buf[(MAX_NCI_PACKET_SIZE*2)+1];
+    int i,j;
+
+    for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
+    {
+        line_buf[j++] = sTable[(*data >> 4) & 0xf];
+        line_buf[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    line_buf[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
+}
+
+
+/*******************************************************************************
+**
+** Function         DispLLCP
+**
+** Description      Log raw LLCP packet as hex-ascii bytes
+**
+** Returns          None.
+**
+*******************************************************************************/
+void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv)
+{
+    int i,j;
+    int nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+    UINT8 * data = (UINT8*) p_buf;
+    int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+    if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+        return;
+
+    for (i = 0; i < data_len; )
+    {
+        for(j = 0; i < data_len && j < sizeof(log_line)-3; i++)
+        {
+            log_line[j++] = sTable[(*data >> 4) & 0xf];
+            log_line[j++] = sTable[*data & 0xf];
+            data++;
+        }
+        log_line[j] = '\0';
+        __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmLlcpR": "BrcmLlcpX", log_line);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         DispHcp
+**
+** Description      Log raw HCP packet as hex-ascii bytes
+**
+** Returns          None.
+**
+*******************************************************************************/
+void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv)
+{
+    int i,j;
+    int nBytes = (len*2)+1;
+    char line_buf[400];
+
+    if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+        return;
+
+    if (nBytes > sizeof(line_buf))
+        return;
+
+    // Only trace HCP if we're tracing HCI as well
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+        return;
+
+    for(i = 0, j = 0; i < len && j < sizeof(line_buf)-3; i++)
+    {
+        line_buf[j++] = sTable[(*data >> 4) & 0xf];
+        line_buf[j++] = sTable[*data & 0xf];
+        data++;
+    }
+    line_buf[j] = '\0';
+
+    __android_log_write(ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR": "BrcmHcpX", line_buf);
+}
+
+void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx) {}
+void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx) {}
+void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx) {}
+void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
+void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
+void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond) {}
+void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv) {}
diff --git a/src/gki/common/gki.h b/src/gki/common/gki.h
new file mode 100644
index 0000000..f1539f1
--- /dev/null
+++ b/src/gki/common/gki.h
@@ -0,0 +1,519 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_H
+#define GKI_H
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+/* Include platform-specific over-rides */
+#if (defined(NFC_STANDALONE) && (NFC_STANDALONE == TRUE))
+    #include "gki_target.h"
+#else
+    /* For non-nfc_standalone, include Bluetooth definitions */
+    #include "bt_target.h"
+#endif
+
+
+
+#include "bt_types.h"
+
+/* Uncomment this line for verbose GKI debugging and buffer tracking */
+/*#define GKI_BUFFER_DEBUG   TRUE*/
+
+
+/* Error codes */
+#define GKI_SUCCESS         0x00
+#define GKI_FAILURE         0x01
+#define GKI_INVALID_TASK    0xF0
+#define GKI_INVALID_POOL    0xFF
+
+
+/************************************************************************
+** Mailbox definitions. Each task has 4 mailboxes that are used to
+** send buffers to the task.
+*/
+#define TASK_MBOX_0    0
+#define TASK_MBOX_1    1
+#define TASK_MBOX_2    2
+#define TASK_MBOX_3    3
+
+#define NUM_TASK_MBOX  4
+
+/************************************************************************
+** Event definitions.
+**
+** There are 4 reserved events used to signal messages rcvd in task mailboxes.
+** There are 4 reserved events used to signal timeout events.
+** There are 8 general purpose events available for applications.
+*/
+#define MAX_EVENTS              16
+
+#define TASK_MBOX_0_EVT_MASK   0x0001
+#define TASK_MBOX_1_EVT_MASK   0x0002
+#define TASK_MBOX_2_EVT_MASK   0x0004
+#define TASK_MBOX_3_EVT_MASK   0x0008
+
+
+#define TIMER_0             0
+#define TIMER_1             1
+#define TIMER_2             2
+#define TIMER_3             3
+
+#define TIMER_0_EVT_MASK    0x0010
+#define TIMER_1_EVT_MASK    0x0020
+#define TIMER_2_EVT_MASK    0x0040
+#define TIMER_3_EVT_MASK    0x0080
+
+#define APPL_EVT_0          8
+#define APPL_EVT_1          9
+#define APPL_EVT_2          10
+#define APPL_EVT_3          11
+#define APPL_EVT_4          12
+#define APPL_EVT_5          13
+#define APPL_EVT_6          14
+#define APPL_EVT_7          15
+
+#define EVENT_MASK(evt)       ((UINT16)(0x0001 << (evt)))
+
+/************************************************************************
+**  Max Time Queue
+**/
+#ifndef GKI_MAX_TIMER_QUEUES
+#define GKI_MAX_TIMER_QUEUES    3
+#endif
+
+/************************************************************************
+**  Utility macros for timer conversion
+**/
+#ifdef TICKS_PER_SEC
+#define GKI_MS_TO_TICKS(x)   ((x) / (1000/TICKS_PER_SEC))
+#define GKI_SECS_TO_TICKS(x) ((x) * (TICKS_PER_SEC))
+#define GKI_TICKS_TO_MS(x)   ((x) * (1000/TICKS_PER_SEC))
+#define GKI_TICKS_TO_SECS(x) ((x) * (1/TICKS_PER_SEC))
+#endif
+
+
+/************************************************************************
+**  Macro to determine the pool buffer size based on the GKI POOL ID at compile time.
+**  Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
+*/
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 1)
+
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0                0
+#endif /* ifndef GKI_POOL_ID_0 */
+
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE                0
+#endif /* ifndef GKI_BUF0_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 2)
+
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1                0
+#endif /* ifndef GKI_POOL_ID_1 */
+
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE                0
+#endif /* ifndef GKI_BUF1_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 3)
+
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2                0
+#endif /* ifndef GKI_POOL_ID_2 */
+
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE                0
+#endif /* ifndef GKI_BUF2_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 4)
+
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3                0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE                0
+#endif /* ifndef GKI_BUF3_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 5)
+
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4                0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE                0
+#endif /* ifndef GKI_BUF4_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 6)
+
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5                0
+#endif /* ifndef GKI_POOL_ID_5 */
+
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE                0
+#endif /* ifndef GKI_BUF5_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 7)
+
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6                0
+#endif /* ifndef GKI_POOL_ID_6 */
+
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE                0
+#endif /* ifndef GKI_BUF6_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 8)
+
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7                0
+#endif /* ifndef GKI_POOL_ID_7 */
+
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE                0
+#endif /* ifndef GKI_BUF7_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 9)
+
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8                0
+#endif /* ifndef GKI_POOL_ID_8 */
+
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE                0
+#endif /* ifndef GKI_BUF8_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 10)
+
+#ifndef GKI_POOL_ID_9
+#define GKI_POOL_ID_9                0
+#endif /* ifndef GKI_POOL_ID_9 */
+
+#ifndef GKI_BUF9_SIZE
+#define GKI_BUF9_SIZE                0
+#endif /* ifndef GKI_BUF9_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 11)
+
+#ifndef GKI_POOL_ID_10
+#define GKI_POOL_ID_10                0
+#endif /* ifndef GKI_POOL_ID_10 */
+
+#ifndef GKI_BUF10_SIZE
+#define GKI_BUF10_SIZE                0
+#endif /* ifndef GKI_BUF10_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 12)
+
+#ifndef GKI_POOL_ID_11
+#define GKI_POOL_ID_11                0
+#endif /* ifndef GKI_POOL_ID_11 */
+
+#ifndef GKI_BUF11_SIZE
+#define GKI_BUF11_SIZE                0
+#endif /* ifndef GKI_BUF11_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 13)
+
+#ifndef GKI_POOL_ID_12
+#define GKI_POOL_ID_12                0
+#endif /* ifndef GKI_POOL_ID_12 */
+
+#ifndef GKI_BUF12_SIZE
+#define GKI_BUF12_SIZE                0
+#endif /* ifndef GKI_BUF12_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 14)
+
+#ifndef GKI_POOL_ID_13
+#define GKI_POOL_ID_13                0
+#endif /* ifndef GKI_POOL_ID_13 */
+
+#ifndef GKI_BUF13_SIZE
+#define GKI_BUF13_SIZE                0
+#endif /* ifndef GKI_BUF13_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 15)
+
+#ifndef GKI_POOL_ID_14
+#define GKI_POOL_ID_14                0
+#endif /* ifndef GKI_POOL_ID_14 */
+
+#ifndef GKI_BUF14_SIZE
+#define GKI_BUF14_SIZE                0
+#endif /* ifndef GKI_BUF14_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 16)
+
+#ifndef GKI_POOL_ID_15
+#define GKI_POOL_ID_15                0
+#endif /* ifndef GKI_POOL_ID_15 */
+
+#ifndef GKI_BUF15_SIZE
+#define GKI_BUF15_SIZE                0
+#endif /* ifndef GKI_BUF15_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
+
+
+/* Timer list entry callback type
+*/
+typedef void (TIMER_CBACK)(void *p_tle);
+#ifndef TIMER_PARAM_TYPE
+#ifdef  WIN2000
+#define TIMER_PARAM_TYPE    void *
+#else
+#define TIMER_PARAM_TYPE    UINT32
+#endif
+#endif
+/* Define a timer list entry
+*/
+typedef struct _tle
+{
+    struct _tle  *p_next;
+    struct _tle  *p_prev;
+    TIMER_CBACK  *p_cback;
+    INT32         ticks;
+    TIMER_PARAM_TYPE   param;
+    UINT16        event;
+    UINT8         in_use;
+} TIMER_LIST_ENT;
+
+/* Define a timer list queue
+*/
+typedef struct
+{
+    TIMER_LIST_ENT   *p_first;
+    TIMER_LIST_ENT   *p_last;
+    INT32             last_ticks;
+} TIMER_LIST_Q;
+
+
+/***********************************************************************
+** This queue is a general purpose buffer queue, for application use.
+*/
+typedef struct
+{
+    void    *p_first;
+    void    *p_last;
+    UINT16   count;
+} BUFFER_Q;
+
+#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
+
+/* Task constants
+*/
+#ifndef TASKPTR
+typedef void (*TASKPTR)(UINT32);
+#endif
+
+
+#define GKI_PUBLIC_POOL         0       /* General pool accessible to GKI_getbuf() */
+#define GKI_RESTRICTED_POOL     1       /* Inaccessible pool to GKI_getbuf() */
+
+/***********************************************************************
+** Function prototypes
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Task management
+*/
+GKI_API extern UINT8   GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16, void*, void*);
+GKI_API extern void    GKI_exit_task(UINT8);
+GKI_API extern UINT8   GKI_get_taskid(void);
+GKI_API extern void    GKI_init(void);
+GKI_API extern INT8   *GKI_map_taskname(UINT8);
+GKI_API extern UINT8   GKI_resume_task(UINT8);
+GKI_API extern void    GKI_run(void *);
+GKI_API extern void    GKI_stop(void);
+GKI_API extern UINT8   GKI_suspend_task(UINT8);
+GKI_API extern UINT8   GKI_is_task_running(UINT8);
+
+/* memory management
+*/
+GKI_API extern void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount);
+GKI_API extern void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len);
+
+/* To send buffers and events between tasks
+*/
+GKI_API extern UINT8   GKI_isend_event (UINT8, UINT16);
+GKI_API extern void    GKI_isend_msg (UINT8, UINT8, void *);
+GKI_API extern void   *GKI_read_mbox  (UINT8);
+GKI_API extern void    GKI_send_msg   (UINT8, UINT8, void *);
+GKI_API extern UINT8   GKI_send_event (UINT8, UINT16);
+
+
+/* To get and release buffers, change owner and get size
+*/
+GKI_API extern void    GKI_change_buf_owner (void *, UINT8);
+GKI_API extern UINT8   GKI_create_pool (UINT16, UINT16, UINT8, void *);
+GKI_API extern void    GKI_delete_pool (UINT8);
+GKI_API extern void   *GKI_find_buf_start (void *);
+GKI_API extern void    GKI_freebuf (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getbuf(size)    GKI_getbuf_debug(size, __FUNCTION__, __LINE__)
+GKI_API extern void   *GKI_getbuf_debug (UINT16, const char *, int);
+#else
+GKI_API extern void   *GKI_getbuf (UINT16);
+#endif
+GKI_API extern UINT16  GKI_get_buf_size (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getpoolbuf(id)    GKI_getpoolbuf_debug(id, __FUNCTION__, __LINE__)
+GKI_API extern void   *GKI_getpoolbuf_debug (UINT8, const char *, int);
+#else
+GKI_API extern void   *GKI_getpoolbuf (UINT8);
+#endif
+
+GKI_API extern UINT16  GKI_poolcount (UINT8);
+GKI_API extern UINT16  GKI_poolfreecount (UINT8);
+GKI_API extern UINT16  GKI_poolutilization (UINT8);
+GKI_API extern void    GKI_register_mempool (void *p_mem);
+GKI_API extern UINT8   GKI_set_pool_permission(UINT8, UINT8);
+
+
+/* User buffer queue management
+*/
+GKI_API extern void   *GKI_dequeue  (BUFFER_Q *);
+GKI_API extern void    GKI_enqueue (BUFFER_Q *, void *);
+GKI_API extern void    GKI_enqueue_head (BUFFER_Q *, void *);
+GKI_API extern void   *GKI_getfirst (BUFFER_Q *);
+GKI_API extern void   *GKI_getlast (BUFFER_Q *);
+GKI_API extern void   *GKI_getnext (void *);
+GKI_API extern void    GKI_init_q (BUFFER_Q *);
+GKI_API extern BOOLEAN GKI_queue_is_empty(BUFFER_Q *);
+GKI_API extern void   *GKI_remove_from_queue (BUFFER_Q *, void *);
+GKI_API extern UINT16  GKI_get_pool_bufsize (UINT8);
+
+/* Timer management
+*/
+GKI_API extern void    GKI_add_to_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern void    GKI_delay(UINT32);
+GKI_API extern UINT32  GKI_get_tick_count(void);
+GKI_API extern INT8   *GKI_get_time_stamp(INT8 *);
+GKI_API extern void    GKI_init_timer_list (TIMER_LIST_Q *);
+GKI_API extern void    GKI_init_timer_list_entry (TIMER_LIST_ENT  *);
+GKI_API extern INT32   GKI_ready_to_sleep (void);
+GKI_API extern void    GKI_remove_from_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern void    GKI_start_timer(UINT8, INT32, BOOLEAN);
+GKI_API extern void    GKI_stop_timer (UINT8);
+GKI_API extern void    GKI_timer_update(INT32);
+GKI_API extern UINT16  GKI_update_timer_list (TIMER_LIST_Q *, INT32);
+GKI_API extern UINT32  GKI_get_remaining_ticks (TIMER_LIST_Q *, TIMER_LIST_ENT  *);
+GKI_API extern UINT16  GKI_wait(UINT16, UINT32);
+
+/* Start and Stop system time tick callback
+ * true for start system tick if time queue is not empty
+ * false to stop system tick if time queue is empty
+*/
+typedef void (SYSTEM_TICK_CBACK)(BOOLEAN);
+
+/* Time queue management for system ticks
+*/
+GKI_API extern BOOLEAN GKI_timer_queue_empty (void);
+GKI_API extern void    GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK *);
+
+/* Disable Interrupts, Enable Interrupts
+*/
+GKI_API extern void    GKI_enable(void);
+GKI_API extern void    GKI_disable(void);
+GKI_API extern void    GKI_sched_lock(void);
+GKI_API extern void    GKI_sched_unlock(void);
+
+/* Allocate (Free) memory from an OS
+*/
+GKI_API extern void     *GKI_os_malloc (UINT32);
+GKI_API extern void      GKI_os_free (void *);
+
+/* os timer operation */
+GKI_API extern UINT32 GKI_get_os_tick_count(void);
+
+/* Exception handling
+*/
+GKI_API extern void    GKI_exception (UINT16, char *);
+
+#if GKI_DEBUG == TRUE
+GKI_API extern void    GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used);
+GKI_API extern void    GKI_PrintBuffer(void);
+GKI_API extern void    GKI_print_task(void);
+#else
+#undef GKI_PrintBufferUsage
+#define GKI_PrintBuffer() NULL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/src/gki/common/gki_buffer.c b/src/gki/common/gki_buffer.c
new file mode 100644
index 0000000..067c7ba
--- /dev/null
+++ b/src/gki/common/gki_buffer.c
@@ -0,0 +1,1531 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+#include <stdio.h>
+
+#if (GKI_NUM_TOTAL_BUF_POOLS > 16)
+#error Number of pools out of range (16 Max)!
+#endif
+
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+static void gki_add_to_pool_list(UINT8 pool_id);
+static void gki_remove_from_pool_list(UINT8 pool_id);
+#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
+
+#if GKI_BUFFER_DEBUG
+#define LOG_TAG "GKI_DEBUG"
+#define LOGD(format, ...)  LogMsg (TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC, format, ## __VA_ARGS__)
+#endif
+/*******************************************************************************
+**
+** Function         gki_init_free_queue
+**
+** Description      Internal function called at startup to initialize a free
+**                  queue. It is called once for each free queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
+{
+    UINT16           i;
+    UINT16           act_size;
+    BUFFER_HDR_T    *hdr;
+    BUFFER_HDR_T    *hdr1 = NULL;
+    UINT32          *magic;
+    INT32            tempsize = size;
+    tGKI_COM_CB     *p_cb = &gki_cb.com;
+
+    /* Ensure an even number of longwords */
+    tempsize = (INT32)ALIGN_POOL(size);
+    act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
+
+    /* Remember pool start and end addresses */
+    if(p_mem)
+    {
+        p_cb->pool_start[id] = (UINT8 *)p_mem;
+        p_cb->pool_end[id]   = (UINT8 *)p_mem + (act_size * total);
+    }
+
+    p_cb->pool_size[id]  = act_size;
+
+    p_cb->freeq[id].size      = (UINT16) tempsize;
+    p_cb->freeq[id].total     = total;
+    p_cb->freeq[id].cur_cnt   = 0;
+    p_cb->freeq[id].max_cnt   = 0;
+
+#if GKI_BUFFER_DEBUG
+    LOGD("gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d start=%p", id, size, tempsize, total, p_mem);
+#endif
+
+    /* Initialize  index table */
+    if(p_mem)
+    {
+        hdr = (BUFFER_HDR_T *)p_mem;
+        p_cb->freeq[id].p_first = hdr;
+        for (i = 0; i < total; i++)
+        {
+            hdr->task_id = GKI_INVALID_TASK;
+            hdr->q_id    = id;
+            hdr->status  = BUF_STATUS_FREE;
+            magic        = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
+            *magic       = MAGIC_NO;
+            hdr1         = hdr;
+            hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+            hdr1->p_next = hdr;
+        }
+        hdr1->p_next = NULL;
+        p_cb->freeq[id].p_last = hdr1;
+    }
+    return;
+}
+
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+static BOOLEAN gki_alloc_free_queue(UINT8 id)
+{
+    FREE_QUEUE_T  *Q;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    printf("\ngki_alloc_free_queue in, id:%d \n", id);
+
+    Q = &p_cb->freeq[p_cb->pool_list[id]];
+
+    if(Q->p_first == 0)
+    {
+        void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
+        if(p_mem)
+        {
+            //re-initialize the queue with allocated memory
+            printf("\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            gki_init_free_queue(id, Q->size, Q->total, p_mem);
+            printf("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            return TRUE;
+        }
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
+    }
+    printf("\ngki_alloc_free_queue out failed, id:%d\n", id);
+    return FALSE;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         gki_buffer_init
+**
+** Description      Called once internally by GKI at startup to initialize all
+**                  buffers and free buffer pools.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_buffer_init(void)
+{
+    UINT8   i, tt, mb;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* Initialize mailboxes */
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+        for (mb = 0; mb < NUM_TASK_MBOX; mb++)
+        {
+            p_cb->OSTaskQFirst[tt][mb] = NULL;
+            p_cb->OSTaskQLast [tt][mb] = NULL;
+        }
+    }
+
+    for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
+    {
+        p_cb->pool_start[tt] = NULL;
+        p_cb->pool_end[tt]   = NULL;
+        p_cb->pool_size[tt]  = 0;
+
+        p_cb->freeq[tt].p_first = 0;
+        p_cb->freeq[tt].p_last  = 0;
+        p_cb->freeq[tt].size    = 0;
+        p_cb->freeq[tt].total   = 0;
+        p_cb->freeq[tt].cur_cnt = 0;
+        p_cb->freeq[tt].max_cnt = 0;
+    }
+
+    /* Use default from target.h */
+    p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
+
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
+#endif
+
+#endif
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
+#endif
+
+    /* add pools to the pool_list which is arranged in the order of size */
+    for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
+    {
+        p_cb->pool_list[i] = i;
+    }
+
+    p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_init_q
+**
+** Description      Called by an application to initialize a buffer queue.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_q (BUFFER_Q *p_q)
+{
+    p_q->p_first = p_q->p_last = NULL;
+    p_q->count = 0;
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_getbuf
+**
+** Description      Called by an application to get a free buffer which
+**                  is of size greater or equal to the requested size.
+**
+**                  Note: This routine only takes buffers from public pools.
+**                        It will not use any buffers from pools
+**                        marked GKI_RESTRICTED_POOL.
+**
+** Parameters       size - (input) number of bytes needed.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
+#else
+void *GKI_getbuf (UINT16 size)
+#endif
+{
+    UINT8         i;
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+#if GKI_BUFFER_DEBUG
+    UINT8         x;
+#endif
+
+    if (size == 0)
+    {
+        GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
+        return (NULL);
+    }
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
+#endif
+    /* Find the first buffer pool that is public that can hold the desired size */
+    for (i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
+            break;
+    }
+
+    if(i == p_cb->curr_total_no_of_pools)
+    {
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
+        return (NULL);
+    }
+
+    /* Make sure the buffers aren't disturbed til finished with allocation */
+    GKI_disable();
+
+    /* search the public buffer pools that are big enough to hold the size
+     * until a free buffer is found */
+    for ( ; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
+        if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
+            continue;
+
+        Q = &p_cb->freeq[p_cb->pool_list[i]];
+        if(Q->cur_cnt < Q->total)
+        {
+        #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+            if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
+            {
+                GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
+                return NULL;
+            }
+        #endif
+            p_hdr = Q->p_first;
+            Q->p_first = p_hdr->p_next;
+
+            if (!Q->p_first)
+                Q->p_last = NULL;
+
+            if(++Q->cur_cnt > Q->max_cnt)
+                Q->max_cnt = Q->cur_cnt;
+
+            GKI_enable();
+
+            p_hdr->task_id = GKI_get_taskid();
+
+            p_hdr->status  = BUF_STATUS_UNLINKED;
+            p_hdr->p_next  = NULL;
+            p_hdr->Type    = 0;
+#if GKI_BUFFER_DEBUG
+            LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[i].total);
+
+            strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+            p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+            p_hdr->_line = _line_;
+#endif
+            return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+        }
+    }
+
+    GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
+    LOGD("******************** GKI Memory Pool Dump ********************");
+
+    p_cb = &gki_cb.com;
+
+    LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
+
+    for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
+
+        LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
+
+        for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
+        {
+            if (p_hdr->status != BUF_STATUS_FREE)
+            {
+                LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x, (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status, p_hdr->_function, p_hdr->_line);
+            }
+
+            p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
+        }
+    }
+    LOGD("**************************************************************");
+#endif
+
+    GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
+
+    GKI_enable();
+
+    return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_getpoolbuf
+**
+** Description      Called by an application to get a free buffer from
+**                  a specific buffer pool.
+**
+**                  Note: If there are no more buffers available from the pool,
+**                        the public buffers are searched for an available buffer.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
+#else
+void *GKI_getpoolbuf (UINT8 pool_id)
+#endif
+{
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (NULL);
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
+#endif
+    /* Make sure the buffers aren't disturbed til finished with allocation */
+    GKI_disable();
+
+    Q = &p_cb->freeq[pool_id];
+    if(Q->cur_cnt < Q->total)
+    {
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+        if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
+            return NULL;
+#endif
+        p_hdr = Q->p_first;
+        Q->p_first = p_hdr->p_next;
+
+        if (!Q->p_first)
+            Q->p_last = NULL;
+
+        if(++Q->cur_cnt > Q->max_cnt)
+            Q->max_cnt = Q->cur_cnt;
+
+        GKI_enable();
+
+
+        p_hdr->task_id = GKI_get_taskid();
+
+        p_hdr->status  = BUF_STATUS_UNLINKED;
+        p_hdr->p_next  = NULL;
+        p_hdr->Type    = 0;
+
+#if GKI_BUFFER_DEBUG
+        LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);
+
+        strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+        p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+        p_hdr->_line = _line_;
+#endif
+        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+    }
+
+    /* If here, no buffers in the specified pool */
+    GKI_enable();
+
+#if GKI_BUFFER_DEBUG
+    /* try for free buffers in public pools */
+    return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
+#else
+    /* try for free buffers in public pools */
+    return (GKI_getbuf(p_cb->freeq[pool_id].size));
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_freebuf
+**
+** Description      Called by an application to return a buffer to the free pool.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_freebuf (void *p_buf)
+{
+    FREE_QUEUE_T    *Q;
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (!p_buf || gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+
+#if GKI_BUFFER_DEBUG
+    LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
+#endif
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
+        return;
+    }
+
+    if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
+        return;
+    }
+
+    GKI_disable();
+
+    /*
+    ** Release the buffer
+    */
+    Q  = &gki_cb.com.freeq[p_hdr->q_id];
+    if (Q->p_last)
+        Q->p_last->p_next = p_hdr;
+    else
+        Q->p_first = p_hdr;
+
+    Q->p_last      = p_hdr;
+    p_hdr->p_next  = NULL;
+    p_hdr->status  = BUF_STATUS_FREE;
+    p_hdr->task_id = GKI_INVALID_TASK;
+    if (Q->cur_cnt > 0)
+        Q->cur_cnt--;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_buf_size
+**
+** Description      Called by an application to get the size of a buffer.
+**
+** Parameters       p_buf - (input) address of the beginning of a buffer.
+**
+** Returns          the size of the buffer
+**
+*******************************************************************************/
+UINT16 GKI_get_buf_size (void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if ((UINT32)p_hdr & 1)
+        return (0);
+
+    if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        return (gki_cb.com.freeq[p_hdr->q_id].size);
+    }
+
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         gki_chk_buf_damage
+**
+** Description      Called internally by OSS to check for buffer corruption.
+**
+** Returns          TRUE if there is a problem, else FALSE
+**
+*******************************************************************************/
+BOOLEAN gki_chk_buf_damage(void *p_buf)
+{
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+
+    UINT32 *magic;
+    magic  = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
+
+    if ((UINT32)magic & 1)
+        return (TRUE);
+
+    if (*magic == MAGIC_NO)
+        return (FALSE);
+
+    return (TRUE);
+
+#else
+
+    return (FALSE);
+
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         GKI_send_msg
+**
+** Description      Called by applications to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+    BUFFER_HDR_T    *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* If task non-existant or not started, drop buffer */
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+        GKI_freebuf (msg);
+        return;
+    }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(msg))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+        return;
+    }
+
+    GKI_disable();
+
+    if (p_cb->OSTaskQFirst[task_id][mbox])
+        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+    else
+        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+    p_hdr->task_id = task_id;
+
+
+    GKI_enable();
+
+    GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_read_mbox
+**
+** Description      Called by applications to read a buffer from one of
+**                  the task mailboxes.  A task can only read its own mailbox.
+**
+** Parameters:      mbox  - (input) mailbox ID to read (0, 1, 2, or 3)
+**
+** Returns          NULL if the mailbox was empty, else the address of a buffer
+**
+*******************************************************************************/
+void *GKI_read_mbox (UINT8 mbox)
+{
+    UINT8           task_id = GKI_get_taskid();
+    void            *p_buf = NULL;
+    BUFFER_HDR_T    *p_hdr;
+
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
+        return (NULL);
+
+    GKI_disable();
+
+    if (gki_cb.com.OSTaskQFirst[task_id][mbox])
+    {
+        p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
+        gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
+
+        p_hdr->p_next = NULL;
+        p_hdr->status = BUF_STATUS_UNLINKED;
+
+        p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
+    }
+
+    GKI_enable();
+
+    return (p_buf);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue
+**
+** Description      Enqueue a buffer at the tail of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
+        return;
+    }
+
+    GKI_disable();
+
+    /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
+    if (p_q->p_first)
+    {
+        BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - BUFFER_HDR_SIZE);
+        p_last_hdr->p_next = p_hdr;
+    }
+    else
+        p_q->p_first = p_buf;
+
+    p_q->p_last = p_buf;
+    p_q->count++;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_enqueue_head
+**
+** Description      Enqueue a buffer at the head of the queue
+**
+** Parameters:      p_q  -  (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(p_buf))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
+        return;
+    }
+
+    GKI_disable();
+
+    if (p_q->p_first)
+    {
+        p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+        p_q->p_first = p_buf;
+    }
+    else
+    {
+        p_q->p_first = p_buf;
+        p_q->p_last  = p_buf;
+        p_hdr->p_next = NULL;
+    }
+    p_q->count++;
+
+    p_hdr->status = BUF_STATUS_QUEUED;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_dequeue
+**
+** Description      Dequeues a buffer from the head of a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_dequeue (BUFFER_Q *p_q)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    GKI_disable();
+
+    if (!p_q || !p_q->count)
+    {
+        GKI_enable();
+        return (NULL);
+    }
+
+    p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+    /* Keep buffers such that GKI header is invisible
+    */
+    if (p_hdr->p_next)
+        p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+    else
+    {
+        p_q->p_first = NULL;
+        p_q->p_last  = NULL;
+    }
+
+    p_q->count--;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_UNLINKED;
+
+    GKI_enable();
+
+    return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_queue
+**
+** Description      Dequeue a buffer from the middle of the queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**                  p_buf - (input) address of the buffer to enqueue
+**
+** Returns          NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
+{
+    BUFFER_HDR_T    *p_prev;
+    BUFFER_HDR_T    *p_buf_hdr;
+
+    GKI_disable();
+
+    if (p_buf == p_q->p_first)
+    {
+        GKI_enable();
+        return (GKI_dequeue (p_q));
+    }
+
+    p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+    p_prev    = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+    for ( ; p_prev; p_prev = p_prev->p_next)
+    {
+        /* If the previous points to this one, move the pointers around */
+        if (p_prev->p_next == p_buf_hdr)
+        {
+            p_prev->p_next = p_buf_hdr->p_next;
+
+            /* If we are removing the last guy in the queue, update p_last */
+            if (p_buf == p_q->p_last)
+                p_q->p_last = p_prev + 1;
+
+            /* One less in the queue */
+            p_q->count--;
+
+            /* The buffer is now unlinked */
+            p_buf_hdr->p_next = NULL;
+            p_buf_hdr->status = BUF_STATUS_UNLINKED;
+
+            GKI_enable();
+            return (p_buf);
+        }
+    }
+
+    GKI_enable();
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getfirst
+**
+** Description      Return a pointer to the first buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getfirst (BUFFER_Q *p_q)
+{
+    return (p_q->p_first);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getlast
+**
+** Description      Return a pointer to the last buffer in a queue
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getlast (BUFFER_Q *p_q)
+{
+    return (p_q->p_last);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_getnext
+**
+** Description      Return a pointer to the next buffer in a queue
+**
+** Parameters:      p_buf  - (input) pointer to the buffer to find the next one from.
+**
+** Returns          NULL if no more buffers in the queue, else next buffer address
+**
+*******************************************************************************/
+void *GKI_getnext (void *p_buf)
+{
+    BUFFER_HDR_T    *p_hdr;
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    if (p_hdr->p_next)
+        return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+    else
+        return (NULL);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         GKI_queue_is_empty
+**
+** Description      Check the status of a queue.
+**
+** Parameters:      p_q  - (input) pointer to a queue.
+**
+** Returns          TRUE if queue is empty, else FALSE
+**
+*******************************************************************************/
+BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
+{
+    return ((BOOLEAN) (p_q->count == 0));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_find_buf_start
+**
+** Description      This function is called with an address inside a buffer,
+**                  and returns the start address ofthe buffer.
+**
+**                  The buffer should be one allocated from one of GKI's pools.
+**
+** Parameters:      p_user_area - (input) address of anywhere in a GKI buffer.
+**
+** Returns          void * - Address of the beginning of the specified buffer if successful,
+**                          otherwise NULL if unsuccessful
+**
+*******************************************************************************/
+void *GKI_find_buf_start (void *p_user_area)
+{
+    UINT16       xx, size;
+    UINT32       yy;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    UINT8       *p_ua = (UINT8 *)p_user_area;
+
+    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+    {
+        if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
+        {
+            yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
+
+            size = p_cb->pool_size[xx];
+
+            yy = (yy / size) * size;
+
+            return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
+        }
+    }
+
+    /* If here, invalid address - not in one of our buffers */
+    GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
+
+    return (NULL);
+}
+
+
+/********************************************************
+* The following functions are not needed for light stack
+*********************************************************/
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+
+/*******************************************************************************
+**
+** Function         GKI_set_pool_permission
+**
+** Description      This function is called to set or change the permissions for
+**                  the specified pool ID.
+**
+** Parameters       pool_id -       (input) pool ID to be set or changed
+**                  permission -    (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
+**
+** Returns          GKI_SUCCESS if successful
+**                  GKI_INVALID_POOL if unsuccessful
+**
+*******************************************************************************/
+UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
+{
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+    {
+        if (permission == GKI_RESTRICTED_POOL)
+            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
+
+        else    /* mark the pool as public */
+            p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
+
+        return (GKI_SUCCESS);
+    }
+    else
+        return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         gki_add_to_pool_list
+**
+** Description      Adds pool to the pool list which is arranged in the
+**                  order of size
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_add_to_pool_list(UINT8 pool_id)
+{
+
+    INT32 i, j;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+     /* Find the position where the specified pool should be inserted into the list */
+    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+
+        if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
+            break;
+    }
+
+    /* Insert the new buffer pool ID into the list of pools */
+    for(j = p_cb->curr_total_no_of_pools; j > i; j--)
+    {
+        p_cb->pool_list[j] = p_cb->pool_list[j-1];
+    }
+
+    p_cb->pool_list[i] = pool_id;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_remove_from_pool_list
+**
+** Description      Removes pool from the pool list. Called when a pool is deleted
+**
+** Returns          void
+**
+*******************************************************************************/
+static void gki_remove_from_pool_list(UINT8 pool_id)
+{
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+    UINT8 i;
+
+    for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+    {
+        if(pool_id == p_cb->pool_list[i])
+            break;
+    }
+
+    while (i < (p_cb->curr_total_no_of_pools - 1))
+    {
+        p_cb->pool_list[i] = p_cb->pool_list[i+1];
+        i++;
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_igetpoolbuf
+**
+** Description      Called by an interrupt service routine to get a free buffer from
+**                  a specific buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns          A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+void *GKI_igetpoolbuf (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+    BUFFER_HDR_T  *p_hdr;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (NULL);
+
+
+    Q = &gki_cb.com.freeq[pool_id];
+    if(Q->cur_cnt < Q->total)
+    {
+        p_hdr = Q->p_first;
+        Q->p_first = p_hdr->p_next;
+
+        if (!Q->p_first)
+            Q->p_last = NULL;
+
+        if(++Q->cur_cnt > Q->max_cnt)
+            Q->max_cnt = Q->cur_cnt;
+
+        p_hdr->task_id = GKI_get_taskid();
+
+        p_hdr->status  = BUF_STATUS_UNLINKED;
+        p_hdr->p_next  = NULL;
+        p_hdr->Type    = 0;
+
+        return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+    }
+
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolcount
+**
+** Description      Called by an application to get the total number of buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the total number of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolcount (UINT8 pool_id)
+{
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (0);
+
+    return (gki_cb.com.freeq[pool_id].total);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolfreecount
+**
+** Description      Called by an application to get the number of free buffers
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          the number of free buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolfreecount (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (0);
+
+    Q  = &gki_cb.com.freeq[pool_id];
+
+    return ((UINT16)(Q->total - Q->cur_cnt));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_change_buf_owner
+**
+** Description      Called to change the task ownership of a buffer.
+**
+** Parameters:      p_buf   - (input) pointer to the buffer
+**                  task_id - (input) task id to change ownership to
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
+{
+    BUFFER_HDR_T    *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+    p_hdr->task_id = task_id;
+
+    return;
+}
+
+#if (defined(GKI_SEND_MSG_FROM_ISR) &&  GKI_SEND_MSG_FROM_ISR == TRUE)
+/*******************************************************************************
+**
+** Function         GKI_isend_msg
+**
+** Description      Called from interrupt context to send a buffer to a task
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+    BUFFER_HDR_T    *p_hdr;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* If task non-existant or not started, drop buffer */
+    if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+        GKI_freebuf (msg);
+        return;
+    }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+    if (gki_chk_buf_damage(msg))
+    {
+        GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+        return;
+    }
+#endif
+
+#if (GKI_ENABLE_OWNER_CHECK == TRUE)
+    if (gki_chk_buf_owner(msg))
+    {
+        GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
+        return;
+    }
+#endif
+
+    p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+    if (p_hdr->status != BUF_STATUS_UNLINKED)
+    {
+        GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+        return;
+    }
+
+    if (p_cb->OSTaskQFirst[task_id][mbox])
+        p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+    else
+        p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+    p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+    p_hdr->p_next = NULL;
+    p_hdr->status = BUF_STATUS_QUEUED;
+    p_hdr->task_id = task_id;
+
+    GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+    return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_create_pool
+**
+** Description      Called by applications to create a buffer pool.
+**
+** Parameters:      size        - (input) length (in bytes) of each buffer in the pool
+**                  count       - (input) number of buffers to allocate for the pool
+**                  permission  - (input) restricted or public access?
+**                                        (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
+**                  p_mem_pool  - (input) pointer to an OS memory pool, NULL if not provided
+**
+** Returns          the buffer pool ID, which should be used in calls to
+**                  GKI_getpoolbuf(). If a pool could not be created, this
+**                  function returns 0xff.
+**
+*******************************************************************************/
+UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
+{
+    UINT8        xx;
+    UINT32       mem_needed;
+    INT32        tempsize = size;
+    tGKI_COM_CB *p_cb = &gki_cb.com;
+
+    /* First make sure the size of each pool has a valid size with room for the header info */
+    if (size > MAX_USER_BUF_SIZE)
+        return (GKI_INVALID_POOL);
+
+    /* First, look for an unused pool */
+    for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+    {
+        if (!p_cb->pool_start[xx])
+            break;
+    }
+
+    if (xx == GKI_NUM_TOTAL_BUF_POOLS)
+        return (GKI_INVALID_POOL);
+
+    /* Ensure an even number of longwords */
+    tempsize = (INT32)ALIGN_POOL(size);
+
+    mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
+
+    if (!p_mem_pool)
+        p_mem_pool = GKI_os_malloc(mem_needed);
+
+    if (p_mem_pool)
+    {
+        /* Initialize the new pool */
+        gki_init_free_queue (xx, size, count, p_mem_pool);
+        gki_add_to_pool_list(xx);
+        (void) GKI_set_pool_permission (xx, permission);
+        p_cb->curr_total_no_of_pools++;
+
+        return (xx);
+    }
+    else
+        return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_delete_pool
+**
+** Description      Called by applications to delete a buffer pool.  The function
+**                  calls the operating specific function to free the actual memory.
+**                  An exception is generated if an error is detected.
+**
+** Parameters:      pool_id - (input) Id of the poll being deleted.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_delete_pool (UINT8 pool_id)
+{
+    FREE_QUEUE_T    *Q;
+    tGKI_COM_CB     *p_cb = &gki_cb.com;
+
+    if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
+        return;
+
+    GKI_disable();
+    Q  = &p_cb->freeq[pool_id];
+
+    if (!Q->cur_cnt)
+    {
+        Q->size      = 0;
+        Q->total     = 0;
+        Q->cur_cnt   = 0;
+        Q->max_cnt   = 0;
+        Q->p_first   = NULL;
+        Q->p_last    = NULL;
+
+        GKI_os_free (p_cb->pool_start[pool_id]);
+
+        p_cb->pool_start[pool_id] = NULL;
+        p_cb->pool_end[pool_id]   = NULL;
+        p_cb->pool_size[pool_id]  = 0;
+
+        gki_remove_from_pool_list(pool_id);
+        p_cb->curr_total_no_of_pools--;
+    }
+    else
+        GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
+
+    GKI_enable();
+
+    return;
+}
+
+#endif /*  BTU_STACK_LITE_ENABLED == FALSE */
+
+/*******************************************************************************
+**
+** Function         GKI_get_pool_bufsize
+**
+** Description      Called by an application to get the size of buffers in a pool
+**
+** Parameters       Pool ID.
+**
+** Returns          the size of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
+{
+    if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+        return (gki_cb.com.freeq[pool_id].size);
+
+    return (0);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_poolutilization
+**
+** Description      Called by an application to get the buffer utilization
+**                  in the specified buffer pool.
+**
+** Parameters       pool_id - (input) pool ID to get the free count of.
+**
+** Returns          % of buffers used from 0 to 100
+**
+*******************************************************************************/
+UINT16 GKI_poolutilization (UINT8 pool_id)
+{
+    FREE_QUEUE_T  *Q;
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+        return (100);
+
+    Q  = &gki_cb.com.freeq[pool_id];
+
+    if (Q->total == 0)
+        return (100);
+
+    return ((Q->cur_cnt * 100) / Q->total);
+}
+
diff --git a/src/gki/common/gki_common.h b/src/gki/common/gki_common.h
new file mode 100644
index 0000000..2bd9f8f
--- /dev/null
+++ b/src/gki/common/gki_common.h
@@ -0,0 +1,393 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_COMMON_H
+#define GKI_COMMON_H
+
+#include "gki.h"
+#include "dyn_mem.h"
+
+#ifndef GKI_DEBUG
+#define GKI_DEBUG	FALSE
+#endif
+
+/* Task States: (For OSRdyTbl) */
+#define TASK_DEAD       0   /* b0000 */
+#define TASK_READY      1   /* b0001 */
+#define TASK_WAIT       2   /* b0010 */
+#define TASK_DELAY      4   /* b0100 */
+#define TASK_SUSPEND    8   /* b1000 */
+
+
+/********************************************************************
+**  Internal Error codes
+*********************************************************************/
+#define GKI_ERROR_BUF_CORRUPTED         0xFFFF
+#define GKI_ERROR_NOT_BUF_OWNER         0xFFFE
+#define GKI_ERROR_FREEBUF_BAD_QID       0xFFFD
+#define GKI_ERROR_FREEBUF_BUF_LINKED    0xFFFC
+#define GKI_ERROR_SEND_MSG_BAD_DEST     0xFFFB
+#define GKI_ERROR_SEND_MSG_BUF_LINKED   0xFFFA
+#define GKI_ERROR_ENQUEUE_BUF_LINKED    0xFFF9
+#define GKI_ERROR_DELETE_POOL_BAD_QID   0xFFF8
+#define GKI_ERROR_BUF_SIZE_TOOBIG       0xFFF7
+#define GKI_ERROR_BUF_SIZE_ZERO         0xFFF6
+#define GKI_ERROR_ADDR_NOT_IN_BUF       0xFFF5
+
+
+/********************************************************************
+**  Misc constants
+*********************************************************************/
+
+#define GKI_MAX_INT32           (0x7fffffffL)
+#define GKI_MAX_TIMESTAMP       (0xffffffffL)
+
+/********************************************************************
+**  Buffer Management Data Structures
+*********************************************************************/
+
+typedef struct _buffer_hdr
+{
+    struct _buffer_hdr *p_next;   /* next buffer in the queue */
+    UINT8   q_id;                 /* id of the queue */
+    UINT8   task_id;              /* task which allocated the buffer*/
+    UINT8   status;               /* FREE, UNLINKED or QUEUED */
+    UINT8   Type;
+
+#if GKI_BUFFER_DEBUG
+    /* for tracking who allocated the buffer */
+    #define _GKI_MAX_FUNCTION_NAME_LEN   (50)
+    char    _function[_GKI_MAX_FUNCTION_NAME_LEN+1];
+    int     _line;
+#endif
+
+} BUFFER_HDR_T;
+
+typedef struct _free_queue
+{
+    BUFFER_HDR_T *p_first;      /* first buffer in the queue */
+    BUFFER_HDR_T *p_last;       /* last buffer in the queue */
+    UINT16          size;          /* size of the buffers in the pool */
+    UINT16          total;         /* toatal number of buffers */
+    UINT16          cur_cnt;       /* number of  buffers currently allocated */
+    UINT16          max_cnt;       /* maximum number of buffers allocated at any time */
+} FREE_QUEUE_T;
+
+
+/* Buffer related defines
+*/
+#define ALIGN_POOL(pl_size)  ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
+#define BUFFER_HDR_SIZE     (sizeof(BUFFER_HDR_T))                  /* Offset past header */
+#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
+#define MAX_USER_BUF_SIZE   ((UINT16)0xffff - BUFFER_PADDING_SIZE)  /* pool size must allow for header */
+#define MAGIC_NO            0xDDBADDBA
+
+#define BUF_STATUS_FREE     0
+#define BUF_STATUS_UNLINKED 1
+#define BUF_STATUS_QUEUED   2
+
+#define GKI_USE_DEFERED_ALLOC_BUF_POOLS
+
+/* Exception related structures (Used in debug mode only)
+*/
+#if (GKI_DEBUG == TRUE)
+typedef struct
+{
+    UINT16  type;
+    UINT8   taskid;
+    UINT8   msg[GKI_MAX_EXCEPTION_MSGLEN];
+} EXCEPTION_T;
+#endif
+
+
+/* Put all GKI variables into one control block
+*/
+typedef struct
+{
+    /* Task management variables
+    */
+    /* The stack and stack size are not used on Windows
+    */
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == FALSE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    UINT8 bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    UINT8 bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    UINT8 bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    UINT8 bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    UINT8 bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    UINT8 bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    UINT8 bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    UINT8 bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    UINT8 bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    UINT8 bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    UINT8 bufpool10[(ALIGN_POOL(GKI_BUF10_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    UINT8 bufpool11[(ALIGN_POOL(GKI_BUF11_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    UINT8 bufpool12[(ALIGN_POOL(GKI_BUF12_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    UINT8 bufpool13[(ALIGN_POOL(GKI_BUF13_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    UINT8 bufpool14[(ALIGN_POOL(GKI_BUF14_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    UINT8 bufpool15[(ALIGN_POOL(GKI_BUF15_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX];
+#endif
+
+#else
+/* Definitions for dynamic buffer use */
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+    UINT8 *bufpool0;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+    UINT8 *bufpool1;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+    UINT8 *bufpool2;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+    UINT8 *bufpool3;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+    UINT8 *bufpool4;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+    UINT8 *bufpool5;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+    UINT8 *bufpool6;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+    UINT8 *bufpool7;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+    UINT8 *bufpool8;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+    UINT8 *bufpool9;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+    UINT8 *bufpool10;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+    UINT8 *bufpool11;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+    UINT8 *bufpool12;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+    UINT8 *bufpool13;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+    UINT8 *bufpool14;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+    UINT8 *bufpool15;
+#endif
+
+#endif
+
+    UINT8  *OSStack[GKI_MAX_TASKS];         /* pointer to beginning of stack */
+    UINT16  OSStackSize[GKI_MAX_TASKS];     /* stack size available to each task */
+
+
+    INT8   *OSTName[GKI_MAX_TASKS];         /* name of the task */
+
+    UINT8   OSRdyTbl[GKI_MAX_TASKS];        /* current state of the task */
+    UINT16  OSWaitEvt[GKI_MAX_TASKS];       /* events that have to be processed by the task */
+    UINT16  OSWaitForEvt[GKI_MAX_TASKS];    /* events the task is waiting for*/
+
+    UINT32  OSTicks;                        /* system ticks from start */
+    UINT32  OSIdleCnt;                      /* idle counter */
+    INT16   OSDisableNesting;               /* counter to keep track of interrupt disable nesting */
+    INT16   OSLockNesting;                  /* counter to keep track of sched lock nesting */
+    INT16   OSIntNesting;                   /* counter to keep track of interrupt nesting */
+
+    /* Timer related variables
+    */
+    INT32   OSTicksTilExp;      /* Number of ticks till next timer expires */
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    UINT32  OSTicksTilStop;     /* inactivity delay timer; OS Ticks till stopping system tick */
+#endif
+    INT32   OSNumOrigTicks;     /* Number of ticks between last timer expiration to the next one */
+
+    INT32   OSWaitTmr   [GKI_MAX_TASKS];  /* ticks the task has to wait, for specific events */
+
+    /* Only take up space timers used in the system (GKI_NUM_TIMERS defined in target.h) */
+#if (GKI_NUM_TIMERS > 0)
+    INT32   OSTaskTmr0  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr0R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+    INT32   OSTaskTmr1  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr1R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+    INT32   OSTaskTmr2  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr2R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+    INT32   OSTaskTmr3  [GKI_MAX_TASKS];
+    INT32   OSTaskTmr3R [GKI_MAX_TASKS];
+#endif
+
+
+
+    /* Buffer related variables
+    */
+    BUFFER_HDR_T    *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
+    BUFFER_HDR_T    *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
+
+    /* Define the buffer pool management variables
+    */
+    FREE_QUEUE_T    freeq[GKI_NUM_TOTAL_BUF_POOLS];
+
+    UINT16   pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
+    UINT16   pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
+    UINT16   pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
+
+    /* Define the buffer pool start addresses
+    */
+    UINT8   *pool_start[GKI_NUM_TOTAL_BUF_POOLS];   /* array of pointers to the start of each buffer pool */
+    UINT8   *pool_end[GKI_NUM_TOTAL_BUF_POOLS];     /* array of pointers to the end of each buffer pool */
+    UINT16   pool_size[GKI_NUM_TOTAL_BUF_POOLS];    /* actual size of the buffers in a pool */
+
+    /* Define the buffer pool access control variables */
+    void        *p_user_mempool;                    /* User O/S memory pool */
+    UINT16      pool_access_mask;                   /* Bits are set if the corresponding buffer pool is a restricted pool */
+    UINT8       pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */
+    UINT8       curr_total_no_of_pools;             /* number of fixed buf pools + current number of dynamic pools */
+
+    BOOLEAN     timer_nesting;                      /* flag to prevent timer interrupt nesting */
+
+    /* Time queue arrays */
+    TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
+    /* System tick callback */
+    SYSTEM_TICK_CBACK *p_tick_cb;
+    BOOLEAN     system_tick_running;                /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
+
+#if (GKI_DEBUG == TRUE)
+    UINT16      ExceptionCnt;                       /* number of GKI exceptions that have happened */
+    EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
+#endif
+
+} tGKI_COM_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal GKI function prototypes
+*/
+GKI_API extern BOOLEAN   gki_chk_buf_damage(void *);
+extern BOOLEAN   gki_chk_buf_owner(void *);
+extern void      gki_buffer_init (void);
+extern void      gki_timers_init(void);
+extern void      gki_adjust_timer_count (INT32);
+
+extern void    OSStartRdy(void);
+extern void	   OSCtxSw(void);
+extern void	   OSIntCtxSw(void);
+extern void    OSSched(void);
+extern void    OSIntEnter(void);
+extern void    OSIntExit(void);
+
+
+/* Debug aids
+*/
+typedef void  (*FP_PRINT)(char *, ...);
+
+#if (GKI_DEBUG == TRUE)
+
+typedef void  (*PKT_PRINT)(UINT8 *, UINT16);
+
+extern void gki_print_task(FP_PRINT);
+extern void gki_print_exception(FP_PRINT);
+extern void gki_print_timer(FP_PRINT);
+extern void gki_print_stack(FP_PRINT);
+extern void gki_print_buffer(FP_PRINT);
+extern void gki_print_buffer_statistics(FP_PRINT, INT16);
+GKI_API extern void gki_print_used_bufs (FP_PRINT, UINT8);
+extern void gki_dump(UINT8 *, UINT16, FP_PRINT);
+extern void gki_dump2(UINT16 *, UINT16, FP_PRINT);
+extern void gki_dump4(UINT32 *, UINT16, FP_PRINT);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gki/common/gki_debug.c b/src/gki/common/gki_debug.c
new file mode 100644
index 0000000..481ba16
--- /dev/null
+++ b/src/gki/common/gki_debug.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#if (GKI_DEBUG == TRUE)
+
+const INT8 * const OSTaskStates[] =
+{
+    (INT8 *)"DEAD",  /* 0 */
+    (INT8 *)"REDY",  /* 1 */
+    (INT8 *)"WAIT",  /* 2 */
+    (INT8 *)"",
+    (INT8 *)"DELY",  /* 4 */
+    (INT8 *)"",
+    (INT8 *)"",
+    (INT8 *)"",
+    (INT8 *)"SUSP",  /* 8 */
+};
+
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBufferUsage
+**
+** Description      Displays Current Buffer Pool summary
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used)
+{
+    int i;
+    FREE_QUEUE_T    *p;
+    UINT8   num = gki_cb.com.curr_total_no_of_pools;
+    UINT16   cur[GKI_NUM_TOTAL_BUF_POOLS];
+
+    GKI_TRACE_0("");
+    GKI_TRACE_0("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
+
+    GKI_TRACE_0("POOL     SIZE  USED  MAXU  TOTAL");
+    GKI_TRACE_0("------------------------------");
+    for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++)
+    {
+        p = &gki_cb.com.freeq[i];
+        if ((1 << i) & gki_cb.com.pool_access_mask)
+        {
+            GKI_TRACE_5("%02d: (R), %4d, %3d, %3d, %3d",
+                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
+        }
+        else
+        {
+            GKI_TRACE_5("%02d: (P), %4d, %3d, %3d, %3d",
+                        i, p->size, p->cur_cnt, p->max_cnt, p->total);
+        }
+        cur[i] = p->cur_cnt;
+    }
+    if (p_num_pools)
+        *p_num_pools = num;
+    if (p_cur_used)
+        memcpy(p_cur_used, cur, num*2);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_PrintBuffer
+**
+** Description      Called internally by OSS to print the buffer pools
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_PrintBuffer(void)
+{
+    UINT16 i;
+    for(i=0; i<GKI_NUM_TOTAL_BUF_POOLS; i++)
+    {
+        GKI_TRACE_5("pool:%4u free %4u cur %3u max %3u  total%3u", i, gki_cb.com.freeq[i].size,
+                    gki_cb.com.freeq[i].cur_cnt, gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         gki_calc_stack
+**
+** Description      This function tries to calculate the amount of
+**                  stack used by looking non magic num. Magic num is consider
+**                  the first byte in the stack.
+**
+** Returns          the number of unused byte on the stack. 4 in case of stack overrun
+**
+*******************************************************************************/
+UINT16 gki_calc_stack (UINT8 task)
+{
+    int    j, stacksize;
+    UINT32 MagicNum;
+    UINT32 *p;
+
+    stacksize = (int) gki_cb.com.OSStackSize[task];
+    p = (UINT32 *)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
+    MagicNum = *p;
+
+    for(j = 0; j < stacksize; j++)
+    {
+        if(*p++ != MagicNum) break;
+    }
+
+    return (j * sizeof(UINT32));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_print_task
+**
+** Description      Print task stack usage.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_print_task(void)
+{
+#ifdef _BT_WIN32
+	GKI_TRACE_0("Service not available under insight");
+#else
+    UINT8 TaskId;
+
+    GKI_TRACE_0("TID TASKNAME STATE FREE_STACK  STACK");
+    for(TaskId=0; TaskId < GKI_MAX_TASKS; TaskId++)
+    {
+        if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD)
+        {
+            GKI_TRACE_5("%2u   %-8s %-5s  0x%04X     0x%04X Bytes",
+                (UINT16)TaskId,  gki_cb.com.OSTName[TaskId],
+                OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
+                gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
+
+        }
+    }
+#endif
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_buffer_statistics
+**
+** Description      Called internally by OSS to print the buffer pools statistics
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_buffer_statistics(FP_PRINT print, INT16 pool)
+{
+    UINT16           i;
+    BUFFER_HDR_T    *hdr;
+    UINT16           size,act_size,maxbuffs;
+    UINT32           *magic;
+
+    if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0)
+    {
+        print("Not a valid Buffer pool\n");
+        return;
+    }
+
+    size = gki_cb.com.freeq[pool].size;
+    maxbuffs = gki_cb.com.freeq[pool].total;
+    act_size = size + BUFFER_PADDING_SIZE;
+    print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u  total=%u\n",
+        pool, gki_cb.com.freeq[pool].size,
+        gki_cb.com.freeq[pool].cur_cnt, gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
+
+    print("      Owner  State    Sanity\n");
+    print("----------------------------\n");
+    hdr = (BUFFER_HDR_T *)(gki_cb.com.pool_start[pool]);
+    for(i=0; i<maxbuffs; i++)
+    {
+        magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + size);
+        print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status, (*magic == MAGIC_NO)?"OK":"CORRUPTED");
+        hdr          = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+    }
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_used_bufs
+**
+** Description      Dumps used buffers in the particular pool
+**
+*******************************************************************************/
+GKI_API void gki_print_used_bufs (FP_PRINT print, UINT8 pool_id)
+{
+    UINT8        *p_start;
+    UINT16       buf_size;
+    UINT16       num_bufs;
+    BUFFER_HDR_T *p_hdr;
+    UINT16       i;
+    UINT32         *magic;
+    UINT16       *p;
+
+
+    if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS && gki_cb.com.pool_start[pool_id] != 0)
+    {
+        print("Not a valid Buffer pool\n");
+        return;
+    }
+
+    p_start = gki_cb.com.pool_start[pool_id];
+    buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
+    num_bufs = gki_cb.com.freeq[pool_id].total;
+
+    for (i = 0; i < num_bufs; i++, p_start += buf_size)
+    {
+        p_hdr = (BUFFER_HDR_T *)p_start;
+        magic = (UINT32 *)((UINT8 *)p_hdr + buf_size - sizeof(UINT32));
+        p     = (UINT16 *) p_hdr;
+
+        if (p_hdr->status != BUF_STATUS_FREE)
+        {
+            print ("%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x %04x %04x\n",
+                i, p_hdr,
+                p_hdr->q_id,
+                GKI_map_taskname(p_hdr->task_id),
+                p_hdr->status,
+                (*magic == MAGIC_NO)? "OK" : "CORRUPTED",
+                p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_task
+**
+** Description      This function prints the task states.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_task (FP_PRINT print)
+{
+    UINT8 i;
+
+    print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
+    print("-------------------------------------------------\n");
+    for(i=0; i<GKI_MAX_TASKS; i++)
+    {
+        if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD)
+        {
+            print("%2u  %-8s %-5s %04X    %04X %7u %u/%u Bytes\n",
+                (UINT16)i,  gki_cb.com.OSTName[i],
+                OSTaskStates[gki_cb.com.OSRdyTbl[i]],
+                gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
+                gki_cb.com.OSWaitTmr[i], gki_calc_stack(i), gki_cb.com.OSStackSize[i]);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_print_exception
+**
+** Description      This function prints the exception information.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_print_exception(FP_PRINT print)
+{
+    UINT16 i;
+    EXCEPTION_T *pExp;
+
+    print ("GKI Exceptions:\n");
+    for (i = 0; i < gki_cb.com.ExceptionCnt; i++)
+    {
+        pExp =     &gki_cb.com.Exception[i];
+        print("%d: Type=%d, Task=%d: %s\n", i,
+            (INT32)pExp->type, (INT32)pExp->taskid, (INT8 *)pExp->msg);
+    }
+}
+
+
+/*****************************************************************************/
+void gki_dump (UINT8 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %02X, ", &s[i], s[i]);
+        else if(j == 7)
+            print("%02X,  ", s[i]);
+        else
+            print("%02X, ", s[i]);
+        if(++j == 16)
+            j=0;
+    }
+    print("\n");
+}
+
+void gki_dump2 (UINT16 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %04X, ", &s[i], s[i]);
+        else
+            print("%04X, ", s[i]);
+        if(++j == 8)
+            j=0;
+    }
+    print("\n");
+}
+
+void gki_dump4 (UINT32 *s, UINT16 len, FP_PRINT print)
+{
+    UINT16 i, j;
+
+    for(i=0, j=0; i<len; i++)
+    {
+        if(j == 0)
+            print("\n%lX: %08lX, ", &s[i], s[i]);
+        else
+            print("%08lX, ", s[i]);
+        if(++j == 4)
+            j=0;
+    }
+    print("\n");
+}
+
+
+#endif
diff --git a/src/gki/common/gki_inet.h b/src/gki/common/gki_inet.h
new file mode 100644
index 0000000..569c4fd
--- /dev/null
+++ b/src/gki/common/gki_inet.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_INET_H
+#define GKI_INET_H
+
+#include "data_types.h"
+
+#define htons   ntohs
+#define htonl   ntohl
+
+#define htonets	nettohs
+#define htonetl	nettohl
+
+#if BIG_ENDIAN == TRUE
+#define ntohs(n) (n)
+#define ntohl(n) (n)
+#define ntoh6(n) (n)
+
+#define nettohs(n) (n)
+#define nettohl(n) (n)
+#else
+extern UINT16 ntohs(UINT16 n);
+extern UINT32 ntohl(UINT32 n);
+extern UINT8 *ntoh6(UINT8 *p);
+
+#define nettohs(n) ((UINT16)((((n) << 8) & 0xff00) | (((n) >> 8) & 0x00ff)))
+#define nettohl(n) ((((n) & 0x000000ff) << 24) | (((n) << 8) & 0x00ff0000) | \
+                   (((n) >> 8) & 0x0000ff00) | (((n) >> 24) & 0x000000ff))
+#endif
+
+#endif /* GKI_INET_H */
+
diff --git a/src/gki/common/gki_time.c b/src/gki/common/gki_time.c
new file mode 100644
index 0000000..10377f6
--- /dev/null
+++ b/src/gki/common/gki_time.c
@@ -0,0 +1,1011 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#ifndef BT_ERROR_TRACE_0
+#define BT_ERROR_TRACE_0(l,m)
+#endif
+
+/* Make sure that this has been defined in target.h */
+#ifndef GKI_NUM_TIMERS
+#error  NO TIMERS: Must define at least 1 timer in the system!
+#endif
+
+
+#define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL)   /* Largest signed positive timer count */
+#define GKI_UNUSED_LIST_ENTRY   (0x80000000L)   /* Marks an unused timer list entry (initial value) */
+#define GKI_MAX_INT32           (0x7fffffffL)
+
+/*******************************************************************************
+**
+** Function         gki_timers_init
+**
+** Description      This internal function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_timers_init(void)
+{
+    UINT8   tt;
+
+    gki_cb.com.OSTicksTilExp = 0;       /* Remaining time (of OSTimeCurTimeout) before next timer expires */
+    gki_cb.com.OSNumOrigTicks = 0;
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
+#endif
+
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+        gki_cb.com.OSWaitTmr   [tt] = 0;
+
+#if (GKI_NUM_TIMERS > 0)
+        gki_cb.com.OSTaskTmr0  [tt] = 0;
+        gki_cb.com.OSTaskTmr0R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        gki_cb.com.OSTaskTmr1  [tt] = 0;
+        gki_cb.com.OSTaskTmr1R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        gki_cb.com.OSTaskTmr2  [tt] = 0;
+        gki_cb.com.OSTaskTmr2R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        gki_cb.com.OSTaskTmr3  [tt] = 0;
+        gki_cb.com.OSTaskTmr3R [tt] = 0;
+#endif
+    }
+
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+    {
+        gki_cb.com.timer_queues[tt] = NULL;
+    }
+
+    gki_cb.com.p_tick_cb = NULL;
+    gki_cb.com.system_tick_running = FALSE;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         gki_timers_is_timer_running
+**
+** Description      This internal function is called to test if any gki timer are running
+**
+**
+** Returns          TRUE if at least one time is running in the system, FALSE else.
+**
+*******************************************************************************/
+BOOLEAN gki_timers_is_timer_running(void)
+{
+    UINT8   tt;
+    for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+    {
+
+#if (GKI_NUM_TIMERS > 0)
+        if(gki_cb.com.OSTaskTmr0  [tt])
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        if(gki_cb.com.OSTaskTmr1  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        if(gki_cb.com.OSTaskTmr2  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        if(gki_cb.com.OSTaskTmr3  [tt] )
+        {
+            return TRUE;
+        }
+#endif
+    }
+
+    return FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_tick_count
+**
+** Description      This function returns the current system ticks
+**
+** Returns          The current number of system ticks
+**
+*******************************************************************************/
+UINT32  GKI_get_tick_count(void)
+{
+    return gki_cb.com.OSTicks;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_ready_to_sleep
+**
+** Description      This function returns the number of system ticks until the
+**                  next timer will expire.  It is typically called by a power
+**                  savings manager to find out how long it can have the system
+**                  sleep before it needs to service the next entry.
+**
+** Parameters:      None
+**
+** Returns          Number of ticks til the next timer expires
+**                  Note: the value is a signed  value.  This value should be
+**                      compared to x > 0, to avoid misinterpreting negative tick
+**                      values.
+**
+*******************************************************************************/
+INT32    GKI_ready_to_sleep (void)
+{
+    return (gki_cb.com.OSTicksTilExp);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_start_timer
+**
+** Description      An application can call this function to start one of
+**                  it's four general purpose timers. Any of the four timers
+**                  can be 1-shot or continuous. If a timer is already running,
+**                  it will be reset to the new parameters.
+**
+** Parameters       tnum            - (input) timer number to be started (TIMER_0,
+**                                              TIMER_1, TIMER_2, or TIMER_3)
+**                  ticks           - (input) the number of system ticks til the
+**                                              timer expires.
+**                  is_continuous   - (input) TRUE if timer restarts automatically,
+**                                              else FALSE if it is a 'one-shot'.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
+{
+    INT32   reload;
+    INT32   orig_ticks;
+    UINT8   task_id = GKI_get_taskid();
+    BOOLEAN bad_timer = FALSE;
+
+    if (ticks <= 0)
+        ticks = 1;
+
+    orig_ticks = ticks;     /* save the ticks in case adjustment is necessary */
+
+
+    /* If continuous timer, set reload, else set it to 0 */
+    if (is_continuous)
+        reload = ticks;
+    else
+        reload = 0;
+
+    GKI_disable();
+
+    if(gki_timers_is_timer_running() == FALSE)
+    {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+        /* if inactivity delay timer is not running, start system tick */
+        if(gki_cb.com.OSTicksTilStop == 0)
+        {
+#endif
+            if(gki_cb.com.p_tick_cb)
+            {
+                /* start system tick */
+                gki_cb.com.system_tick_running = TRUE;
+                (gki_cb.com.p_tick_cb) (TRUE);
+            }
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+        }
+        else
+        {
+            /* clear inactivity delay timer */
+            gki_cb.com.OSTicksTilStop = 0;
+        }
+#endif
+    }
+    /* Add the time since the last task timer update.
+    ** Note that this works when no timers are active since
+    ** both OSNumOrigTicks and OSTicksTilExp are 0.
+    */
+    if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
+    {
+        ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
+    }
+    else
+        ticks = GKI_MAX_INT32;
+
+    switch (tnum)
+    {
+#if (GKI_NUM_TIMERS > 0)
+        case TIMER_0:
+            gki_cb.com.OSTaskTmr0R[task_id] = reload;
+            gki_cb.com.OSTaskTmr0 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        case TIMER_1:
+            gki_cb.com.OSTaskTmr1R[task_id] = reload;
+            gki_cb.com.OSTaskTmr1 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        case TIMER_2:
+            gki_cb.com.OSTaskTmr2R[task_id] = reload;
+            gki_cb.com.OSTaskTmr2 [task_id] = ticks;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        case TIMER_3:
+            gki_cb.com.OSTaskTmr3R[task_id] = reload;
+            gki_cb.com.OSTaskTmr3 [task_id] = ticks;
+            break;
+#endif
+        default:
+            bad_timer = TRUE;       /* Timer number is bad, so do not use */
+    }
+
+    /* Update the expiration timeout if a legitimate timer */
+    if (!bad_timer)
+    {
+        /* Only update the timeout value if it is less than any other newly started timers */
+        gki_adjust_timer_count (orig_ticks);
+    }
+
+    GKI_enable();
+
+}
+
+/*******************************************************************************
+**
+** Function         GKI_stop_timer
+**
+** Description      An application can call this function to stop one of
+**                  it's four general purpose timers. There is no harm in
+**                  stopping a timer that is already stopped.
+**
+** Parameters       tnum            - (input) timer number to be started (TIMER_0,
+**                                              TIMER_1, TIMER_2, or TIMER_3)
+** Returns          void
+**
+*******************************************************************************/
+void GKI_stop_timer (UINT8 tnum)
+{
+    UINT8  task_id = GKI_get_taskid();
+
+    GKI_disable();
+
+    switch (tnum)
+    {
+#if (GKI_NUM_TIMERS > 0)
+        case TIMER_0:
+            gki_cb.com.OSTaskTmr0R[task_id] = 0;
+            gki_cb.com.OSTaskTmr0 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+        case TIMER_1:
+            gki_cb.com.OSTaskTmr1R[task_id] = 0;
+            gki_cb.com.OSTaskTmr1 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+        case TIMER_2:
+            gki_cb.com.OSTaskTmr2R[task_id] = 0;
+            gki_cb.com.OSTaskTmr2 [task_id] = 0;
+            break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+        case TIMER_3:
+            gki_cb.com.OSTaskTmr3R[task_id] = 0;
+            gki_cb.com.OSTaskTmr3 [task_id] = 0;
+            break;
+#endif
+    }
+
+    if (gki_timers_is_timer_running() == FALSE)
+    {
+        if (gki_cb.com.p_tick_cb)
+        {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+            /* if inactivity delay timer is not running */
+            if ((gki_cb.com.system_tick_running)&&(gki_cb.com.OSTicksTilStop == 0))
+            {
+                /* set inactivity delay timer */
+                /* when timer expires, system tick will be stopped */
+                gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
+            }
+#else
+            gki_cb.com.system_tick_running = FALSE;
+            gki_cb.com.p_tick_cb(FALSE); /* stop system tick */
+#endif
+        }
+    }
+
+    GKI_enable();
+
+
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_timer_update
+**
+** Description      This function is called by an OS to drive the GKI's timers.
+**                  It is typically called at every system tick to
+**                  update the timers for all tasks, and check for timeouts.
+**
+**                  Note: It has been designed to also allow for variable tick updates
+**                      so that systems with strict power savings requirements can
+**                      have the update occur at variable intervals.
+**
+** Parameters:      ticks_since_last_update - (input) This is the number of TICKS that have
+**                          occurred since the last time GKI_timer_update was called.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_timer_update (INT32 ticks_since_last_update)
+{
+    UINT8   task_id;
+    long    next_expiration;        /* Holds the next soonest expiration time after this update */
+
+    /* Increment the number of ticks used for time stamps */
+    gki_cb.com.OSTicks += ticks_since_last_update;
+
+    /* If any timers are running in any tasks, decrement the remaining time til
+     * the timer updates need to take place (next expiration occurs)
+     */
+    gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
+
+    /* Don't allow timer interrupt nesting */
+    if (gki_cb.com.timer_nesting)
+        return;
+
+    gki_cb.com.timer_nesting = 1;
+
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+    /* if inactivity delay timer is set and expired */
+    if (gki_cb.com.OSTicksTilStop)
+    {
+        if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update )
+        {
+            if(gki_cb.com.p_tick_cb)
+            {
+                gki_cb.com.system_tick_running = FALSE;
+                (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */
+            }
+            gki_cb.com.OSTicksTilStop = 0;      /* clear inactivity delay timer */
+            gki_cb.com.timer_nesting = 0;
+            return;
+        }
+        else
+            gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
+    }
+#endif
+
+    /* No need to update the ticks if no timeout has occurred */
+    if (gki_cb.com.OSTicksTilExp > 0)
+    {
+        gki_cb.com.timer_nesting = 0;
+        return;
+    }
+
+    GKI_disable();
+
+    next_expiration = GKI_NO_NEW_TMRS_STARTED;
+
+    /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
+       to account for the difference so timer updates below are decremented by the full number
+       of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
+       value only affects the timer updates below
+     */
+    gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
+
+    /* Check for OS Task Timers */
+    for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+    {
+        if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
+        {
+            gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
+            if (gki_cb.com.OSWaitTmr[task_id] <= 0)
+            {
+                /* Timer Expired */
+                gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+            }
+        }
+
+#if (GKI_NUM_TIMERS > 0)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr0[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
+            {
+                /* Set Timer 0 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_0_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_0_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr0[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr1[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
+            {
+                /* Set Timer 1 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_1_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_1_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr1[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr2[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
+            {
+                /* Set Timer 2 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_2_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_2_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr2[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+         /* If any timer is running, decrement */
+        if (gki_cb.com.OSTaskTmr3[task_id] > 0)
+        {
+            gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+            if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
+            {
+                /* Set Timer 3 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) &&  GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+                GKI_isend_event (task_id, TIMER_3_EVT_MASK);
+#else
+                GKI_send_event (task_id, TIMER_3_EVT_MASK);
+#endif
+                gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
+            }
+        }
+
+        /* Check to see if this timer is the next one to expire */
+        if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
+            next_expiration = gki_cb.com.OSTaskTmr3[task_id];
+#endif
+
+    }
+
+    /* Set the next timer experation value if there is one to start */
+    if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
+    {
+        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
+    }
+    else
+    {
+        gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
+    }
+
+    gki_cb.com.timer_nesting = 0;
+
+    GKI_enable();
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_empty
+**
+** Description      This function is called by applications to see whether the timer
+**                  queue is empty
+**
+** Parameters
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN GKI_timer_queue_empty (void)
+{
+    UINT8 tt;
+
+    for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+    {
+        if (gki_cb.com.timer_queues[tt])
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_timer_queue_register_callback
+**
+** Description      This function is called by applications to register system tick
+**                  start/stop callback for time queues
+**
+**
+** Parameters       p_callback - (input) pointer to the system tick callback
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+void GKI_timer_queue_register_callback (SYSTEM_TICK_CBACK *p_callback)
+{
+    gki_cb.com.p_tick_cb = p_callback;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list
+**
+** Description      This function is called by applications when they
+**                  want to initialize a timer list.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list (TIMER_LIST_Q *p_timer_listq)
+{
+    p_timer_listq->p_first    = NULL;
+    p_timer_listq->p_last     = NULL;
+    p_timer_listq->last_ticks = 0;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_init_timer_list_entry
+**
+** Description      This function is called by the applications when they
+**                  want to initialize a timer list entry. This must be
+**                  done prior to first use of the entry.
+**
+** Parameters       p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_init_timer_list_entry (TIMER_LIST_ENT  *p_tle)
+{
+    p_tle->p_next  = NULL;
+    p_tle->p_prev  = NULL;
+    p_tle->ticks   = GKI_UNUSED_LIST_ENTRY;
+    p_tle->in_use  = FALSE;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_update_timer_list
+**
+** Description      This function is called by the applications when they
+**                  want to update a timer list. This should be at every
+**                  timer list unit tick, e.g. once per sec, once per minute etc.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  num_units_since_last_update - (input) number of units since the last update
+**                                  (allows for variable unit update)
+**
+**      NOTE: The following timer list update routines should not be used for exact time
+**            critical purposes.  The timer tasks should be used when exact timing is needed.
+**
+** Returns          the number of timers that have expired
+**
+*******************************************************************************/
+UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
+{
+    TIMER_LIST_ENT  *p_tle;
+    UINT16           num_time_out = 0;
+    INT32            rem_ticks;
+    INT32            temp_ticks;
+
+    p_tle = p_timer_listq->p_first;
+
+    /* First, get the guys who have previously timed out */
+    /* Note that the tick value of the timers should always be '0' */
+    while ((p_tle) && (p_tle->ticks <= 0))
+    {
+        num_time_out++;
+        p_tle = p_tle->p_next;
+    }
+
+    /* Timer entriy tick values are relative to the preceeding entry */
+    rem_ticks = num_units_since_last_update;
+
+    /* Now, adjust remaining timer entries */
+    while ((p_tle != NULL) && (rem_ticks > 0))
+    {
+        temp_ticks = p_tle->ticks;
+        p_tle->ticks -= rem_ticks;
+
+        /* See if this timer has just timed out */
+        if (p_tle->ticks <= 0)
+        {
+            /* We set the number of ticks to '0' so that the legacy code
+             * that assumes a '0' or nonzero value will still work as coded. */
+            p_tle->ticks = 0;
+
+            num_time_out++;
+        }
+
+        rem_ticks -= temp_ticks;  /* Decrement the remaining ticks to process */
+        p_tle = p_tle->p_next;
+    }
+
+    if (p_timer_listq->last_ticks > 0)
+    {
+        p_timer_listq->last_ticks -= num_units_since_last_update;
+
+        /* If the last timer has expired set last_ticks to 0 so that other list update
+        * functions will calculate correctly
+        */
+        if (p_timer_listq->last_ticks < 0)
+            p_timer_listq->last_ticks = 0;
+    }
+
+    return (num_time_out);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_get_remaining_ticks
+**
+** Description      This function is called by an application to get remaining
+**                  ticks to expire
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_target_tle    - (input) pointer to a timer list queue entry
+**
+** Returns          0 if timer is not used or timer is not in the list
+**                  remaining ticks if success
+**
+*******************************************************************************/
+UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_target_tle)
+{
+    TIMER_LIST_ENT  *p_tle;
+    UINT32           rem_ticks = 0;
+
+    if (p_target_tle->in_use)
+    {
+        p_tle = p_timer_listq->p_first;
+
+        /* adding up all of ticks in previous entries */
+        while ((p_tle)&&(p_tle != p_target_tle))
+        {
+            rem_ticks += p_tle->ticks;
+            p_tle = p_tle->p_next;
+        }
+
+        /* if found target entry */
+        if (p_tle == p_target_tle)
+        {
+            rem_ticks += p_tle->ticks;
+        }
+        else
+        {
+            BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: No timer entry in the list");
+            return(0);
+        }
+    }
+    else
+    {
+        BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: timer entry is not active");
+    }
+
+    return (rem_ticks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_add_to_timer_list
+**
+** Description      This function is called by an application to add a timer
+**                  entry to a timer list.
+**
+**                  Note: A timer value of '0' will effectively insert an already
+**                      expired event.  Negative tick values will be ignored.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
+{
+    UINT32           nr_ticks_total;
+    UINT8 tt;
+    TIMER_LIST_ENT  *p_temp;
+    if (p_tle == NULL || p_timer_listq == NULL) {
+        GKI_TRACE_3("%s: invalid argument %x, %x****************************<<", __func__, p_timer_listq, p_tle);
+        return;
+    }
+
+
+    /* Only process valid tick values */
+    if (p_tle->ticks >= 0)
+    {
+        /* If this entry is the last in the list */
+        if (p_tle->ticks >= p_timer_listq->last_ticks)
+        {
+            /* If this entry is the only entry in the list */
+            if (p_timer_listq->p_first == NULL)
+                p_timer_listq->p_first = p_tle;
+            else
+            {
+                /* Insert the entry onto the end of the list */
+                if (p_timer_listq->p_last != NULL)
+                    p_timer_listq->p_last->p_next = p_tle;
+
+                p_tle->p_prev = p_timer_listq->p_last;
+            }
+
+            p_tle->p_next = NULL;
+            p_timer_listq->p_last = p_tle;
+            nr_ticks_total = p_tle->ticks;
+            p_tle->ticks -= p_timer_listq->last_ticks;
+
+            p_timer_listq->last_ticks = nr_ticks_total;
+        }
+        else    /* This entry needs to be inserted before the last entry */
+        {
+            /* Find the entry that the new one needs to be inserted in front of */
+            p_temp = p_timer_listq->p_first;
+            while (p_tle->ticks > p_temp->ticks)
+            {
+                /* Update the tick value if looking at an unexpired entry */
+                if (p_temp->ticks > 0)
+                    p_tle->ticks -= p_temp->ticks;
+
+                p_temp = p_temp->p_next;
+            }
+
+            /* The new entry is the first in the list */
+            if (p_temp == p_timer_listq->p_first)
+            {
+                p_tle->p_next = p_timer_listq->p_first;
+                p_timer_listq->p_first->p_prev = p_tle;
+                p_timer_listq->p_first = p_tle;
+            }
+            else
+            {
+                p_temp->p_prev->p_next = p_tle;
+                p_tle->p_prev = p_temp->p_prev;
+                p_temp->p_prev = p_tle;
+                p_tle->p_next = p_temp;
+            }
+            p_temp->ticks -= p_tle->ticks;
+        }
+
+        p_tle->in_use = TRUE;
+
+        /* if we already add this timer queue to the array */
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+             if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+                 return;
+        }
+        /* add this timer queue to the array */
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+             if (gki_cb.com.timer_queues[tt] == NULL)
+                 break;
+        }
+        if (tt < GKI_MAX_TIMER_QUEUES)
+        {
+            gki_cb.com.timer_queues[tt] = p_timer_listq;
+        }
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_remove_from_timer_list
+**
+** Description      This function is called by an application to remove a timer
+**                  entry from a timer list.
+**
+** Parameters       p_timer_listq   - (input) pointer to the timer list queue object
+**                  p_tle           - (input) pointer to a timer list queue entry
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT  *p_tle)
+{
+    UINT8 tt;
+
+    /* Verify that the entry is valid */
+    if (p_tle == NULL || p_tle->in_use == FALSE || p_timer_listq->p_first == NULL)
+    {
+        return;
+    }
+
+    /* Add the ticks remaining in this timer (if any) to the next guy in the list.
+    ** Note: Expired timers have a tick value of '0'.
+    */
+    if (p_tle->p_next != NULL)
+    {
+        p_tle->p_next->ticks += p_tle->ticks;
+    }
+    else
+    {
+        p_timer_listq->last_ticks -= p_tle->ticks;
+    }
+
+    /* Unlink timer from the list.
+    */
+    if (p_timer_listq->p_first == p_tle)
+    {
+        p_timer_listq->p_first = p_tle->p_next;
+
+        if (p_timer_listq->p_first != NULL)
+            p_timer_listq->p_first->p_prev = NULL;
+
+        if (p_timer_listq->p_last == p_tle)
+            p_timer_listq->p_last = NULL;
+    }
+    else
+    {
+        if (p_timer_listq->p_last == p_tle)
+        {
+            p_timer_listq->p_last = p_tle->p_prev;
+
+            if (p_timer_listq->p_last != NULL)
+                p_timer_listq->p_last->p_next = NULL;
+        }
+        else
+        {
+            if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
+                p_tle->p_next->p_prev = p_tle->p_prev;
+            else
+            {
+                /* Error case - chain messed up ?? */
+                return;
+            }
+
+            if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
+                p_tle->p_prev->p_next = p_tle->p_next;
+            else
+            {
+                /* Error case - chain messed up ?? */
+                return;
+            }
+        }
+    }
+
+    p_tle->p_next = p_tle->p_prev = NULL;
+    p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+    p_tle->in_use = FALSE;
+
+    /* if timer queue is empty */
+    if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL)
+    {
+        for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+        {
+            if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+            {
+                gki_cb.com.timer_queues[tt] = NULL;
+                break;
+            }
+        }
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         gki_adjust_timer_count
+**
+** Description      This function is called whenever a new timer or GKI_wait occurs
+**                  to adjust (if necessary) the current time til the first expiration.
+**                  This only needs to make an adjustment if the new timer (in ticks) is
+**                  less than the number of ticks remaining on the current timer.
+**
+** Parameters:      ticks - (input) number of system ticks of the new timer entry
+**
+**                  NOTE:  This routine MUST be called while interrupts are disabled to
+**                          avoid updates while adjusting the timer variables.
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_adjust_timer_count (INT32 ticks)
+{
+    if (ticks > 0)
+    {
+        /* See if the new timer expires before the current first expiration */
+        if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
+        {
+            gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
+            gki_cb.com.OSTicksTilExp = ticks;
+        }
+    }
+
+    return;
+}
diff --git a/src/gki/ulinux/data_types.h b/src/gki/ulinux/data_types.h
new file mode 100644
index 0000000..0768494
--- /dev/null
+++ b/src/gki/ulinux/data_types.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 DATA_TYPES_H
+#define DATA_TYPES_H
+
+#ifndef NULL
+#define NULL     0
+#endif
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+typedef unsigned char   UINT8;
+typedef unsigned short  UINT16;
+typedef unsigned long   UINT32;
+typedef unsigned long long int UINT64;
+typedef signed   long   INT32;
+typedef signed   char   INT8;
+typedef signed   short  INT16;
+typedef unsigned char   BOOLEAN;
+
+typedef UINT32          TIME_STAMP;
+
+#ifndef TRUE
+#define TRUE   (!FALSE)
+#endif
+
+typedef unsigned char   UBYTE;
+
+#ifdef __arm
+#define PACKED  __packed
+#define INLINE  __inline
+#else
+#define PACKED
+#define INLINE
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN FALSE
+#endif
+
+#define UINT16_LOW_BYTE(x)      ((x) & 0xff)
+#define UINT16_HI_BYTE(x)       ((x) >> 8)
+
+/* MACRO definitions for safe string functions */
+/* Replace standard string functions with safe functions if available */
+#define BCM_STRCAT_S(x1,x2,x3)      strcat((x1),(x3))
+#define BCM_STRNCAT_S(x1,x2,x3,x4)  strncat((x1),(x3),(x4))
+#define BCM_STRCPY_S(x1,x2,x3)      strcpy((x1),(x3))
+#define BCM_STRNCPY_S(x1,x2,x3,x4)  strncpy((x1),(x3),(x4))
+#define BCM_SPRINTF_S(x1,x2,x3,x4)  sprintf((x1),(x3),(x4))
+#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
+
+#endif
+
diff --git a/src/gki/ulinux/gki_int.h b/src/gki/ulinux/gki_int.h
new file mode 100644
index 0000000..c59ac32
--- /dev/null
+++ b/src/gki/ulinux/gki_int.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_INT_H
+#define GKI_INT_H
+
+#include "gki_common.h"
+#include <pthread.h>
+
+/**********************************************************************
+** OS specific definitions
+*/
+#ifdef ANDROID
+#include <sys/times.h>
+#endif
+
+typedef struct
+{
+    pthread_mutex_t     GKI_mutex;
+    pthread_t           thread_id[GKI_MAX_TASKS];
+    pthread_mutex_t     thread_evt_mutex[GKI_MAX_TASKS];
+    pthread_cond_t      thread_evt_cond[GKI_MAX_TASKS];
+    pthread_mutex_t     thread_timeout_mutex[GKI_MAX_TASKS];
+    pthread_cond_t      thread_timeout_cond[GKI_MAX_TASKS];
+    int                 no_timer_suspend;   /* 1: no suspend, 0 stop calling GKI_timer_update() */
+    pthread_mutex_t     gki_timer_mutex;
+    pthread_cond_t      gki_timer_cond;
+    int                 gki_timer_wake_lock_on;
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_t     GKI_trace_mutex;
+#endif
+} tGKI_OS;
+
+/* condition to exit or continue GKI_run() timer loop */
+#define GKI_TIMER_TICK_RUN_COND 1
+#define GKI_TIMER_TICK_STOP_COND 0
+#define GKI_TIMER_TICK_EXIT_COND 2
+
+extern void gki_system_tick_start_stop_cback(BOOLEAN start);
+
+/* Contains common control block as well as OS specific variables */
+typedef struct
+{
+    tGKI_OS     os;
+    tGKI_COM_CB com;
+} tGKI_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if GKI_DYNAMIC_MEMORY == FALSE
+GKI_API extern tGKI_CB  gki_cb;
+#else
+GKI_API extern tGKI_CB *gki_cb_ptr;
+#define gki_cb (*gki_cb_ptr)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/gki/ulinux/gki_ulinux.c b/src/gki/ulinux/gki_ulinux.c
new file mode 100644
index 0000000..b889469
--- /dev/null
+++ b/src/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1288 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define GKI_DEBUG   FALSE
+
+#include <pthread.h>  /* must be 1st header defined  */
+#include <time.h>
+#include "gki_int.h"
+#include "gki_target.h"
+
+/* Temp android logging...move to android tgt config file */
+
+#ifndef LINUX_NATIVE
+#include <cutils/log.h>
+#else
+#define LOGV(format, ...)  fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+#define LOGE(format, ...)  fprintf (stderr, LOG_TAG format, ## __VA_ARGS__)
+#define LOGI(format, ...)  fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#define pthread_cond_timedwait_monotonic pthread_cond_timedwait
+
+#endif
+
+/* Define the structure that holds the GKI variables
+*/
+#if GKI_DYNAMIC_MEMORY == FALSE
+tGKI_CB   gki_cb;
+#endif
+
+#define NANOSEC_PER_MILLISEC (1000000)
+#define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
+
+/* works only for 1ms to 1000ms heart beat ranges */
+#define LINUX_SEC (1000/TICKS_PER_SEC)
+// #define GKI_TICK_TIMER_DEBUG
+
+#define LOCK(m)  pthread_mutex_lock(&m)
+#define UNLOCK(m) pthread_mutex_unlock(&m)
+#define INIT(m) pthread_mutex_init(&m, NULL)
+
+
+/* this kind of mutex go into tGKI_OS control block!!!! */
+/* static pthread_mutex_t GKI_sched_mutex; */
+/*static pthread_mutex_t thread_delay_mutex;
+static pthread_cond_t thread_delay_cond;
+static pthread_mutex_t gki_timer_update_mutex;
+static pthread_cond_t   gki_timer_update_cond;
+*/
+#ifdef NO_GKI_RUN_RETURN
+static pthread_t            timer_thread_id = 0;
+#endif
+
+
+/* For Android */
+
+#ifndef GKI_SHUTDOWN_EVT
+#define GKI_SHUTDOWN_EVT    APPL_EVT_7
+#endif
+
+typedef struct
+{
+    UINT8 task_id;          /* GKI task id */
+    TASKPTR task_entry;     /* Task entry function*/
+    UINT32 params;          /* Extra params to pass to task entry function */
+    pthread_cond_t* pCond;	/* for android*/
+    pthread_mutex_t* pMutex;  /* for android*/
+} gki_pthread_info_t;
+gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
+
+/*******************************************************************************
+**
+** Function         gki_task_entry
+**
+** Description      entry point of GKI created tasks
+**
+** Returns          void
+**
+*******************************************************************************/
+void gki_task_entry(UINT32 params)
+{
+    pthread_t thread_id = pthread_self();
+    gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
+    GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x", p_pthread_info->task_id,
+                gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
+                p_pthread_info->pCond, p_pthread_info->pMutex);
+
+    gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
+    /* Call the actual thread entry point */
+    (p_pthread_info->task_entry)(p_pthread_info->params);
+
+    GKI_TRACE_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
+    gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
+
+    pthread_exit(0);    /* GKI tasks have no return value */
+}
+/* end android */
+
+#ifndef ANDROID
+void GKI_TRACE(char *fmt, ...)
+{
+    LOCK(gki_cb.os.GKI_trace_mutex);
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+
+    va_end(ap);
+    UNLOCK(gki_cb.os.GKI_trace_mutex);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_init
+**
+** Description      This function is called once at startup to initialize
+**                  all the timer structures.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_init(void)
+{
+    pthread_mutexattr_t attr;
+    tGKI_OS             *p_os;
+
+    memset (&gki_cb, 0, sizeof (gki_cb));
+
+    gki_buffer_init();
+    gki_timers_init();
+    gki_cb.com.OSTicks = (UINT32) times(0);
+
+    pthread_mutexattr_init(&attr);
+
+#ifndef __CYGWIN__
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+    p_os = &gki_cb.os;
+    pthread_mutex_init(&p_os->GKI_mutex, &attr);
+    /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
+#endif
+    /* pthread_mutex_init(&thread_delay_mutex, NULL); */  /* used in GKI_delay */
+    /* pthread_cond_init (&thread_delay_cond, NULL); */
+
+    /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
+     * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
+    p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
+    pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
+    pthread_cond_init(&p_os->gki_timer_cond, NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_os_tick_count
+**
+** Description      This function is called to retrieve the native OS system tick.
+**
+** Returns          Tick count of native OS.
+**
+*******************************************************************************/
+UINT32 GKI_get_os_tick_count(void)
+{
+
+    /* TODO - add any OS specific code here
+    **/
+    return (gki_cb.com.OSTicks);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_create_task
+**
+** Description      This function is called to create a new OSS task.
+**
+** Parameters:      task_entry  - (input) pointer to the entry function of the task
+**                  task_id     - (input) Task id is mapped to priority
+**                  taskname    - (input) name given to the task
+**                  stack       - (input) pointer to the top of the stack (highest memory location)
+**                  stacksize   - (input) size of the stack allocated for the task
+**
+** Returns          GKI_SUCCESS if all OK, GKI_FAILURE if any problem
+**
+** NOTE             This function take some parameters that may not be needed
+**                  by your particular OS. They are here for compatability
+**                  of the function prototype.
+**
+*******************************************************************************/
+UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize, void* pCondVar, void* pMutex)
+{
+    UINT16  i;
+    UINT8   *p;
+    struct sched_param param;
+    int policy, ret = 0;
+    pthread_attr_t attr1;
+
+    GKI_TRACE_5 ("GKI_create_task func=0x%x  id=%d  name=%s  stack=0x%x  stackSize=%d", task_entry, task_id, taskname, stack, stacksize);
+
+    if (task_id >= GKI_MAX_TASKS)
+    {
+        GKI_TRACE_0("Error! task ID > max task allowed");
+        return (GKI_FAILURE);
+    }
+
+
+    gki_cb.com.OSRdyTbl[task_id]    = TASK_READY;
+    gki_cb.com.OSTName[task_id]     = taskname;
+    gki_cb.com.OSWaitTmr[task_id]   = 0;
+    gki_cb.com.OSWaitEvt[task_id]   = 0;
+
+    /* Initialize mutex and condition variable objects for events and timeouts */
+    pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], NULL);
+    pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], NULL);
+
+    pthread_attr_init(&attr1);
+    /* by default, pthread creates a joinable thread */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
+
+    GKI_TRACE_3("GKI creating task %i, pCond/pMutex=%x/%x", task_id, pCondVar, pMutex);
+#else
+    GKI_TRACE_1("GKI creating JOINABLE task %i", task_id);
+#endif
+
+    /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
+    /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
+    gki_pthread_info[task_id].task_id = task_id;
+    gki_pthread_info[task_id].task_entry = task_entry;
+    gki_pthread_info[task_id].params = 0;
+    gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
+    gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
+
+    ret = pthread_create( &gki_cb.os.thread_id[task_id],
+              &attr1,
+              (void *)gki_task_entry,
+              &gki_pthread_info[task_id]);
+
+    if (ret != 0)
+    {
+         GKI_TRACE_2("pthread_create failed(%d), %s!", ret, taskname);
+         return GKI_FAILURE;
+    }
+
+    if(pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param)==0)
+    {
+#if defined(PBS_SQL_TASK)
+         if (task_id == PBS_SQL_TASK)
+         {
+             GKI_TRACE_0("PBS SQL lowest priority task");
+             policy = SCHED_NORMAL;
+         }
+         else
+#endif
+         {
+             policy = SCHED_RR;
+             param.sched_priority = 30 - task_id - 2;
+         }
+         pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
+     }
+
+    GKI_TRACE_6( "Leaving GKI_create_task %x %d %x %s %x %d",
+              task_entry,
+              task_id,
+              gki_cb.os.thread_id[task_id],
+              taskname,
+              stack,
+              stacksize);
+
+    return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shutdown
+**
+** Description      shutdowns the GKI tasks/threads in from max task id to 0 and frees
+**                  pthread resources!
+**                  IMPORTANT: in case of join method, GKI_shutdown must be called outside
+**                  a GKI thread context!
+**
+** Returns          void
+**
+*******************************************************************************/
+#define WAKE_LOCK_ID "brcm_nfca"
+#define PARTIAL_WAKE_LOCK 1
+extern int acquire_wake_lock(int lock, const char* id);
+extern int release_wake_lock(const char* id);
+
+void GKI_shutdown(void)
+{
+    UINT8 task_id;
+    volatile int    *p_run_cond = &gki_cb.os.no_timer_suspend;
+    int     oldCOnd = 0;
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    int i = 0;
+#else
+    int result;
+#endif
+
+    /* release threads and set as TASK_DEAD. going from low to high priority fixes
+     * GKI_exception problem due to btu->hci sleep request events  */
+    for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
+    {
+        if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
+        {
+            gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
+
+            /* paranoi settings, make sure that we do not execute any mailbox events */
+            gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
+                                                TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
+            GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+            i = 0;
+
+            while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
+                usleep(100 * 1000);
+#else
+            /* wait for proper Arnold Schwarzenegger task state */
+            result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
+            if ( result < 0 )
+            {
+                GKI_TRACE_1( "pthread_join() FAILED: result: %d", result );
+            }
+#endif
+            GKI_TRACE_1( "GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
+            GKI_exit_task(task_id - 1);
+        }
+    }
+
+    /* Destroy mutex and condition variable objects */
+    pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
+    /*    pthread_mutex_destroy(&GKI_sched_mutex); */
+#if (GKI_DEBUG == TRUE)
+    pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
+#endif
+    /*    pthread_mutex_destroy(&thread_delay_mutex);
+     pthread_cond_destroy (&thread_delay_cond); */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+    i = 0;
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+    shutdown_timer = 1;
+#endif
+    if (gki_cb.os.gki_timer_wake_lock_on)
+    {
+        GKI_TRACE_0("GKI_shutdown :  release_wake_lock(brcm_btld)");
+        release_wake_lock(WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 0;
+    }
+    oldCOnd = *p_run_cond;
+    *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
+    if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
+        pthread_cond_signal( &gki_cb.os.gki_timer_cond );
+
+}
+
+/*******************************************************************************
+ **
+ ** Function        GKI_run
+ **
+ ** Description     This function runs a task
+ **
+ ** Parameters:     start: TRUE start system tick (again), FALSE stop
+ **
+ ** Returns         void
+ **
+ *********************************************************************************/
+void gki_system_tick_start_stop_cback(BOOLEAN start)
+{
+    tGKI_OS         *p_os = &gki_cb.os;
+    volatile int    *p_run_cond = &p_os->no_timer_suspend;
+    volatile static int wake_lock_count;
+    if ( FALSE == start )
+    {
+        /* this can lead to a race condition. however as we only read this variable in the timer loop
+         * we should be fine with this approach. otherwise uncomment below mutexes.
+         */
+        /* GKI_disable(); */
+        *p_run_cond = GKI_TIMER_TICK_STOP_COND;
+        /* GKI_enable(); */
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count);
+#endif
+        release_wake_lock(WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 0;
+    }
+    else
+    {
+        /* restart GKI_timer_update() loop */
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+        gki_cb.os.gki_timer_wake_lock_on = 1;
+        *p_run_cond = GKI_TIMER_TICK_RUN_COND;
+        pthread_mutex_lock( &p_os->gki_timer_mutex );
+        pthread_cond_signal( &p_os->gki_timer_cond );
+        pthread_mutex_unlock( &p_os->gki_timer_mutex );
+
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count );
+#endif
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         timer_thread
+**
+** Description      Timer thread
+**
+** Parameters:      id  - (input) timer ID
+**
+** Returns          void
+**
+*********************************************************************************/
+#ifdef NO_GKI_RUN_RETURN
+void timer_thread(signed long id)
+{
+    GKI_TRACE_1("%s enter", __func__);
+    struct timespec delay;
+    int timeout = 1000;  /* 10  ms per system tick  */
+    int err;
+
+    while(!shutdown_timer)
+    {
+        delay.tv_sec = timeout / 1000;
+        delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+        /* [u]sleep can't be used because it uses SIGALRM */
+
+        do
+        {
+            err = nanosleep(&delay, &delay);
+        } while (err < 0 && errno ==EINTR);
+
+        GKI_timer_update(1);
+    }
+    GKI_TRACE_1("%s exit", __func__);
+    pthread_exit(NULL);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         GKI_run
+**
+** Description      This function runs a task
+**
+** Parameters:      p_task_id  - (input) pointer to task id
+**
+** Returns          void
+**
+** NOTE             This function is only needed for operating systems where
+**                  starting a task is a 2-step process. Most OS's do it in
+**                  one step, If your OS does it in one step, this function
+**                  should be empty.
+*********************************************************************************/
+void GKI_run (void *p_task_id)
+{
+    GKI_TRACE_1("%s enter", __func__);
+    struct timespec delay;
+    int err = 0;
+    volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;
+
+#ifndef GKI_NO_TICK_STOP
+    /* register start stop function which disable timer loop in GKI_run() when no timers are
+     * in any GKI/BTA/BTU this should save power when BTLD is idle! */
+    GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
+    APPL_TRACE_DEBUG0( "GKI_run(): Start/Stop GKI_timer_update_registered!" );
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+    GKI_TRACE_0("GKI_run == NO_GKI_RUN_RETURN");
+    pthread_attr_t timer_attr;
+
+    shutdown_timer = 0;
+
+    pthread_attr_init(&timer_attr);
+    pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
+    if (pthread_create( &timer_thread_id,
+              &timer_attr,
+              timer_thread,
+              NULL) != 0 )
+    {
+        GKI_TRACE_0("GKI_run: pthread_create failed to create timer_thread!");
+        return GKI_FAILURE;
+    }
+#else
+    GKI_TRACE_2("GKI_run, run_cond(%x)=%d ", p_run_cond, *p_run_cond);
+    for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;)
+    {
+        do
+        {
+            /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
+             * 1-1000ms heart beat units! */
+            delay.tv_sec = LINUX_SEC / 1000;
+            delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
+
+            /* [u]sleep can't be used because it uses SIGALRM */
+            do
+            {
+                err = nanosleep(&delay, &delay);
+            } while (err < 0 && errno == EINTR);
+
+            /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick
+             * e.g. power saving you may want to provide more ticks
+             */
+            GKI_timer_update( 1 );
+            /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
+        } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond);
+
+        /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND
+         * block timer main thread till re-armed by  */
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_0( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> SUSPENDED GKI_timer_update()" );
+#endif
+        if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
+            GKI_TRACE_1("%s waiting timer mutex", __func__);
+            pthread_mutex_lock( &gki_cb.os.gki_timer_mutex );
+            pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex );
+            pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
+            GKI_TRACE_1("%s exited timer mutex", __func__);
+        }
+        /* potentially we need to adjust os gki_cb.com.OSTicks */
+
+#ifdef GKI_TICK_TIMER_DEBUG
+        BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> RESTARTED GKI_timer_update(): run_cond: %d",
+                    *p_run_cond );
+#endif
+    } /* for */
+#endif
+    GKI_TRACE_1("%s exit", __func__);
+    return(0);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_stop
+**
+** Description      This function is called to stop
+**                  the tasks and timers when the system is being stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here.
+**
+*******************************************************************************/
+void GKI_stop (void)
+{
+    UINT8 task_id;
+
+    /*  gki_queue_timer_cback(FALSE); */
+    /* TODO - add code here if needed*/
+
+    for(task_id = 0; task_id<GKI_MAX_TASKS; task_id++)
+    {
+        if(gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
+        {
+            GKI_exit_task(task_id);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_wait
+**
+** Description      This function is called by tasks to wait for a specific
+**                  event or set of events. The task may specify the duration
+**                  that it wants to wait for, or 0 if infinite.
+**
+** Parameters:      flag -    (input) the event or set of events to wait for
+**                  timeout - (input) the duration that the task wants to wait
+**                                    for the specific events (in system ticks)
+**
+**
+** Returns          the event mask of received events or zero if timeout
+**
+*******************************************************************************/
+UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
+{
+    UINT16 evt;
+    UINT8 rtask;
+    struct timespec abstime = { 0, 0 };
+    int sec;
+    int nano_sec;
+
+    rtask = GKI_get_taskid();
+    GKI_TRACE_3("GKI_wait %d %x %d", rtask, flag, timeout);
+    if (rtask >= GKI_MAX_TASKS) {
+        pthread_exit(NULL);
+        return 0;
+    }
+
+    gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
+    if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
+        int ret;
+        GKI_TRACE_3("GKI_wait task=%i, pCond/pMutex = %x/%x", rtask, p_pthread_info->pCond, p_pthread_info->pMutex);
+        ret = pthread_mutex_lock(p_pthread_info->pMutex);
+        ret = pthread_cond_signal(p_pthread_info->pCond);
+        ret = pthread_mutex_unlock(p_pthread_info->pMutex);
+        p_pthread_info->pMutex = NULL;
+        p_pthread_info->pCond = NULL;
+    }
+    gki_cb.com.OSWaitForEvt[rtask] = flag;
+
+    /* protect OSWaitEvt[rtask] from modification from an other thread */
+    pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
+
+#if 0 /* for clean scheduling we probably should always call pthread_cond_wait() */
+    /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
+     has been modified. however this should only result in addtional call to  pthread_cond_wait() but as
+     the cond is met, it will exit immediately (depending on schedulling) */
+    if (gki_cb.com.OSTaskQFirst[rtask][0])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][1])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][2])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+    if (gki_cb.com.OSTaskQFirst[rtask][3])
+    gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+#endif
+
+    if (!(gki_cb.com.OSWaitEvt[rtask] & flag))
+    {
+        if (timeout)
+        {
+            //            timeout = GKI_MS_TO_TICKS(timeout);     /* convert from milliseconds to ticks */
+
+            /* get current system time */
+            //            clock_gettime(CLOCK_MONOTONIC, &currSysTime);
+            //            abstime.tv_sec = currSysTime.time;
+            //            abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+            clock_gettime(CLOCK_MONOTONIC, &abstime);
+
+            /* add timeout */
+            sec = timeout / 1000;
+            nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
+            abstime.tv_nsec += nano_sec;
+            if (abstime.tv_nsec > NSEC_PER_SEC)
+            {
+                abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
+                abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
+            }
+            abstime.tv_sec += sec;
+
+            pthread_cond_timedwait_monotonic(&gki_cb.os.thread_evt_cond[rtask],
+                    &gki_cb.os.thread_evt_mutex[rtask], &abstime);
+
+        }
+        else
+        {
+            pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
+        }
+
+        /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
+         e.g. it looks like it is implemented as a counter in which case multiple cond_signal
+         should NOT be lost! */
+        // we are waking up after waiting for some events, so refresh variables
+        // no need to call GKI_disable() here as we know that we will have some events as we've been waking up after condition pending or timeout
+        if (gki_cb.com.OSTaskQFirst[rtask][0])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][1])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][2])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+        if (gki_cb.com.OSTaskQFirst[rtask][3])
+            gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+
+        if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+        {
+            gki_cb.com.OSWaitEvt[rtask] = 0;
+            /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
+            pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+            BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "GKI TASK_DEAD received. exit thread %d...", rtask );
+
+            gki_cb.os.thread_id[rtask] = 0;
+            pthread_exit(NULL);
+            return (EVENT_MASK(GKI_SHUTDOWN_EVT));
+        }
+    }
+
+    /* Clear the wait for event mask */
+    gki_cb.com.OSWaitForEvt[rtask] = 0;
+
+    /* Return only those bits which user wants... */
+    evt = gki_cb.com.OSWaitEvt[rtask] & flag;
+
+    /* Clear only those bits which user wants... */
+    gki_cb.com.OSWaitEvt[rtask] &= ~flag;
+
+    /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
+    pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+    GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
+
+    return (evt);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_delay
+**
+** Description      This function is called by tasks to sleep unconditionally
+**                  for a specified amount of time. The duration is in milliseconds
+**
+** Parameters:      timeout -    (input) the duration in milliseconds
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_delay (UINT32 timeout)
+{
+    UINT8 rtask = GKI_get_taskid();
+    struct timespec delay;
+    int err;
+
+    GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
+
+    delay.tv_sec = timeout / 1000;
+    delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+    /* [u]sleep can't be used because it uses SIGALRM */
+
+    do {
+        err = nanosleep(&delay, &delay);
+    } while (err < 0 && errno ==EINTR);
+
+    /* Check if task was killed while sleeping */
+    /* NOTE
+    **      if you do not implement task killing, you do not
+    **      need this check.
+    */
+    if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+    {
+    }
+
+    GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_send_event
+**
+** Description      This function is called by tasks to send events to other
+**                  tasks. Tasks can also send events to themselves.
+**
+** Parameters:      task_id -  (input) The id of the task to which the event has to
+**                  be sent
+**                  event   -  (input) The event that has to be sent
+**
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+*******************************************************************************/
+UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
+{
+    GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
+
+    /* use efficient coding to avoid pipeline stalls */
+    if (task_id < GKI_MAX_TASKS)
+    {
+        /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
+        pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+        /* Set the event bit */
+        gki_cb.com.OSWaitEvt[task_id] |= event;
+
+        pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
+
+        pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+        GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
+        return ( GKI_SUCCESS );
+    }
+    return (GKI_FAILURE);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_isend_event
+**
+** Description      This function is called from ISRs to send events to other
+**                  tasks. The only difference between this function and GKI_send_event
+**                  is that this function assumes interrupts are already disabled.
+**
+** Parameters:      task_id -  (input) The destination task Id for the event.
+**                  event   -  (input) The event flag
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put your code here, otherwise you can delete the entire
+**                  body of the function.
+**
+*******************************************************************************/
+UINT8 GKI_isend_event (UINT8 task_id, UINT16 event)
+{
+
+    GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
+    GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
+    return    GKI_send_event(task_id, event);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_taskid
+**
+** Description      This function gets the currently running task ID.
+**
+** Returns          task ID
+**
+** NOTE             The Widcomm upper stack and profiles may run as a single task.
+**                  If you only have one GKI task, then you can hard-code this
+**                  function to return a '1'. Otherwise, you should have some
+**                  OS-specific method to determine the current task.
+**
+*******************************************************************************/
+UINT8 GKI_get_taskid (void)
+{
+    int i;
+
+    pthread_t thread_id = pthread_self( );
+    for (i = 0; i < GKI_MAX_TASKS; i++) {
+        if (gki_cb.os.thread_id[i] == thread_id) {
+            GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
+            return(i);
+        }
+    }
+
+    GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
+
+    return(-1);
+}
+
+/*******************************************************************************
+**
+** Function         GKI_map_taskname
+**
+** Description      This function gets the task name of the taskid passed as arg.
+**                  If GKI_MAX_TASKS is passed as arg the currently running task
+**                  name is returned
+**
+** Parameters:      task_id -  (input) The id of the task whose name is being
+**                  sought. GKI_MAX_TASKS is passed to get the name of the
+**                  currently running task.
+**
+** Returns          pointer to task name
+**
+** NOTE             this function needs no customization
+**
+*******************************************************************************/
+INT8 *GKI_map_taskname (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_map_taskname %d", task_id);
+
+    if (task_id < GKI_MAX_TASKS)
+    {
+        GKI_TRACE_2("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
+         return (gki_cb.com.OSTName[task_id]);
+    }
+    else if (task_id == GKI_MAX_TASKS )
+    {
+        return (gki_cb.com.OSTName[GKI_get_taskid()]);
+    }
+    else
+    {
+        return "BAD";
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_enable
+**
+** Description      This function enables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+void GKI_enable (void)
+{
+    GKI_TRACE_0("GKI_enable");
+    pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
+/* 	pthread_mutex_xx is nesting save, no need for this: already_disabled = 0; */
+    GKI_TRACE_0("Leaving GKI_enable");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_disable
+**
+** Description      This function disables interrupts.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_disable (void)
+{
+    //GKI_TRACE_0("GKI_disable");
+
+/*	pthread_mutex_xx is nesting save, no need for this: if (!already_disabled) {
+    already_disabled = 1; */
+    		pthread_mutex_lock(&gki_cb.os.GKI_mutex);
+/*  } */
+    //GKI_TRACE_0("Leaving GKI_disable");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_exception
+**
+** Description      This function throws an exception.
+**                  This is normally only called for a nonrecoverable error.
+**
+** Parameters:      code    -  (input) The code for the error
+**                  msg     -  (input) The message that has to be logged
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void GKI_exception (UINT16 code, char *msg)
+{
+    UINT8 task_id;
+    int i = 0;
+
+    GKI_TRACE_ERROR_0( "GKI_exception(): Task State Table");
+
+    for(task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+    {
+        GKI_TRACE_ERROR_3( "TASK ID [%d] task name [%s] state [%d]",
+                         task_id,
+                         gki_cb.com.OSTName[task_id],
+                         gki_cb.com.OSRdyTbl[task_id]);
+    }
+
+    GKI_TRACE_ERROR_2("GKI_exception %d %s", code, msg);
+    GKI_TRACE_ERROR_0( "********************************************************************");
+    GKI_TRACE_ERROR_2( "* GKI_exception(): %d %s", code, msg);
+    GKI_TRACE_ERROR_0( "********************************************************************");
+
+#if (GKI_DEBUG == TRUE)
+    GKI_disable();
+
+    if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION)
+    {
+        EXCEPTION_T *pExp;
+
+        pExp =  &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
+        pExp->type = code;
+        pExp->taskid = GKI_get_taskid();
+        strncpy((char *)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
+    }
+
+    GKI_enable();
+#endif
+
+    GKI_TRACE_ERROR_2("GKI_exception %d %s done", code, msg);
+
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_get_time_stamp
+**
+** Description      This function formats the time into a user area
+**
+** Parameters:      tbuf -  (output) the address to the memory containing the
+**                  formatted time
+**
+** Returns          the address of the user area containing the formatted time
+**                  The format of the time is ????
+**
+** NOTE             This function is only called by OBEX.
+**
+*******************************************************************************/
+INT8 *GKI_get_time_stamp (INT8 *tbuf)
+{
+    UINT32 ms_time;
+    UINT32 s_time;
+    UINT32 m_time;
+    UINT32 h_time;
+    INT8   *p_out = tbuf;
+
+    gki_cb.com.OSTicks = times(0);
+    ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
+    s_time  = ms_time/100;   /* 100 Ticks per second */
+    m_time  = s_time/60;
+    h_time  = m_time/60;
+
+    ms_time -= s_time*100;
+    s_time  -= m_time*60;
+    m_time  -= h_time*60;
+
+    *p_out++ = (INT8)((h_time / 10) + '0');
+    *p_out++ = (INT8)((h_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((m_time / 10) + '0');
+    *p_out++ = (INT8)((m_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((s_time / 10) + '0');
+    *p_out++ = (INT8)((s_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out++ = (INT8)((ms_time / 10) + '0');
+    *p_out++ = (INT8)((ms_time % 10) + '0');
+    *p_out++ = ':';
+    *p_out   = 0;
+
+    return (tbuf);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_register_mempool
+**
+** Description      This function registers a specific memory pool.
+**
+** Parameters:      p_mem -  (input) pointer to the memory pool
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If your OS has different memory pools, you
+**                  can tell GKI the pool to use by calling this function.
+**
+*******************************************************************************/
+void GKI_register_mempool (void *p_mem)
+{
+    gki_cb.com.p_user_mempool = p_mem;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_malloc
+**
+** Description      This function allocates memory
+**
+** Parameters:      size -  (input) The size of the memory that has to be
+**                  allocated
+**
+** Returns          the address of the memory allocated, or NULL if failed
+**
+** NOTE             This function is called by the Widcomm stack when
+**                  dynamic memory allocation is used. (see dyn_mem.h)
+**
+*******************************************************************************/
+void *GKI_os_malloc (UINT32 size)
+{
+    return (malloc(size));
+}
+
+/*******************************************************************************
+**
+** Function         GKI_os_free
+**
+** Description      This function frees memory
+**
+** Parameters:      size -  (input) The address of the memory that has to be
+**                  freed
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. It is only called from within GKI if dynamic
+**
+*******************************************************************************/
+void GKI_os_free (void *p_mem)
+{
+    if(p_mem != NULL)
+		free(p_mem);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_suspend_task()
+**
+** Description      This function suspends the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to suspended
+**
+** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension capability,
+**                  put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_suspend_task (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_suspend_task %d - NOT implemented", task_id);
+
+
+    GKI_TRACE_1("GKI_suspend_task %d done", task_id);
+
+    return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_resume_task()
+**
+** Description      This function resumes the task specified in the argument.
+**
+** Parameters:      task_id  - (input) the id of the task that has to resumed
+**
+** Returns          GKI_SUCCESS if all OK
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to implement task suspension capability,
+**                  put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_resume_task (UINT8 task_id)
+{
+    GKI_TRACE_1("GKI_resume_task %d - NOT implemented", task_id);
+
+
+    GKI_TRACE_1("GKI_resume_task %d done", task_id);
+
+    return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_exit_task
+**
+** Description      This function is called to stop a GKI task.
+**
+** Parameters:      task_id  - (input) the id of the task that has to be stopped
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put specific code here to kill a task.
+**
+*******************************************************************************/
+void GKI_exit_task (UINT8 task_id)
+{
+    GKI_disable();
+    gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
+
+    /* Destroy mutex and condition variable objects */
+    pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
+    pthread_cond_destroy (&gki_cb.os.thread_evt_cond[task_id]);
+    pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
+    pthread_cond_destroy (&gki_cb.os.thread_timeout_cond[task_id]);
+
+    GKI_enable();
+
+	//GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+    GKI_TRACE_1("GKI_exit_task %d done", task_id);
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_sched_lock
+**
+** Description      This function is called by tasks to disable scheduler
+**                  task context switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to disable context switching.
+**
+*******************************************************************************/
+void GKI_sched_lock(void)
+{
+    GKI_TRACE_0("GKI_sched_lock");
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         GKI_sched_unlock
+**
+** Description      This function is called by tasks to enable scheduler switching.
+**
+** Returns          void
+**
+** NOTE             This function is NOT called by the Widcomm stack and
+**                  profiles. If you want to use it in your own implementation,
+**                  put code here to tell the OS to re-enable context switching.
+**
+*******************************************************************************/
+void GKI_sched_unlock(void)
+{
+    GKI_TRACE_0("GKI_sched_unlock");
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftdown
+**
+** Description      shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount)
+{
+    register UINT8 *ps = p_mem + len - 1;
+    register UINT8 *pd = ps + shift_amount;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function         GKI_shiftup
+**
+** Description      shift memory up (to delete a record)
+**
+*******************************************************************************/
+void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len)
+{
+    register UINT8 *ps = p_src;
+    register UINT8 *pd = p_dest;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd++ = *ps++;
+}
+
+
diff --git a/src/hal/include/gki_hal_target.h b/src/hal/include/gki_hal_target.h
new file mode 100644
index 0000000..9714348
--- /dev/null
+++ b/src/hal/include/gki_hal_target.h
@@ -0,0 +1,256 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 GKI_HAL_TARGET_H
+#define GKI_HAL_TARGET_H
+
+#ifdef BUILDCFG
+#include "buildcfg_hal.h"
+#endif
+
+#include "data_types.h"
+
+/* Define export prefixes for modules exported by HAL */
+#ifndef GKI_API
+#define GKI_API
+#endif
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API
+#endif
+
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef NFC_HAL_TASK
+#define NFC_HAL_TASK                0
+#endif
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS               1
+#endif
+
+/******************************************************************************
+**
+** Timer configuration
+**
+******************************************************************************/
+
+/* The number of GKI timers in the software system. */
+#ifndef GKI_NUM_TIMERS
+#define GKI_NUM_TIMERS              2
+#endif
+
+/* A conversion value for translating ticks to calculate GKI timer.  */
+#ifndef TICKS_PER_SEC
+#define TICKS_PER_SEC               100
+#endif
+
+/************************************************************************
+**  Utility macros converting ticks to time with user define OS ticks per sec
+**/
+#ifndef GKI_MS_TO_TICKS
+#define GKI_MS_TO_TICKS(x)   ((x) / (1000 / TICKS_PER_SEC))
+#endif
+
+#ifndef GKI_SECS_TO_TICKS
+#define GKI_SECS_TO_TICKS(x)   ((x) * (TICKS_PER_SEC))
+#endif
+
+#ifndef GKI_TICKS_TO_MS
+#define GKI_TICKS_TO_MS(x)   ((x) * 1000 / TICKS_PER_SEC)
+#endif
+
+#ifndef GKI_TICKS_TO_SECS
+#define GKI_TICKS_TO_SECS(x)   ((x) / TICKS_PER_SEC)
+#endif
+
+
+
+/* TICK per second from OS (OS dependent change this macro accordingly to various OS) */
+#ifndef OS_TICKS_PER_SEC
+#define OS_TICKS_PER_SEC               1000
+#endif
+
+/************************************************************************
+**  Utility macros converting ticks to time with user define OS ticks per sec
+**/
+
+#ifndef GKI_OS_TICKS_TO_MS
+#define GKI_OS_TICKS_TO_MS(x)   ((x) * 1000 / OS_TICKS_PER_SEC)
+#endif
+
+
+#ifndef GKI_OS_TICKS_TO_SECS
+#define GKI_OS_TICKS_TO_SECS(x)   ((x) / OS_TICKS_PER_SEC))
+#endif
+
+
+/* delay in ticks before stopping system tick. */
+#ifndef GKI_DELAY_STOP_SYS_TICK
+#define GKI_DELAY_STOP_SYS_TICK     10
+#endif
+
+/* Option to guarantee no preemption during timer expiration (most system don't need this) */
+#ifndef GKI_TIMER_LIST_NOPREEMPT
+#define GKI_TIMER_LIST_NOPREEMPT    FALSE
+#endif
+
+/******************************************************************************
+**
+** Buffer configuration
+**
+******************************************************************************/
+
+/* TRUE if GKI uses dynamic buffers. */
+#ifndef GKI_USE_DYNAMIC_BUFFERS
+#define GKI_USE_DYNAMIC_BUFFERS     FALSE
+#endif
+
+/* The size of the buffers in pool 0. */
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE               64
+#endif
+
+/* The number of buffers in buffer pool 0. */
+#ifndef GKI_BUF0_MAX
+#define GKI_BUF0_MAX                8
+#endif
+
+/* The ID of buffer pool 0. */
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0               0
+#endif
+
+/* The size of the buffers in pool 1. */
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE               288
+#endif
+
+/* The number of buffers in buffer pool 1. */
+#ifndef GKI_BUF1_MAX
+#define GKI_BUF1_MAX                8
+#endif
+
+/* The ID of buffer pool 1. */
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1               1
+#endif
+
+/* The size of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE
+#define GKI_MAX_BUF_SIZE            GKI_BUF1_SIZE
+#endif
+
+/* The pool ID of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE_POOL_ID
+#define GKI_MAX_BUF_SIZE_POOL_ID    GKI_POOL_ID_1
+#endif
+
+/* buffer size for USERIAL, it must large enough to hold NFC_HDR and max packet size */
+#ifndef USERIAL_POOL_BUF_SIZE
+#define USERIAL_POOL_BUF_SIZE       GKI_BUF1_SIZE
+#endif
+
+/* buffer pool ID for USERIAL */
+#ifndef USERIAL_POOL_ID
+#define USERIAL_POOL_ID             GKI_POOL_ID_1
+#endif
+
+#ifndef GKI_NUM_FIXED_BUF_POOLS
+#define GKI_NUM_FIXED_BUF_POOLS     2
+#endif
+
+/* The number of fixed and dynamic buffer pools */
+#ifndef GKI_NUM_TOTAL_BUF_POOLS
+#define GKI_NUM_TOTAL_BUF_POOLS     2
+#endif
+
+/* The buffer pool usage mask. */
+#ifndef GKI_DEF_BUFPOOL_PERM_MASK
+#define GKI_DEF_BUFPOOL_PERM_MASK   0xfff0
+#endif
+
+/* The buffer corruption check flag. */
+#ifndef GKI_ENABLE_BUF_CORRUPTION_CHECK
+#define GKI_ENABLE_BUF_CORRUPTION_CHECK TRUE
+#endif
+
+/* The GKI severe error macro. */
+#ifndef GKI_SEVERE
+#define GKI_SEVERE(code)
+#endif
+
+/* TRUE if GKI includes debug functionality. */
+#ifndef GKI_DEBUG
+#define GKI_DEBUG                   FALSE
+#endif
+
+/* Maximum number of exceptions logged. */
+#ifndef GKI_MAX_EXCEPTION
+#define GKI_MAX_EXCEPTION           8
+#endif
+
+/* Maximum number of chars stored for each exception message. */
+#ifndef GKI_MAX_EXCEPTION_MSGLEN
+#define GKI_MAX_EXCEPTION_MSGLEN    64
+#endif
+
+#ifndef GKI_SEND_MSG_FROM_ISR
+#define GKI_SEND_MSG_FROM_ISR    FALSE
+#endif
+
+
+/* GKI Trace Macros */
+#define GKI_TRACE_0(m)                          LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m)
+#define GKI_TRACE_1(m,p1)                       LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1)
+#define GKI_TRACE_2(m,p1,p2)                    LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2)
+#define GKI_TRACE_3(m,p1,p2,p3)                 LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3)
+#define GKI_TRACE_4(m,p1,p2,p3,p4)              LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4)
+#define GKI_TRACE_5(m,p1,p2,p3,p4,p5)           LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_6(m,p1,p2,p3,p4,p5,p6)        LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4,p5,p6)
+
+#define GKI_TRACE_ERROR_0(m)                    LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m)
+#define GKI_TRACE_ERROR_1(m,p1)                 LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1)
+#define GKI_TRACE_ERROR_2(m,p1,p2)              LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2)
+#define GKI_TRACE_ERROR_3(m,p1,p2,p3)           LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3)
+#define GKI_TRACE_ERROR_4(m,p1,p2,p3,p4)        LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4)
+#define GKI_TRACE_ERROR_5(m,p1,p2,p3,p4,p5)     LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_ERROR_6(m,p1,p2,p3,p4,p5,p6)  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* GKI_TARGET_H */
diff --git a/src/hal/include/nci_defs.h b/src/hal/include/nci_defs.h
new file mode 100644
index 0000000..befffd9
--- /dev/null
+++ b/src/hal/include/nci_defs.h
@@ -0,0 +1,851 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the definition from NCI specification
+ *
+ ******************************************************************************/
+
+#ifndef NFC_NCI_DEFS_H
+#define NFC_NCI_DEFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NCI_BRCM_CO_ID              0x2E
+
+/* Define the message header size for all NCI Commands and Notifications.
+*/
+#define NCI_MSG_HDR_SIZE        3   /* per NCI spec */
+#define NCI_DATA_HDR_SIZE       3   /* per NCI spec */
+#define NCI_MAX_PAYLOAD_SIZE    0xFE
+#define NCI_MAX_CTRL_SIZE       0xFF/* max control message size */
+#define NCI_CTRL_INIT_SIZE      32  /* initial NFCC control payload size */
+#define NCI_MAX_VSC_SIZE        0xFF
+#define NCI_VSC_MSG_HDR_SIZE    12  /* NCI header (3) + callback function pointer(8; use 8 to be safe) + HCIT (1 byte) */
+#define NCI_TL_SIZE             2
+
+#define NCI_ISO_DEP_MAX_INFO      253   /* Max frame size (256) - Prologue (1) - Epilogue (2) in ISO-DEP, CID and NAD are not used*/
+#define NCI_NFC_DEP_MAX_DATA      251   /* Max payload (254) - Protocol Header (3) in NFC-DEP, DID and NAD are not used */
+
+/* NCI Command and Notification Format:
+ * 3 byte message header:
+ * byte 0: MT PBF GID
+ * byte 1: OID
+ * byte 2: Message Length */
+/* MT: Message Type (byte 0) */
+#define NCI_MT_MASK         0xE0
+#define NCI_MT_SHIFT        5
+#define NCI_MT_DATA         0x00
+#define NCI_MT_CMD          1   /* (NCI_MT_CMD << NCI_MT_SHIFT) = 0x20 */
+#define NCI_MT_RSP          2   /* (NCI_MT_RSP << NCI_MT_SHIFT) = 0x40 */
+#define NCI_MT_NTF          3   /* (NCI_MT_NTF << NCI_MT_SHIFT) = 0x60 */
+#define NCI_MT_CFG          4   /* (NCI_MT_CFG << NCI_MT_SHIFT) = 0x80 */
+
+#define NCI_MTS_CMD         0x20
+#define NCI_MTS_RSP         0x40
+#define NCI_MTS_NTF         0x60
+#define NCI_MTS_CFG         0x80
+
+#define NCI_NTF_BIT         0x80     /* the tNFC_VS_EVT is a notification */
+#define NCI_RSP_BIT         0x40     /* the tNFC_VS_EVT is a response     */
+
+/* for internal use only; not from specification */
+/* the following 2 flags are used in layer_specific for fragmentation/reassembly of data packets */
+#define NCI_LS_DATA         0x00
+#define NCI_LS_DATA_PBF     0x01
+
+/* PBF: Packet Boundary Flag (byte 0) */
+#define NCI_PBF_MASK        0x10
+#define NCI_PBF_SHIFT       4
+#define NCI_PBF_NO_OR_LAST  0x00    /* not fragmented or last fragment */
+#define NCI_PBF_ST_CONT     0x10    /* start or continuing fragment */
+
+/* GID: Group Identifier (byte 0) */
+#define NCI_GID_MASK        0x0F
+#define NCI_GID_SHIFT       0
+#define NCI_GID_CORE        0x00    /* 0000b NCI Core group */
+#define NCI_GID_RF_MANAGE   0x01    /* 0001b RF Management group */
+#define NCI_GID_EE_MANAGE   0x02    /* 0010b NFCEE Management group */
+#define NCI_GID_PROP        0x0F    /* 1111b Proprietary */
+/* 0111b - 1110b RFU */
+
+/* OID: Opcode Identifier (byte 1) */
+#define NCI_OID_MASK        0x3F
+#define NCI_OID_SHIFT       0
+
+/* For routing */
+#define NCI_DH_ID               0   /* for DH */
+/* To identify the loopback test */
+#define NCI_TEST_ID             0xFE/* for loopback test */
+
+/* Destination Type */
+#define NCI_DEST_TYPE_NFCC      1   /* NFCC - loopback */
+#define NCI_DEST_TYPE_REMOTE    2   /* Remote NFC Endpoint */
+#define NCI_DEST_TYPE_NFCEE     3   /* NFCEE */
+
+/* builds byte0 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR0(p, mt, gid) \
+    *(p)++ = (UINT8) (((mt) << NCI_MT_SHIFT) | (gid));
+
+#define NCI_MSG_PBLD_HDR0(p, mt, pbf, gid) \
+    *(p)++ = (UINT8) (((mt) << NCI_MT_SHIFT) | ((pbf) << NCI_PBF_SHIFT) | (gid));
+
+/* builds byte1 of NCI Command and Notification packet */
+#define NCI_MSG_BLD_HDR1(p, oid) \
+    *(p)++ = (UINT8) (((oid) << NCI_OID_SHIFT));
+
+/* parse byte0 of NCI packet */
+#define NCI_MSG_PRS_HDR0(p, mt, pbf, gid) \
+    mt = (*(p) & NCI_MT_MASK) >> NCI_MT_SHIFT; \
+    pbf = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT; \
+    gid = *(p)++ & NCI_GID_MASK;
+
+/* parse MT and PBF bits of NCI packet */
+#define NCI_MSG_PRS_MT_PBF(p, mt, pbf) \
+    mt = (*(p) & NCI_MT_MASK) >> NCI_MT_SHIFT; \
+    pbf = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT;
+
+/* parse byte1 of NCI Cmd/Ntf */
+#define NCI_MSG_PRS_HDR1(p, oid) \
+    oid = (*(p) & NCI_OID_MASK); (p)++;
+
+/* NCI Data Format:
+ * byte 0: MT(0) PBF CID
+ * byte 1: RFU
+ * byte 2: Data Length */
+/* CID: Connection Identifier (byte 0) 1-0xF Dynamically assigned (by NFCC), 0 is predefined  */
+#define NCI_CID_MASK        0x0F
+
+/* builds 3-byte message header of NCI Data packet */
+#define NCI_DATA_BLD_HDR(p, cid, len) \
+    *(p)++ = (UINT8) (cid); *(p)++ = 0; *(p)++ = (UINT8) (len);
+
+#define NCI_DATA_PBLD_HDR(p, pbf, cid, len) \
+    *(p)++ = (UINT8) (((pbf) << NCI_PBF_SHIFT) | (cid)); *(p)++=0; *(p)++ = (len);
+
+#define NCI_DATA_PRS_HDR(p, pbf, cid, len) \
+    (pbf) = (*(p) & NCI_PBF_MASK) >> NCI_PBF_SHIFT; (cid) = (*(p) & NCI_CID_MASK); p++; p++; (len) = *(p)++;
+
+
+/* Logical target ID 0x01-0xFE */
+
+
+
+/* Status Codes */
+#define NCI_STATUS_OK                   0x00
+#define NCI_STATUS_REJECTED             0x01
+#define NCI_STATUS_MESSAGE_CORRUPTED    0x02
+#define NCI_STATUS_BUFFER_FULL          0xE0
+#define NCI_STATUS_FAILED               0x03
+#define NCI_STATUS_NOT_INITIALIZED      0x04
+#define NCI_STATUS_SYNTAX_ERROR         0x05
+#define NCI_STATUS_SEMANTIC_ERROR       0x06
+#define NCI_STATUS_UNKNOWN_GID          0x07
+#define NCI_STATUS_UNKNOWN_OID          0x08
+#define NCI_STATUS_INVALID_PARAM        0x09
+#define NCI_STATUS_MSG_SIZE_TOO_BIG     0x0A
+/* discovery */
+#define NCI_STATUS_ALREADY_STARTED      0xA0
+#define NCI_STATUS_ACTIVATION_FAILED    0xA1
+#define NCI_STATUS_TEAR_DOWN            0xA2
+/* RF Interface */
+#define NCI_STATUS_RF_TRANSMISSION_ERR  0xB0
+#define NCI_STATUS_RF_PROTOCOL_ERR      0xB1
+#define NCI_STATUS_TIMEOUT              0xB2
+/* NFCEE Interface */
+#define NCI_STATUS_EE_INTF_ACTIVE_FAIL  0xC0
+#define NCI_STATUS_EE_TRANSMISSION_ERR  0xC1
+#define NCI_STATUS_EE_PROTOCOL_ERR      0xC2
+#define NCI_STATUS_EE_TIMEOUT           0xC3
+
+
+typedef UINT8 tNCI_STATUS;
+
+/* RF Technologies */
+#define NCI_RF_TECHNOLOGY_A             0x00
+#define NCI_RF_TECHNOLOGY_B             0x01
+#define NCI_RF_TECHNOLOGY_F             0x02
+#define NCI_RF_TECHNOLOGY_15693         0x03
+
+/* Bit Rates */
+#define NCI_BIT_RATE_106                0x00/* 106 kbit/s */
+#define NCI_BIT_RATE_212                0x01/* 212 kbit/s */
+#define NCI_BIT_RATE_424                0x02/* 424 kbit/s */
+#define NCI_BIT_RATE_848                0x03/* 848 Kbit/s */
+#define NCI_BIT_RATE_1696               0x04/* 1696 Kbit/s*/
+#define NCI_BIT_RATE_3392               0x05/* 3392 Kbit/s*/
+#define NCI_BIT_RATE_6784               0x06/* 6784 Kbit/s*/
+
+/**********************************************
+ * NCI Core Group Opcode        - 0
+ **********************************************/
+#define NCI_MSG_CORE_RESET              0
+#define NCI_MSG_CORE_INIT               1
+#define NCI_MSG_CORE_SET_CONFIG         2
+#define NCI_MSG_CORE_GET_CONFIG         3
+#define NCI_MSG_CORE_CONN_CREATE        4
+#define NCI_MSG_CORE_CONN_CLOSE         5
+#define NCI_MSG_CORE_CONN_CREDITS       6
+#define NCI_MSG_CORE_GEN_ERR_STATUS     7
+#define NCI_MSG_CORE_INTF_ERR_STATUS    8
+
+/**********************************************
+ * RF MANAGEMENT Group Opcode    - 1
+ **********************************************/
+#define NCI_MSG_RF_DISCOVER_MAP         0
+#define NCI_MSG_RF_SET_ROUTING          1
+#define NCI_MSG_RF_GET_ROUTING          2
+#define NCI_MSG_RF_DISCOVER             3
+#define NCI_MSG_RF_DISCOVER_SELECT      4
+#define NCI_MSG_RF_INTF_ACTIVATED       5
+#define NCI_MSG_RF_DEACTIVATE           6
+#define NCI_MSG_RF_FIELD                7
+#define NCI_MSG_RF_T3T_POLLING          8
+#define NCI_MSG_RF_EE_ACTION            9
+#define NCI_MSG_RF_EE_DISCOVERY_REQ     10
+#define NCI_MSG_RF_PARAMETER_UPDATE     11
+
+/**********************************************
+ * NFCEE MANAGEMENT Group Opcode - 2
+ **********************************************/
+#define NCI_MSG_NFCEE_DISCOVER          0
+#define NCI_MSG_NFCEE_MODE_SET          1
+
+/**********************************************
+ * NCI Proprietary  Group       - F
+ **********************************************/
+
+/**********************************************
+ * NCI Core Group Params
+ **********************************************/
+#define NCI_CORE_PARAM_SIZE_RESET       0x01
+#define NCI_CORE_PARAM_SIZE_RESET_RSP   0x03
+#define NCI_CORE_PARAM_SIZE_RESET_NTF   0x02
+
+#define NCI_CORE_PARAM_SIZE_INIT        0x00 /* no payload */
+#define NCI_CORE_PARAM_SIZE_INIT_RSP    0x11
+#define NCI_CORE_INIT_RSP_OFFSET_NUM_INTF   0x05
+
+#define NCI_CORE_PARAM_SIZE_SET_CONFIG_RSP   0x02    /* Status (1 octet) and number of params */
+
+
+/* octet 0 */
+#define NCI_FEAT_DISCOVERY_FREG     0x00000001
+#define NCI_FEAT_DISCOVERY_CFGM     0x00000006
+/* octet 1 */
+#define NCI_FEAT_TECHNOLOGY_ROUTING 0x00000200
+#define NCI_FEAT_PROTOCOL_ROUTING   0x00000400
+#define NCI_FEAT_AID_ROUTING        0x00000800
+/* octet 2 */
+#define NCI_FEAT_BATTERY_OFF_MD     0x00010000
+#define NCI_FEAT_SWITCH_OFF_MD      0x00020000
+
+
+/* supported Interfaces */
+#define NCI_SUP_INTF_FRAME           0x0001
+#define NCI_SUP_INTF_ISO_DEP         0x0002
+#define NCI_SUP_INTF_NFC_DEP         0x0004
+
+
+
+#define NCI_CORE_PARAM_SIZE_CON_CREATE      0x02 /* handle, num_tlv, (tlv) */
+#define NCI_CORE_PARAM_SIZE_CON_CREATE_RSP  0x04 /* status, size, credits, conn_id */
+#define NCI_CON_CREATE_TAG_EE_INTF          0x00 /* old */
+#define NCI_CON_CREATE_TAG_RF_DISC_ID       0x00
+#define NCI_CON_CREATE_TAG_NFCEE_VAL        0x01
+
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE       0x01 /* Conn ID (1 octet) */
+#define NCI_CORE_PARAM_SIZE_CON_CLOSE_RSP   0x01 /* Status (1 octet) */
+
+#define NCI_CORE_PARAM_SIZE_RF_FIELD_NTF            0x01 /* RF Field Status (1 octet) */
+
+#define NCI_RESET_TYPE_KEEP_CFG         0x00  /* Keep the NCI configuration (if possible) and perform NCI initialization. */
+#define NCI_RESET_TYPE_RESET_CFG        0x01  /* Reset the NCI configuration, and perform NCI initialization. */
+
+#define NCI_RESET_STATUS_KEPT_CFG       0x00  /* NCI Configuration has been kept  */
+#define NCI_RESET_STATUS_RESET_CFG      0x01  /* NCI Configuration has been reset */
+
+#define NCI_RF_STS_NO_REMOTE    0x00 /* No operating field generated by remote device  */
+#define NCI_RF_STS_REMOTE       0x01 /* Operating field generated by remote device  */
+
+
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE      0x01 /* Discovery Action (1 octet) */
+#define NCI_PARAM_SIZE_DISCOVER_NFCEE_RSP  0x02 /* Status (1 octet)Number of NFCEEs (1 octet) */
+
+#define NCI_DISCOVER_ACTION_DISABLE     0
+#define NCI_DISCOVER_ACTION_ENABLE      1
+
+#define NCI_EE_DISCOVER_REQ_TYPE_LISTEN     0x01
+#define NCI_EE_DISCOVER_REQ_TYPE_POLL       0x02
+
+#define NCI_RF_PARAM_ID_TECH_N_MODE     0x00  /* RF Technology and Mode   */
+#define NCI_RF_PARAM_ID_TX_BIT_RATE     0x01  /* Transmit Bit Rate        */
+#define NCI_RF_PARAM_ID_RX_BIT_RATE     0x02  /* Receive Bit Rate         */
+#define NCI_RF_PARAM_ID_B_DATA_EX_PARAM 0x03  /* B Data Exchange config param */
+
+
+#define NCI_NFCEE_INTERFACE_APDU         0x00
+#define NCI_NFCEE_INTERFACE_HCI_ACCESS   0x01
+#define NCI_NFCEE_INTERFACE_T3T          0x02
+#define NCI_NFCEE_INTERFACE_TRANSPARENT  0x03
+#define NCI_NFCEE_INTERFACE_PROPRIETARY  0x80
+
+#define NCI_NFCEE_STS_CONN_ACTIVE       0x00
+#define NCI_NFCEE_STS_CONN_INACTIVE     0x01
+#define NCI_NFCEE_STS_REMOVED           0x02
+#define NCI_NUM_NFCEE_STS               3
+
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET      0x02 /* Logical Target ID (1 octet)NFCEE Mode (1 octet) */
+#define NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET_RSP  0x01 /* Status (1 octet) */
+
+#define NCI_NFCEE_MD_DEACTIVATE         0x00    /* Deactivate the connected NFCEE */
+#define NCI_NFCEE_MD_ACTIVATE           0x01    /* Activate the connected NFCEE */
+#define NCI_NUM_NFCEE_MODE              2
+
+/**********************************************
+ * NCI Deactivation Type
+ **********************************************/
+#define NCI_DEACTIVATE_TYPE_IDLE        0   /* Idle Mode     */
+#define NCI_DEACTIVATE_TYPE_SLEEP       1   /* Sleep Mode    */
+#define NCI_DEACTIVATE_TYPE_SLEEP_AF    2   /* Sleep_AF Mode */
+#define NCI_DEACTIVATE_TYPE_DISCOVERY   3   /* Discovery     */
+
+/**********************************************
+ * NCI Deactivation Reasons
+ **********************************************/
+#define NCI_DEACTIVATE_REASON_DH_REQ        0   /* DH Request       */
+#define NCI_DEACTIVATE_REASON_ENDPOINT_REQ  1   /* Endpoint Request */
+#define NCI_DEACTIVATE_REASON_RF_LINK_LOSS  2   /* RF Link Loss     */
+#define NCI_DEACTIVATE_REASON_NFCB_BAD_AFI  3   /* NFC-B Bad AFI    */
+
+ /**********************************************
+ * NCI Interface Mode
+ **********************************************/
+#define NCI_INTERFACE_MODE_POLL             1
+#define NCI_INTERFACE_MODE_LISTEN           2
+#define NCI_INTERFACE_MODE_POLL_N_LISTEN    3
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_EE_DIRECT_RF      0
+#define NCI_INTERFACE_FRAME             1
+#define NCI_INTERFACE_ISO_DEP           2
+#define NCI_INTERFACE_NFC_DEP           3
+#define NCI_INTERFACE_MAX               NCI_INTERFACE_NFC_DEP
+#define NCI_INTERFACE_FIRST_VS          0x80
+typedef UINT8 tNCI_INTF_TYPE;
+
+/**********************************************
+ * NCI RF Management / DISCOVERY Group Params
+ **********************************************/
+#define NCI_DISCOVER_PARAM_SIZE_RSP     0x01
+
+#define NCI_DISCOVER_PARAM_SIZE_SELECT      0x03 /* ID, protocol, interface */
+#define NCI_DISCOVER_PARAM_SIZE_SELECT_RSP  0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_STOP        0x00 /*  */
+#define NCI_DISCOVER_PARAM_SIZE_STOP_RSP    0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT       0x01 /* type */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_RSP   0x01 /* Status (1 octet) */
+#define NCI_DISCOVER_PARAM_SIZE_DEACT_NTF   0x01 /* type */
+
+/**********************************************
+ * Supported Protocols
+ **********************************************/
+#define NCI_PROTOCOL_UNKNOWN            0x00
+#define NCI_PROTOCOL_T1T                0x01
+#define NCI_PROTOCOL_T2T                0x02
+#define NCI_PROTOCOL_T3T                0x03
+#define NCI_PROTOCOL_ISO_DEP            0x04
+#define NCI_PROTOCOL_NFC_DEP            0x05
+/**********************************************
+ * Proprietary Protocols
+ **********************************************/
+#ifndef NCI_PROTOCOL_18092_ACTIVE
+#define NCI_PROTOCOL_18092_ACTIVE       0x80
+#endif
+#ifndef NCI_PROTOCOL_B_PRIME
+#define NCI_PROTOCOL_B_PRIME            0x81
+#endif
+#ifndef NCI_PROTOCOL_DUAL
+#define NCI_PROTOCOL_DUAL               0x82
+#endif
+#ifndef NCI_PROTOCOL_15693
+#define NCI_PROTOCOL_15693              0x83
+#endif
+#ifndef NCI_PROTOCOL_KOVIO
+#define NCI_PROTOCOL_KOVIO              0x8a
+#endif
+
+
+/* Discovery Types/Detected Technology and Mode */
+#define NCI_DISCOVERY_TYPE_POLL_A               0x00
+#define NCI_DISCOVERY_TYPE_POLL_B               0x01
+#define NCI_DISCOVERY_TYPE_POLL_F               0x02
+#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE        0x03
+#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE        0x05
+#define NCI_DISCOVERY_TYPE_POLL_B_PRIME         0x74
+#define NCI_DISCOVERY_TYPE_POLL_KOVIO           0x77
+#define NCI_DISCOVERY_TYPE_LISTEN_A             0x80
+#define NCI_DISCOVERY_TYPE_LISTEN_B             0x81
+#define NCI_DISCOVERY_TYPE_LISTEN_F             0x82
+#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE      0x83
+#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE      0x85
+#define NCI_DISCOVERY_TYPE_LISTEN_B_PRIME       0xF4
+#define NCI_DISCOVERY_TYPE_POLL_ISO15693        0x06
+#define NCI_DISCOVERY_TYPE_LISTEN_ISO15693      0x86
+#define NCI_DISCOVERY_TYPE_MAX  NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+
+typedef UINT8 tNCI_DISCOVERY_TYPE;
+
+#define NCI_EE_TRIG_7816_SELECT         0x00
+#define NCI_EE_TRIG_RF_PROTOCOL         0x01
+#define NCI_EE_TRIG_RF_TECHNOLOGY       0x02
+#define NCI_EE_TRIG_APP_INIT            0x10
+
+#define NCI_EE_ACT_TAG_AID              0xC0        /* AID                 */
+#define NCI_EE_ACT_TAG_PROTO            0xC1        /* RF protocol         */
+#define NCI_EE_ACT_TAG_TECH             0xC2        /* RF technology       */
+#define NCI_EE_ACT_TAG_DATA             0xC3        /* hex data for app    */
+#define NCI_EE_ACT_TAG_DEBUG            0xC4        /* debug trace         */
+
+#define NCI_ROUTE_TAG_TECH              0x00        /* Technology based routing  */
+#define NCI_ROUTE_TAG_PROTO             0x01        /* Protocol based routing  */
+#define NCI_ROUTE_TAG_AID               0x02        /* AID routing */
+
+#define NCI_ROUTE_PWR_STATE_ON          0x01        /* The device is on */
+#define NCI_ROUTE_PWR_STATE_SWITCH_OFF  0x02        /* The device is switched off */
+#define NCI_ROUTE_PWR_STATE_BATT_OFF    0x04        /* The device's battery is removed */
+
+#define NCI_NFCEE_TAG_HW_ID             0x00       /* Hardware / Registration Identification  */
+#define NCI_NFCEE_TAG_ATR_BYTES         0x01       /* ATR Bytes  */
+#define NCI_NFCEE_TAG_T3T_INFO          0x02       /* T3T Command Set Interface Supplementary Info */
+#define NCI_NFCEE_TAG_HCI_HOST_ID       0xA0       /* HCI host ID */
+
+#define NCI_DISCOVER_NTF_LAST           0x00
+#define NCI_DISCOVER_NTF_LAST_ABORT     0x01
+#define NCI_DISCOVER_NTF_MORE           0x02
+
+
+/* NCI RF Management Group Params */
+#define NCI_RF_PARAM_SIZE_T3T_POLLING   0x04        /* System Code, RC, TSN */
+
+/**********************************************
+ * NCI Parameter IDs
+ **********************************************/
+
+#define NCI_PARAM_ID_TOTAL_DURATION     0x00
+#define NCI_PARAM_ID_CON_DEVICES_LIMIT  0x01
+#define NCI_PARAM_ID_PA_BAILOUT         0x08
+#define NCI_PARAM_ID_PB_AFI             0x10
+#define NCI_PARAM_ID_PB_BAILOUT         0x11
+#define NCI_PARAM_ID_PB_ATTRIB_PARAM1   0x12
+#define NCI_PARAM_ID_PF_BIT_RATE        0x18
+#define NCI_PARAM_ID_PB_H_INFO          0x20
+#define NCI_PARAM_ID_PI_BIT_RATE        0x21
+
+#define NCI_PARAM_ID_BITR_NFC_DEP       0x28
+#define NCI_PARAM_ID_ATR_REQ_GEN_BYTES  0x29
+#define NCI_PARAM_ID_ATR_REQ_CONFIG     0x2A
+
+#define NCI_PARAM_ID_LA_BIT_FRAME_SDD   0x30
+#define NCI_PARAM_ID_LA_PLATFORM_CONFIG 0x31
+#define NCI_PARAM_ID_LA_SEL_INFO        0x32
+#define NCI_PARAM_ID_LA_NFCID1          0x33
+#define NCI_PARAM_ID_LB_SENSB_INFO      0x38
+#define NCI_PARAM_ID_LB_NFCID0          0x39
+#define NCI_PARAM_ID_LB_APPDATA         0x3A
+#define NCI_PARAM_ID_LB_SFGI            0x3B
+#define NCI_PARAM_ID_LB_ADC_FO          0x3C
+#define NCI_PARAM_ID_LB_PROTOCOL        NCI_PARAM_ID_LB_SENSB_INFO
+
+#define NCI_PARAM_ID_LF_T3T_ID1         0x40
+#define NCI_PARAM_ID_LF_T3T_ID2         0x41
+#define NCI_PARAM_ID_LF_T3T_ID3         0x42
+#define NCI_PARAM_ID_LF_T3T_ID4         0x43
+#define NCI_PARAM_ID_LF_T3T_ID5         0x44
+#define NCI_PARAM_ID_LF_T3T_ID6         0x45
+#define NCI_PARAM_ID_LF_T3T_ID7         0x46
+#define NCI_PARAM_ID_LF_T3T_ID8         0x47
+#define NCI_PARAM_ID_LF_T3T_ID9         0x48
+#define NCI_PARAM_ID_LF_T3T_ID10        0x49
+#define NCI_PARAM_ID_LF_T3T_ID11        0x4A
+#define NCI_PARAM_ID_LF_T3T_ID12        0x4B
+#define NCI_PARAM_ID_LF_T3T_ID13        0x4C
+#define NCI_PARAM_ID_LF_T3T_ID14        0x4D
+#define NCI_PARAM_ID_LF_T3T_ID15        0x4E
+#define NCI_PARAM_ID_LF_T3T_ID16        0x4F
+#define NCI_PARAM_ID_LF_PROTOCOL        0x50
+#define NCI_PARAM_ID_LF_T3T_PMM         0x51
+#define NCI_PARAM_ID_LF_T3T_MAX         0x52    /* max num of LF_T3T_ID supported by NFCC (1 for now) */
+#define NCI_PARAM_ID_LF_T3T_FLAGS2      0x53
+#define NCI_PARAM_ID_LF_CON_BITR_F      0x54
+#define NCI_PARAM_ID_FWI                0x58
+#define NCI_PARAM_ID_LA_HIST_BY         0x59
+#define NCI_PARAM_ID_LB_H_INFO_RSP      0x5A
+#define NCI_PARAM_ID_LI_BIT_RATE        0x5B
+
+#define NCI_PARAM_ID_WT                 0x60
+#define NCI_PARAM_ID_ATR_RES_GEN_BYTES  0x61
+#define NCI_PARAM_ID_ATR_RSP_CONFIG     0x62
+
+#define NCI_PARAM_ID_RF_FIELD_INFO      0x80
+#define NCI_PARAM_ID_RF_NFCEE_ACTION    0x81
+#define NCI_PARAM_ID_NFC_DEP_OP         0x82
+
+
+
+/* NCI_PARAM_ID_HOST_LISTEN_MASK (byte1 for DH, byte2 for UICC) */
+#define NCI_LISTEN_MASK_A               0x01 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_B               0x02 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_F               0x04 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE & 0x0F)) */
+#define NCI_LISTEN_MASK_A_ACTIVE        0x08 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE & 0x0F))  */
+#define NCI_LISTEN_MASK_B_PRIME         0x10 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_B_PRIME & 0x0F))   */
+#define NCI_LISTEN_MASK_F_ACTIVE        0x20 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE & 0x0F))  */
+#define NCI_LISTEN_MASK_ISO15693        0x40 /* (0x01 << (NCI_DISCOVERY_TYPE_LISTEN_ISO15693 & 0x0F))  */
+
+/* Type A Parameters */
+#define NCI_PARAM_PLATFORM_T1T      0x0C
+#define NCI_PARAM_SEL_INFO_ISODEP   0x20
+#define NCI_PARAM_SEL_INFO_NFCDEP   0x40
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_TOTAL_DURATION        2
+
+#define NCI_PARAM_LEN_PA_FSDI               1
+
+#define NCI_PARAM_LEN_LA_BIT_FRAME_SDD      1
+#define NCI_PARAM_LEN_LA_PLATFORM_CONFIG    1
+#define NCI_PARAM_LEN_LA_SEL_INFO           1
+
+#define NCI_PARAM_LEN_LB_SENSB_INFO         1
+#define NCI_PARAM_LEN_LB_NFCID0             4
+#define NCI_PARAM_LEN_LB_APPDATA            4
+#define NCI_PARAM_LEN_LB_ADC_FO             1
+
+#define NCI_PARAM_LEN_LF_PROTOCOL           1
+#define NCI_PARAM_LEN_LF_T3T_FLAGS2         2
+#define NCI_PARAM_LEN_LF_T3T_PMM            8
+#define NCI_PARAM_LEN_LF_T3T_ID            10
+
+#define NCI_PARAM_LEN_FWI                   1
+#define NCI_PARAM_LEN_WT                    1
+/* GEN_BYTES - variable */
+
+/* Listen protocol bits - NCI_PARAM_ID_LF_PROTOCOL and NCI_PARAM_ID_LB_SENSB_INFO */
+#define NCI_LISTEN_PROTOCOL_ISO_DEP     0x01
+#define NCI_LISTEN_PROTOCOL_NFC_DEP     0x02
+
+#define NCI_DISCOVER_PARAM_SIZE_TEST_RF       0x06
+
+
+/* LF_T3T_FLAGS2 listen bits all-disabled definition */
+#define NCI_LF_T3T_FLAGS2_ALL_DISABLED  0x0000
+#define NCI_LF_T3T_FLAGS2_ID1_ENABLED   0x0001
+
+typedef struct
+{
+    UINT16              addr;
+    UINT8               len;
+    UINT8               *data;
+} NCIP_T1T_SETMEM_CMD_t;
+
+typedef struct
+{
+    UINT8               status;
+} NCIP_T1T_SETMEM_RSP_t;
+
+typedef struct
+{
+    UINT16              addr;
+} NCIP_T1T_GETMEM_CMD_t;
+
+typedef struct
+{
+    UINT8               status;
+    UINT8               *data;
+} NCIP_T1T_GETMEM_RSP_t;
+
+typedef struct
+{
+    UINT8               hr0;
+    UINT8               hr1;
+} NCIP_T1T_SETHR_CMD_t;
+
+typedef struct
+{
+    UINT8               status;
+} NCIP_T1T_SETHR_RSP_t;
+
+
+#ifndef NCI_GET_CMD_BUF
+#if (!defined (HCI_USE_VARIABLE_SIZE_CMD_BUF) || (HCI_USE_VARIABLE_SIZE_CMD_BUF == FALSE))
+/* Allocate fixed-size buffer from HCI_CMD_POOL (default case) */
+#define NCI_GET_CMD_BUF(paramlen)    ((BT_HDR *) GKI_getpoolbuf (NFC_NCI_POOL_ID))
+#else
+/* Allocate smallest possible buffer (for platforms with limited RAM) */
+#define NCI_GET_CMD_BUF(paramlen)    ((BT_HDR *) GKI_getbuf ((UINT16) (BT_HDR_SIZE + NCI_MSG_HDR_SIZE + NCI_MSG_OFFSET_SIZE + (paramlen))))
+#endif
+#endif  /* NCI_GET_CMD_BUF */
+
+
+#define NCI_MAX_AID_LEN     16
+
+
+typedef struct
+{
+    UINT8   type;
+    UINT8   frequency;
+} tNCI_DISCOVER_PARAMS;
+
+typedef struct
+{
+    UINT8   protocol;
+    UINT8   mode;
+    UINT8   intf_type;
+} tNCI_DISCOVER_MAPS;
+
+#define NCI_NFCID1_MAX_LEN    10
+typedef struct
+{
+    UINT8       sens_res[2];/* SENS_RES Response (ATQA). Available after Technology Detection */
+    UINT8       nfcid1_len;    /* 4, 7 or 10 */
+    UINT8       nfcid1[NCI_NFCID1_MAX_LEN]; /* AKA NFCID1 */
+    UINT8       sel_rsp;    /* SEL_RSP (SAK) Available after Collision Resolution */
+} tNCI_RF_PA_PARAMS;
+
+
+#define NCI_MAX_SENSB_RES_LEN       12
+typedef struct
+{
+    UINT8       sensb_res_len;/* Length of SENSB_RES Response (Byte 2 - Byte 12 or 13) Available after Technology Detection */
+    UINT8       sensb_res[NCI_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+} tNCI_RF_PB_PARAMS;
+
+#define NCI_MAX_SENSF_RES_LEN       18
+#define NCI_SENSF_RES_OFFSET_PAD0   8
+#define NCI_SENSF_RES_OFFSET_RD     16
+#define NCI_NFCID2_LEN              8
+#define NCI_T3T_PMM_LEN             8
+#define NCI_SYSTEMCODE_LEN          2
+#define NCI_RF_F_UID_LEN            NCI_NFCID2_LEN
+#define NCI_MRTI_CHECK_INDEX        13
+#define NCI_MRTI_UPDATE_INDEX       14
+typedef struct
+{
+    UINT8       bit_rate;/* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+    UINT8       sensf_res_len;/* Length of SENSF_RES Response (Byte 2 - Byte 17 or 19) Available after Technology Detection */
+    UINT8       sensf_res[NCI_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+} tNCI_RF_PF_PARAMS;
+
+typedef struct
+{
+    UINT8       nfcid2[NCI_NFCID2_LEN];  /* NFCID2 generated by the Local NFCC for NFC-DEP Protocol.Available for Frame Interface  */
+} tNCI_RF_LF_PARAMS;
+
+typedef struct
+{
+    tNCI_DISCOVERY_TYPE     mode;
+    union
+    {
+        tNCI_RF_PA_PARAMS   pa;
+        tNCI_RF_PB_PARAMS   pb;
+        tNCI_RF_PF_PARAMS   pf;
+        tNCI_RF_LF_PARAMS   lf;
+    } param; /* Discovery Type specific parameters */
+} tNCI_RF_TECH_PARAMS;
+
+
+#ifndef NCI_MAX_ATS_LEN
+#define NCI_MAX_ATS_LEN             60
+#endif
+#ifndef NCI_MAX_HIS_BYTES_LEN
+#define NCI_MAX_HIS_BYTES_LEN       50
+#endif
+#ifndef NCI_MAX_GEN_BYTES_LEN
+#define NCI_MAX_GEN_BYTES_LEN       48
+#endif
+
+#define NCI_ATS_T0_INDEX            0
+#define NCI_ATS_TC_MASK             0x40
+#define NCI_ATS_TB_MASK             0x20
+#define NCI_ATS_TA_MASK             0x10
+#define NCI_ATS_FSCI_MASK           0x0F
+typedef struct
+{
+    UINT8       ats_res_len;  /* Length of ATS RES */
+    UINT8       ats_res[NCI_MAX_ATS_LEN];  /* ATS RES defined in [DIGPROT] */
+} tNCI_INTF_PA_ISO_DEP;
+
+typedef struct
+{
+    UINT8       rats;  /* RATS */
+} tNCI_INTF_LA_ISO_DEP;
+
+#define NCI_P_GEN_BYTE_INDEX    15
+#define NCI_L_GEN_BYTE_INDEX    14
+#define NCI_L_NFC_DEP_TO_INDEX  13
+typedef struct
+{
+    UINT8       atr_res_len;  /* Length of ATR_RES */
+    UINT8       atr_res[NCI_MAX_ATS_LEN];  /* ATR_RES (Byte 3 - Byte 17+n) as defined in [DIGPROT] */
+} tNCI_INTF_PA_NFC_DEP;
+
+/* Note: keep tNCI_INTF_PA_NFC_DEP data member in the same order as tNCI_INTF_LA_NFC_DEP */
+typedef struct
+{
+    UINT8       atr_req_len;  /* Length of ATR_REQ */
+    UINT8       atr_req[NCI_MAX_ATS_LEN];  /* ATR_REQ (Byte 3 - Byte 18+n) as defined in [DIGPROT] */
+} tNCI_INTF_LA_NFC_DEP;
+typedef tNCI_INTF_LA_NFC_DEP tNCI_INTF_LF_NFC_DEP;
+typedef tNCI_INTF_PA_NFC_DEP tNCI_INTF_PF_NFC_DEP;
+
+#define NCI_MAX_ATTRIB_LEN   (10 + NCI_MAX_GEN_BYTES_LEN)
+
+typedef struct
+{
+    UINT8       attrib_res_len;  /* Length of ATTRIB RES */
+    UINT8       attrib_res[NCI_MAX_ATTRIB_LEN];  /* ATTRIB RES  as defined in [DIGPROT] */
+} tNCI_INTF_PB_ISO_DEP;
+
+typedef struct
+{
+    UINT8       attrib_req_len;  /* Length of ATTRIB REQ */
+    UINT8       attrib_req[NCI_MAX_ATTRIB_LEN];  /* ATTRIB REQ (Byte 2 - Byte 10+k) as defined in [DIGPROT] */
+} tNCI_INTF_LB_ISO_DEP;
+
+typedef struct
+{
+    tNCI_INTF_TYPE      type;  /* Interface Type  1 Byte  See Table 67 */
+    union
+    {
+        tNCI_INTF_LA_ISO_DEP    la_iso;
+        tNCI_INTF_PA_ISO_DEP    pa_iso;
+        tNCI_INTF_LB_ISO_DEP    lb_iso;
+        tNCI_INTF_PB_ISO_DEP    pb_iso;
+        tNCI_INTF_LA_NFC_DEP    la_nfc;
+        tNCI_INTF_PA_NFC_DEP    pa_nfc;
+        tNCI_INTF_LF_NFC_DEP    lf_nfc;
+        tNCI_INTF_PF_NFC_DEP    pf_nfc;
+    } intf_param;       /* Activation Parameters   0 - n Bytes */
+} tNCI_INTF_PARAMS;
+
+/*
+** HCI Network CMD/NTF structure
+*/
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type A card emulation enabled indicator, 0x02:enabled    */
+    UINT8   sak;
+    UINT8   uid_reg_len;
+    UINT8   uid_reg[10];
+    UINT8   atqa[2];        /* ATQA response code */
+    UINT8   app_data_len;
+    UINT8   app_data[15];   /* 15 bytes optional storage for historic data, use 2 slots */
+    UINT8   fwi_sfgi;       /* FRAME WAITING TIME, START-UP FRAME GUARD TIME            */
+    UINT8   cid_support;
+    UINT8   datarate_max[3];
+    UINT8   clt_support;
+} tNCI_HCI_CE_RF_A;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type B card emulation enabled indicator, 0x02:enabled    */
+    UINT8   pupi_len;
+    UINT8   pupi_reg[4];
+    UINT8   afi;
+    UINT8   atqb[4];        /* 4 bytes ATQB application data                            */
+    UINT8   higherlayer_resp[61]; /* 0~ 61 bytes ATRB_INF use 1~4 personality slots     */
+    UINT8   datarate_max[3];
+    UINT8   natrb;
+} tNCI_HCI_CE_RF_B;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type B prime card emulation enabled indicator, 0x02:enabled */
+    UINT8   pat_in_len;
+    UINT8   pat_in[8];
+    UINT8   dat_out_len;
+    UINT8   dat_out[40];    /* ISO7816-3 <=64 byte, and other fields are 9 bytes        */
+    UINT8   natr;
+} tNCI_HCI_CE_RF_BP;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   mode;           /* Type F card emulation enabled indicator, 0x02:enabled    */
+    UINT8   speed_cap;
+    UINT8   clt_support;
+} tNCI_HCI_CE_RF_F;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   datarate_max;
+} tNCI_HCI_RD_RF_A;
+
+typedef struct
+{
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+    UINT8   afi;
+    UINT8   hldata_len;
+    UINT8   high_layer_data[61];  /* INF field in ATTRIB command                        */
+} tNCI_HCI_RD_RF_B;
+
+typedef struct
+{
+    UINT8   source_host;
+    UINT8   dest_host;
+    UINT8   source_gate;
+    UINT8   dest_gate;
+    UINT8   pipe_id;        /* if MSB is set then valid, 7 bits for Pipe ID             */
+} tNCI_HCI_DYN_PIPE_INFO;
+
+typedef struct
+{
+    UINT8                target_handle;
+    UINT8                session_id[8];
+    UINT8                sync_id[2];
+    UINT8                static_pipe_info;
+    tNCI_HCI_CE_RF_A     ce_rf_a;
+    tNCI_HCI_CE_RF_B     ce_rf_b;
+    tNCI_HCI_CE_RF_BP    ce_rf_bp;
+    tNCI_HCI_CE_RF_F     ce_rf_f;
+} tNCI_HCI_NETWK;
+
+typedef struct
+{
+    UINT8                   target_handle;
+    UINT8                   session_id[8];
+    UINT8                   static_pipe_info;
+    UINT8                   num_dyn_pipes;
+    tNCI_HCI_DYN_PIPE_INFO  dyn_pipe_info[20];
+} tNCI_HCI_NETWK_DH;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* NFC_NCI_DEFS_H */
diff --git a/src/hal/include/nfc_hal_api.h b/src/hal/include/nfc_hal_api.h
new file mode 100644
index 0000000..d147527
--- /dev/null
+++ b/src/hal/include/nfc_hal_api.h
@@ -0,0 +1,223 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFC Hardware Abstraction Layer API
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_API_H
+#define NFC_HAL_API_H
+#include <hardware/nfc.h>
+#include "data_types.h"
+
+/****************************************************************************
+** NFC_HDR header definition for NFC messages
+*****************************************************************************/
+typedef struct
+{
+    UINT16          event;
+    UINT16          len;
+    UINT16          offset;
+    UINT16          layer_specific;
+} NFC_HDR;
+#define NFC_HDR_SIZE (sizeof (NFC_HDR))
+
+typedef UINT8 tHAL_NFC_STATUS;
+
+typedef void (tHAL_NFC_STATUS_CBACK) (tHAL_NFC_STATUS status);
+typedef void (tHAL_NFC_CBACK) (UINT8 event, tHAL_NFC_STATUS status);
+typedef void (tHAL_NFC_DATA_CBACK) (UINT16 data_len, UINT8   *p_data);
+
+/*******************************************************************************
+** tHAL_NFC_ENTRY HAL entry-point lookup table
+*******************************************************************************/
+
+typedef void (tHAL_API_INITIALIZE) (void);
+typedef void (tHAL_API_TERMINATE) (void);
+typedef void (tHAL_API_OPEN) (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback);
+typedef void (tHAL_API_CLOSE) (void);
+typedef void (tHAL_API_CORE_INITIALIZED) (UINT8 *p_core_init_rsp_params);
+typedef void (tHAL_API_WRITE) (UINT16 data_len, UINT8 *p_data);
+typedef BOOLEAN (tHAL_API_PREDISCOVER) (void);
+typedef void (tHAL_API_CONTROL_GRANTED) (void);
+typedef void (tHAL_API_POWER_CYCLE) (void);
+
+
+typedef struct
+{
+    tHAL_API_INITIALIZE *initialize;
+    tHAL_API_TERMINATE *terminate;
+    tHAL_API_OPEN *open;
+    tHAL_API_CLOSE *close;
+    tHAL_API_CORE_INITIALIZED *core_initialized;
+    tHAL_API_WRITE *write;
+    tHAL_API_PREDISCOVER *prediscover;
+    tHAL_API_CONTROL_GRANTED *control_granted;
+    tHAL_API_POWER_CYCLE *power_cycle;
+
+
+} tHAL_NFC_ENTRY;
+
+
+/*******************************************************************************
+** HAL API Function Prototypes
+*******************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Toolset-specific macro for exporting API funcitons */
+#if (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE)) && (defined(_WINDLL))
+#define EXPORT_HAL_API  __declspec(dllexport)
+#else
+#define EXPORT_HAL_API
+#endif
+
+/*******************************************************************************
+**
+** Function         HAL_NfcInitialize
+**
+** Description      Called when HAL library is loaded.
+**
+**                  Initialize GKI and start the HCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcInitialize(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcTerminate
+**
+** Description      Called to terminate NFC HAL
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcTerminate(void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcOpen
+**
+** Description      Open transport and intialize the NFCC, and
+**                  Register callback for HAL event notifications,
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcClose
+**
+** Description      Prepare for shutdown. A HAL_CLOSE_CPLT_EVT will be
+**                  reported when complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcClose (void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcCoreInitialized
+**
+** Description      Called after the CORE_INIT_RSP is received from the NFCC.
+**                  At this time, the HAL can do any chip-specific configuration,
+**                  and when finished signal the libnfc-nci with event
+**                  HAL_POST_INIT_CPLT_EVT.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcCoreInitialized (UINT8 *p_core_init_rsp_params);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcWrite
+**
+** Description      Send an NCI control message or data packet to the
+**                  transport. If an NCI command message exceeds the transport
+**                  size, HAL is responsible for fragmenting it, Data packets
+**                  must be of the correct size.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcWrite (UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreDiscover
+**
+** Description      Perform any vendor-specific pre-discovery actions (if needed)
+**                  If any actions were performed TRUE will be returned, and
+**                  HAL_PRE_DISCOVER_CPLT_EVT will notify when actions are
+**                  completed.
+**
+** Returns          TRUE if vendor-specific pre-discovery actions initialized
+**                  FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+EXPORT_HAL_API BOOLEAN HAL_NfcPreDiscover (void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcControlGranted
+**
+** Description      Grant control to HAL control for sending NCI commands.
+**
+**                  Call in response to HAL_REQUEST_CONTROL_EVT.
+**
+**                  Must only be called when there are no NCI commands pending.
+**
+**                  HAL_RELEASE_CONTROL_EVT will notify when HAL no longer
+**                  needs control of NCI.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcControlGranted (void);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPowerCycle
+**
+** Description      Restart NFCC by power cyle
+**
+**                  HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns          void
+**
+*******************************************************************************/
+EXPORT_HAL_API void HAL_NfcPowerCycle (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_API_H  */
diff --git a/src/hal/include/nfc_hal_target.h b/src/hal/include/nfc_hal_target.h
new file mode 100644
index 0000000..b6eedc9
--- /dev/null
+++ b/src/hal/include/nfc_hal_target.h
@@ -0,0 +1,244 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 NFC_HAL_TARGET_H
+#define NFC_HAL_TARGET_H
+
+#include "data_types.h"
+
+#ifdef BUILDCFG
+#include "buildcfg_hal.h"
+#endif
+
+/****************************************************************************
+** NCI related configuration
+****************************************************************************/
+
+/* GKI pool for NCI messages */
+#ifndef NFC_HAL_NCI_POOL_ID
+#define NFC_HAL_NCI_POOL_ID                     GKI_POOL_ID_1
+#endif
+
+#ifndef NFC_HAL_NCI_POOL_BUF_SIZE
+#define NFC_HAL_NCI_POOL_BUF_SIZE               GKI_BUF1_SIZE
+#endif
+
+/* Initial Max Control Packet Payload Size (until receiving payload size in INIT_CORE_RSP) */
+#ifndef NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE
+#define NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE      0xFF
+#endif
+
+/* Number of bytes to reserve in front of NCI messages (e.g. for transport header) */
+#ifndef NFC_HAL_NCI_MSG_OFFSET_SIZE
+#define NFC_HAL_NCI_MSG_OFFSET_SIZE             1
+#endif
+
+/* NFC-WAKE */
+#ifndef NFC_HAL_LP_NFC_WAKE_GPIO
+#define NFC_HAL_LP_NFC_WAKE_GPIO                UPIO_GENERAL3
+#endif
+
+/* NFCC snooze mode idle timeout before deassert NFC_WAKE in ms */
+#ifndef NFC_HAL_LP_IDLE_TIMEOUT
+#define NFC_HAL_LP_IDLE_TIMEOUT                 100
+#endif
+
+/* NFC snooze mode */
+#ifndef NFC_HAL_LP_SNOOZE_MODE
+#define NFC_HAL_LP_SNOOZE_MODE                  NFC_HAL_LP_SNOOZE_MODE_UART
+#endif
+
+/* Idle Threshold Host in 100ms unit */
+#ifndef NFC_HAL_LP_IDLE_THRESHOLD_HOST
+#define NFC_HAL_LP_IDLE_THRESHOLD_HOST          0
+#endif
+
+/* Idle Threshold HC in 100ms unit */
+#ifndef NFC_HAL_LP_IDLE_THRESHOLD_HC
+#define NFC_HAL_LP_IDLE_THRESHOLD_HC            0
+#endif
+
+
+/* Default NFCC power-up baud rate */
+#ifndef NFC_HAL_DEFAULT_BAUD
+#define NFC_HAL_DEFAULT_BAUD                    USERIAL_BAUD_115200
+#endif
+
+/* time (in ms) between power off and on NFCC */
+#ifndef NFC_HAL_POWER_CYCLE_DELAY
+#define NFC_HAL_POWER_CYCLE_DELAY               100
+#endif
+
+#ifndef NFC_HAL_PRM_DEBUG
+#define NFC_HAL_PRM_DEBUG                       TRUE
+#endif
+
+/* max patch data length (Can be overridden by platform for ACL HCI command size) */
+#ifndef NFC_HAL_PRM_HCD_CMD_MAXLEN
+#define NFC_HAL_PRM_HCD_CMD_MAXLEN              250
+#endif
+
+/* Require PreI2C patch by default */
+#ifndef NFC_HAL_PRE_I2C_PATCH_INCLUDED
+#define NFC_HAL_PRE_I2C_PATCH_INCLUDED          TRUE
+#endif
+
+/* Set to TRUE to always download patch regardless of version */
+#ifndef NFC_HAL_PRM_SKIP_VERSION_CHECK
+#define NFC_HAL_PRM_SKIP_VERSION_CHECK          FALSE
+#endif
+
+/* Mininum payload size for SPD NCI commands (used to validate HAL_NfcPrmSetSpdNciCmdPayloadSize) */
+/* Default is 32, as required by the NCI specifications; however this value may be          */
+/* over-riden for platforms that have transport packet limitations                          */
+#ifndef NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE
+#define NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE    (32)
+#endif
+
+/* amount of time to wait for RESET NTF after patch download */
+#ifndef NFC_HAL_PRM_RESET_NTF_DELAY
+#define NFC_HAL_PRM_RESET_NTF_DELAY             (10000)
+#endif
+
+/* amount of time to wait after downloading preI2C patch before downloading LPM/FPM patch */
+#ifndef NFC_HAL_PRM_POST_I2C_FIX_DELAY
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY          (200)
+#endif
+
+/* NFCC will respond to more than one technology during listen discovery  */
+#ifndef NFC_HAL_DM_MULTI_TECH_RESP
+#define NFC_HAL_DM_MULTI_TECH_RESP              TRUE
+#endif
+
+/* Data rate for 15693 command/response, it must be same as RW_I93_FLAG_DATA_RATE in nfc_target.h */
+#define NFC_HAL_I93_FLAG_DATA_RATE_LOW          0x00
+#define NFC_HAL_I93_FLAG_DATA_RATE_HIGH         0x02
+
+#ifndef NFC_HAL_I93_FLAG_DATA_RATE
+#define NFC_HAL_I93_FLAG_DATA_RATE              NFC_HAL_I93_FLAG_DATA_RATE_HIGH
+#endif
+
+/* Quick Timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC               100       /* 10ms timer */
+#endif
+
+#ifndef NFC_HAL_SHARED_TRANSPORT_ENABLED
+#define NFC_HAL_SHARED_TRANSPORT_ENABLED        FALSE
+#endif
+
+/* Enable verbose tracing by default */
+#ifndef NFC_HAL_TRACE_VERBOSE
+#define NFC_HAL_TRACE_VERBOSE                   TRUE
+#endif
+
+#ifndef NFC_HAL_INITIAL_TRACE_LEVEL
+#define NFC_HAL_INITIAL_TRACE_LEVEL             5
+#endif
+
+/* Map NFC serial port to USERIAL_PORT_6 by default */
+#ifndef USERIAL_NFC_PORT
+#define USERIAL_NFC_PORT                        (USERIAL_PORT_6)
+#endif
+
+/* Restore NFCC baud rate to default on shutdown if baud rate was updated */
+#ifndef NFC_HAL_RESTORE_BAUD_ON_SHUTDOWN
+#define NFC_HAL_RESTORE_BAUD_ON_SHUTDOWN        TRUE
+#endif
+
+/* Enable protocol tracing by default */
+#ifndef NFC_HAL_TRACE_PROTOCOL
+#define NFC_HAL_TRACE_PROTOCOL                  TRUE
+#endif
+#define BT_TRACE_PROTOCOL                       (NFC_HAL_TRACE_PROTOCOL)
+
+#define LogMsg_0 LogMsg
+#define LogMsg_1 LogMsg
+#define LogMsg_2 LogMsg
+#define LogMsg_3 LogMsg
+#define LogMsg_4 LogMsg
+#define LogMsg_5 LogMsg
+#define LogMsg_6 LogMsg
+
+/* Trace macros */
+#define BT_TRACE_0(l,t,m)                           LogMsg_0((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)),(m))
+#define BT_TRACE_1(l,t,m,p1)                        LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1))
+#define BT_TRACE_2(l,t,m,p1,p2)                     LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2))
+#define BT_TRACE_3(l,t,m,p1,p2,p3)                  LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3))
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)               LogMsg_4(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4))
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)            LogMsg_5(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5))
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)         LogMsg_6(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5),(UINT32)(p6))
+
+#define NCI_TRACE_ERROR0(m)                     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m);}
+#define NCI_TRACE_ERROR1(m,p1)                  {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1);}
+#define NCI_TRACE_ERROR2(m,p1,p2)               {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)            {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_WARNING0(m)                   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m);}
+#define NCI_TRACE_WARNING1(m,p1)                {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1);}
+#define NCI_TRACE_WARNING2(m,p1,p2)             {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)          {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_API0(m)                       {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_API, m);}
+#define NCI_TRACE_API1(m,p1)                    {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1);}
+#define NCI_TRACE_API2(m,p1,p2)                 {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2);}
+#define NCI_TRACE_API3(m,p1,p2,p3)              {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)           {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_EVENT0(m)                     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m);}
+#define NCI_TRACE_EVENT1(m,p1)                  {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1);}
+#define NCI_TRACE_EVENT2(m,p1,p2)               {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)            {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_DEBUG0(m)                     {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m);}
+#define NCI_TRACE_DEBUG1(m,p1)                  {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1);}
+#define NCI_TRACE_DEBUG2(m,p1,p2)               {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_hal_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* GKI_TARGET_H */
diff --git a/src/hal/include/nfc_types.h b/src/hal/include/nfc_types.h
new file mode 100644
index 0000000..c4a963f
--- /dev/null
+++ b/src/hal/include/nfc_types.h
@@ -0,0 +1,147 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 NFC_TYPES_H
+#define NFC_TYPES_H
+
+/* Mask for NFC_HDR event field */
+#define NFC_EVT_MASK                    0xFF00
+#define NFC_SUB_EVT_MASK                0x00FF
+
+/****************************************************************************
+** NFC_HAL_TASK  definitions
+*****************************************************************************/
+
+/* NFC_HAL_TASK event messages */
+#define NFC_HAL_EVT_TO_NFC_NCI             0x0100   /* NCI message for sending to NFCC          */
+#define NFC_HAL_EVT_POST_CORE_RESET        0x0200   /* Request to start NCIT quick timer        */
+#define NFC_HAL_EVT_TO_START_QUICK_TIMER   0x0300   /* Request to start chip-specific config    */
+#define NFC_HAL_EVT_HCI                    0x0400   /* NCI message for hci persistency data     */
+#define NFC_HAL_EVT_PRE_DISCOVER           0x0500   /* NCI message to issue prediscover config  */
+#define NFC_HAL_EVT_CONTROL_GRANTED        0x0600   /* permission to send commands queued in HAL*/
+
+/* NFC_HAL_TASK sub event messages */
+#define NFC_HAL_HCI_RSP_NV_READ_EVT        (0x01 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_RSP_NV_WRITE_EVT       (0x02 | NFC_HAL_EVT_HCI)
+#define NFC_HAL_HCI_VSC_TIMEOUT_EVT        (0x03 | NFC_HAL_EVT_HCI)
+
+
+/* Event masks for NFC_TASK messages */
+#define NFC_EVT_TO_NFC_NCI              0x4000      /* NCI message for sending to host stack    */
+#define NFC_EVT_TO_NFC_ERR              0x4100      /* Error notification to NFC Task           */
+#define NFC_EVT_TO_NFC_MSGS             0x4200      /* Messages between NFC and NCI task        */
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*****************************************************************************/
+
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
+#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define INT8_TO_STREAM(p, u8)    {*(p)++ = (INT8)(u8);}
+#define ARRAY32_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 32;           ijk++) *(p)++ = (UINT8) a[31 - ijk];}
+#define ARRAY16_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 16;           ijk++) *(p)++ = (UINT8) a[15 - ijk];}
+#define ARRAY8_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < 8;            ijk++) *(p)++ = (UINT8) a[7 - ijk];}
+#define BDADDR_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN;  ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
+#define LAP_TO_STREAM(p, a)      {register int ijk; for (ijk = 0; ijk < LAP_LEN;      ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
+#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len;        ijk++) *(p)++ = (UINT8) a[ijk];}
+#define REVERSE_ARRAY_TO_STREAM(p, a, len)  {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
+
+#define STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
+#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
+#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
+#define STREAM_TO_BDADDR(a, p)   {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
+#define STREAM_TO_ARRAY32(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY16(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY8(a, p)   {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_LAP(a, p)      {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
+#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
+#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
+#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
+#define UINT8_TO_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*****************************************************************************/
+
+#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24);  *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
+#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
+#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
+#define UINT8_TO_BE_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+
+#define BE_STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
+#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
+#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
+#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+
+
+/*****************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*****************************************************************************/
+
+#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24);  *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
+#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
+#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
+#define UINT8_TO_BE_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+/*****************************************************************************
+** Define trace levels
+*****************************************************************************/
+
+#define BT_TRACE_LEVEL_NONE    0          /* No trace messages to be generated    */
+#define BT_TRACE_LEVEL_ERROR   1          /* Error condition trace messages       */
+#define BT_TRACE_LEVEL_WARNING 2          /* Warning condition trace messages     */
+#define BT_TRACE_LEVEL_API     3          /* API traces                           */
+#define BT_TRACE_LEVEL_EVENT   4          /* Debug messages for events            */
+#define BT_TRACE_LEVEL_DEBUG   5          /* Full debug messages                  */
+
+
+#define TRACE_CTRL_GENERAL          0x00000000
+#define TRACE_LAYER_NCI             0x00280000
+#define TRACE_LAYER_GKI             0x001a0000
+#define TRACE_ORG_STACK             0x00000000
+#define TRACE_ORG_GKI               0x00000400
+
+#define TRACE_TYPE_ERROR            0x00000000
+#define TRACE_TYPE_WARNING          0x00000001
+#define TRACE_TYPE_API              0x00000002
+#define TRACE_TYPE_EVENT            0x00000003
+#define TRACE_TYPE_DEBUG            0x00000004
+
+
+/* Define a function for logging */
+typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...);
+
+#endif /* NFC_TYPES_H */
+
diff --git a/src/hal/int/nfc_brcm_defs.h b/src/hal/int/nfc_brcm_defs.h
new file mode 100644
index 0000000..9ce68e3
--- /dev/null
+++ b/src/hal/int/nfc_brcm_defs.h
@@ -0,0 +1,239 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Broadcom-specific defintions that are shared
+ *  between HAL, nfc stack, adaptation layer and applications.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_BRCM_DEFS_H
+#define NFC_BRCM_DEFS_H
+
+/*****************************************************************************
+** Broadcom-specific NCI definitions
+*****************************************************************************/
+
+/**********************************************
+ * NCI Message Proprietary  Group       - F
+ **********************************************/
+#define NCI_MSG_TAG_SET_MEM             0x00
+#define NCI_MSG_TAG_GET_MEM             0x01
+#define NCI_MSG_T1T_SET_HR              0x02
+#define NCI_MSG_SET_CLF_REGISTERS       0x03
+#define NCI_MSG_GET_BUILD_INFO          0x04
+#define NCI_MSG_HCI_NETWK               0x05
+#define NCI_MSG_SET_FWFSM               0x06
+#define NCI_MSG_SET_UICCRDRF            0x07
+#define NCI_MSG_POWER_LEVEL             0x08
+#define NCI_MSG_FRAME_LOG               0x09
+#define NCI_MSG_UICC_READER_ACTION      0x0A
+#define NCI_MSG_SET_PPSE_RESPONSE       0x0B
+#define NCI_MSG_PRBS_SET                0x0C
+#define NCI_MSG_RESET_ALL_UICC_CFG      0x0D    /* reset HCI network/close all pipes (S,D) register */
+#define NCI_MSG_GET_NFCEE_INFO          0x0E
+#define NCI_MSG_DISABLE_INIT_CHECK      0x0F
+#define NCI_MSG_ANTENNA_SELF_TEST       0x10
+#define NCI_MSG_SET_MAX_PKT_SIZE        0x11
+#define NCI_MSG_NCIP_CLK_REQ_OR_CAR_DET 0x12
+#define NCI_MSG_NCIP_CONFIG_DBUART      0x13
+#define NCI_MSG_NCIP_ENABLE_DVT_DRIVER  0x14
+#define NCI_MSG_SET_ASWP                0x15
+#define NCI_MSG_ENCAPSULATE_NCI         0x16
+#define NCI_MSG_CONFIGURE_ARM_JTAG      0x17
+#define NCI_MSG_STATISTICS              0x18
+#define NCI_MSG_SET_DSP_TABLE           0x19
+#define NCI_MSG_GET_DSP_TABLE           0x1a
+#define NCI_MSG_READY_RX_CMD            0x1b
+#define NCI_MSG_GET_VBAT                0x1c
+#define NCI_MSG_GET_XTAL_INDEX_FROM_DH  0x1d
+#define NCI_MSG_SWP_LOG                 0x1e
+#define NCI_MSG_GET_PWRLEVEL            0x1f
+#define NCI_MSG_SET_VBAT_MONITOR        0x20
+#define NCI_MSG_SET_TINT_MODE           0x21
+#define NCI_MSG_ACCESS_APP              0x22
+#define NCI_MSG_SET_SECURE_MODE         0x23
+#define NCI_MSG_GET_NV_DEVICE           0x24
+#define NCI_MSG_LPTD                    0x25
+#define NCI_MSG_SET_CE4_AS_SNOOZE       0x26
+#define NCI_MSG_NFCC_SEND_HCI           0x27
+#define NCI_MSG_CE4_PATCH_DOWNLOAD_DONE 0x28
+#define NCI_MSG_EEPROM_RW               0x29
+#define NCI_MSG_GET_CLF_REGISTERS       0x2A
+#define NCI_MSG_RF_TEST                 0x2B
+#define NCI_MSG_DEBUG_PRINT             0x2C
+#define NCI_MSG_GET_PATCH_VERSION       0x2D
+#define NCI_MSG_SECURE_PATCH_DOWNLOAD   0x2E
+#define NCI_MSG_SPD_FORMAT_NVM          0x2F
+#define NCI_MSG_SPD_READ_NVM            0x30
+
+/**********************************************
+ * Proprietary  NCI status codes
+ **********************************************/
+#define NCI_STATUS_SPD_ERROR_ORDER          0xE0
+#define NCI_STATUS_SPD_ERROR_DEST           0xE1
+#define NCI_STATUS_SPD_ERROR_PROJECTID      0xE2
+#define NCI_STATUS_SPD_ERROR_CHIPVER        0xE3
+#define NCI_STATUS_SPD_ERROR_MAJORVER       0xE4
+#define NCI_STATUS_SPD_ERROR_INVALID_PARAM  0xE5
+#define NCI_STATUS_SPD_ERROR_INVALID_SIG    0xE6
+#define NCI_STATUS_SPD_ERROR_NVM_CORRUPTED  0xE7
+#define NCI_STATUS_SPD_ERROR_PWR_MODE       0xE8
+#define NCI_STATUS_SPD_ERROR_MSG_LEN        0xE9
+#define NCI_STATUS_SPD_ERROR_PATCHSIZE      0xEA
+
+
+
+#define NCI_NV_DEVICE_NONE              0x00
+#define NCI_NV_DEVICE_EEPROM            0x08
+#define NCI_NV_DEVICE_UICC1             0x10
+
+/* The events reported on tNFC_VS_CBACK */
+/* The event is (NCI_NTF_BIT|oid) or (NCI_RSP_BIT|oid) */
+#define NFC_VS_HCI_NETWK_EVT            (NCI_NTF_BIT|NCI_MSG_HCI_NETWK)
+#define NFC_VS_HCI_NETWK_RSP            (NCI_RSP_BIT|NCI_MSG_HCI_NETWK)
+#define NFC_VS_UICC_READER_ACTION_EVT   (NCI_NTF_BIT|NCI_MSG_UICC_READER_ACTION)
+#define NFC_VS_POWER_LEVEL_RSP          (NCI_RSP_BIT|NCI_MSG_POWER_LEVEL)
+#define NFC_VS_GET_NV_DEVICE_EVT        (NCI_RSP_BIT|NCI_MSG_GET_NV_DEVICE)
+#define NFC_VS_LPTD_EVT                 (NCI_NTF_BIT|NCI_MSG_LPTD)
+#define NFC_VS_GET_BUILD_INFO_EVT       (NCI_RSP_BIT|NCI_MSG_GET_BUILD_INFO)
+#define NFC_VS_GET_PATCH_VERSION_EVT    (NCI_RSP_BIT|NCI_MSG_GET_PATCH_VERSION)
+#define NFC_VS_SEC_PATCH_DOWNLOAD_EVT   (NCI_RSP_BIT|NCI_MSG_SECURE_PATCH_DOWNLOAD)
+#define NFC_VS_SEC_PATCH_AUTH_EVT       (NCI_NTF_BIT|NCI_MSG_SECURE_PATCH_DOWNLOAD)
+
+#define NCI_GET_PATCH_VERSION_NVM_OFFSET    37
+
+
+#define NCI_NFCC_PIPE_INFO_NV_SIZE      24  /* Static and dynamic pipe id and status for each pipe to uicc0 and uicc1. */
+#define NCI_PERSONALITY_SLOT_SIZE       19
+#define NCI_DYNAMIC_PIPE_SIZE           8
+
+#define NCI_SWP_INTERFACE_TYPE          0xFF    /* Type of TLV in NCI_MSG_HCI_NETWK */
+#define NCI_HCI_GATE_TYPE               0xFE    /* Type of TLV in NCI_MSG_HCI_NETWK */
+
+/* Secure Patch Download definitions (patch type definitions) */
+#define NCI_SPD_TYPE_HEADER             0x00
+#define NCI_SPD_TYPE_SRAM               0x01
+#define NCI_SPD_TYPE_AON                0x02
+#define NCI_SPD_TYPE_PATCH_TABLE        0x03
+#define NCI_SPD_TYPE_SECURE_CONFIG      0x04
+#define NCI_SPD_TYPE_CONTROLLED_CONFIG  0x05
+#define NCI_SPD_TYPE_SIGNATURE          0x06
+#define NCI_SPD_TYPE_SIGCHEK            0x07
+
+/* Secure Patch Download definitions (NCI_SPD_TYPE_HEADER definitions) */
+#define NCI_SPD_HEADER_OFFSET_CHIPVERLEN    0x18
+#define NCI_SPD_HEADER_CHIPVER_LEN          16
+
+/* NVM Type (in GET_PATCH_VERSION RSP) */
+#define NCI_SPD_NVM_TYPE_NONE           0x00
+#define NCI_SPD_NVM_TYPE_EEPROM         0x01
+#define NCI_SPD_NVM_TYPE_UICC           0x02
+
+/**********************************************
+ * NCI NFCC proprietary features in octet 3
+ **********************************************/
+#define NCI_FEAT_SIGNED_PATCH           0x01000000
+
+/**********************************************
+ * NCI Interface Types
+ **********************************************/
+#define NCI_INTERFACE_VS_CALYPSO_CE     0x81
+#define NCI_INTERFACE_VS_T2T_CE         0x82    /* for Card Emulation side */
+#define NCI_INTERFACE_VS_15693          0x83    /* for both Reader/Writer and Card Emulation side */
+#define NCI_INTERFACE_VS_T1T_CE         0x84    /* for Card Emulation side */
+
+/**********************************************
+ * NCI Proprietary Parameter IDs
+ **********************************************/
+#define NCI_PARAM_ID_LA_FSDI            0xA0
+#define NCI_PARAM_ID_LB_FSDI            0xA1
+#define NCI_PARAM_ID_HOST_LISTEN_MASK   0xA2
+#define NCI_PARAM_ID_CHIP_TYPE          0xA3 /* NFCDEP */
+#define NCI_PARAM_ID_PA_ANTICOLL        0xA4
+#define NCI_PARAM_ID_CONTINUE_MODE      0xA5
+#define NCI_PARAM_ID_LBP                0xA6
+#define NCI_PARAM_ID_T1T_RDR_ONLY       0xA7
+#define NCI_PARAM_ID_LA_SENS_RES        0xA8
+#define NCI_PARAM_ID_PWR_SETTING_BITMAP 0xA9
+#define NCI_PARAM_ID_WI_NTF_ENABLE      0xAA
+#define NCI_PARAM_ID_LN_BITRATE         0xAB /* NFCDEP Listen Bitrate */
+#define NCI_PARAM_ID_LF_BITRATE         0xAC /* FeliCa */
+#define NCI_PARAM_ID_SWP_BITRATE_MASK   0xAD
+#define NCI_PARAM_ID_KOVIO              0xAE
+#define NCI_PARAM_ID_UICC_NTF_TO        0xAF
+#define NCI_PARAM_ID_NFCDEP             0xB0
+#define NCI_PARAM_ID_CLF_REGS_CFG       0xB1
+#define NCI_PARAM_ID_NFCDEP_TRANS_TIME  0xB2
+#define NCI_PARAM_ID_CREDIT_TIMER       0xB3
+#define NCI_PARAM_ID_CORRUPT_RX         0xB4
+#define NCI_PARAM_ID_ISODEP             0xB5
+#define NCI_PARAM_ID_LF_CONFIG          0xB6
+#define NCI_PARAM_ID_I93_DATARATE       0xB7
+#define NCI_PARAM_ID_CREDITS_THRESHOLD  0xB8
+#define NCI_PARAM_ID_TAGSNIFF_CFG       0xB9
+#define NCI_PARAM_ID_PA_FSDI            0xBA /* ISODEP */
+#define NCI_PARAM_ID_PB_FSDI            0xBB /* ISODEP */
+#define NCI_PARAM_ID_FRAME_INTF_RETXN   0xBC
+
+#define NCI_PARAM_ID_UICC_RDR_PRIORITY  0xBD
+#define NCI_PARAM_ID_GUARD_TIME         0xBE
+#define NCI_PARAM_ID_STDCONFIG          0xBF /* dont not use this config item */
+#define NCI_PARAM_ID_PROPCFG            0xC0 /* dont not use this config item  */
+#define NCI_PARAM_ID_MAXTRY2ACTIVATE    0xC1
+#define NCI_PARAM_ID_SWPCFG             0xC2
+#define NCI_PARAM_ID_CLF_LPM_CFG        0xC3
+#define NCI_PARAM_ID_DCLB               0xC4
+#define NCI_PARAM_ID_ACT_ORDER          0xC5
+#define NCI_PARAM_ID_DEP_DELAY_ACT      0xC6
+#define NCI_PARAM_ID_DH_PARITY_CRC_CTL  0xC7
+#define NCI_PARAM_ID_PREINIT_DSP_CFG    0xC8
+#define NCI_PARAM_ID_FW_WORKAROUND      0xC9
+#define NCI_PARAM_ID_RFU_CONFIG         0xCA
+#define NCI_PARAM_ID_EMVCO_ENABLE       0xCB
+#define NCI_PARAM_ID_ANTDRIVER_PARAM    0xCC
+#define NCI_PARAM_ID_PLL325_CFG_PARAM   0xCD
+#define NCI_PARAM_ID_OPNLP_ADPLL_ENABLE 0xCE
+#define NCI_PARAM_ID_CONFORMANCE_MODE   0xCF
+
+#define NCI_PARAM_ID_LPO_ON_OFF_ENABLE  0xD0
+#define NCI_PARAM_ID_FORCE_VANT         0xD1
+#define NCI_PARAM_ID_COEX_CONFIG        0xD2
+#define NCI_PARAM_ID_INTEL_MODE         0xD3
+
+#define NCI_PARAM_ID_AID                0xFF
+
+/**********************************************
+ * NCI Parameter ID Lens
+ **********************************************/
+#define NCI_PARAM_LEN_PWR_SETTING_BITMAP    3
+#define NCI_PARAM_LEN_HOST_LISTEN_MASK      2
+#define NCI_PARAM_LEN_PLL325_CFG_PARAM      14
+
+/**********************************************
+ * Snooze Mode
+ **********************************************/
+#define NFC_SNOOZE_MODE_NONE      0x00    /* Snooze mode disabled    */
+#define NFC_SNOOZE_MODE_UART      0x01    /* Snooze mode for UART    */
+#define NFC_SNOOZE_MODE_SPI_I2C   0x08    /* Snooze mode for SPI/I2C */
+
+#define NFC_SNOOZE_ACTIVE_LOW     0x00    /* high to low voltage is asserting */
+#define NFC_SNOOZE_ACTIVE_HIGH    0x01    /* low to high voltage is asserting */
+
+#endif  /* NFC_BRCM_DEFS_H */
diff --git a/src/hal/int/nfc_hal_int.h b/src/hal/int/nfc_hal_int.h
new file mode 100644
index 0000000..ca8dc20
--- /dev/null
+++ b/src/hal/int/nfc_hal_int.h
@@ -0,0 +1,473 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains the NCI transport internal definitions and functions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_HAL_INT_H
+#define NFC_HAL_INT_H
+
+#include "nfc_hal_target.h"
+#include "gki.h"
+#include "nci_defs.h"
+#include "nfc_brcm_defs.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************
+** NFC HAL TASK transport definitions
+****************************************************************************/
+/* NFC HAL Task event masks */
+#define NFC_HAL_TASK_EVT_DATA_RDY               EVENT_MASK (APPL_EVT_0)
+#define NFC_HAL_TASK_EVT_INITIALIZE             EVENT_MASK (APPL_EVT_5)
+#define NFC_HAL_TASK_EVT_TERMINATE              EVENT_MASK (APPL_EVT_6)
+#define NFC_HAL_TASK_EVT_POWER_CYCLE            EVENT_MASK (APPL_EVT_7)
+
+#define NFC_HAL_TASK_EVT_MBOX                   (TASK_MBOX_0_EVT_MASK)
+
+/* NFC HAL Task mailbox definitions */
+#define NFC_HAL_TASK_MBOX                       (TASK_MBOX_0)
+
+/* NFC HAL Task Timer events */
+#ifndef NFC_HAL_QUICK_TIMER_EVT_MASK
+#define NFC_HAL_QUICK_TIMER_EVT_MASK            (TIMER_0_EVT_MASK)
+#endif
+
+#ifndef NFC_HAL_QUICK_TIMER_ID
+#define NFC_HAL_QUICK_TIMER_ID                  (TIMER_0)
+#endif
+
+/* NFC HAL Task Timer types */
+#define NFC_HAL_TTYPE_NCI_WAIT_RSP              0
+#define NFC_HAL_TTYPE_POWER_CYCLE               1
+
+/* NFC HAL Task Wait Response flag */
+#define NFC_HAL_WAIT_RSP_CMD                    0x10    /* wait response on an NCI command                  */
+#define NFC_HAL_WAIT_RSP_VSC                    0x20    /* wait response on an NCI vendor specific command  */
+#define NFC_HAL_WAIT_RSP_PROP                   0x40    /* wait response on a proprietary command           */
+#define NFC_HAL_WAIT_RSP_NONE                   0x00    /* not waiting for anything                         */
+
+typedef UINT8 tNFC_HAL_WAIT_RSP;
+
+typedef UINT16 tNFC_HAL_HCI_EVT;
+
+
+#define NFC_HAL_HCI_DH_TARGET_HANDLE            0xF2
+#define NFC_HAL_HCI_UICC0_TARGET_HANDLE         0xF3
+#define NFC_HAL_HCI_UICC1_TARGET_HANDLE         0xF4
+
+#define NFC_HAL_HCI_SESSION_ID_LEN              0x08
+#define NFC_HAL_HCI_NETWK_INFO_SIZE             184
+#define NFC_HAL_HCI_DH_NETWK_INFO_SIZE          111
+
+#define NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
+#define NFC_HAL_HCI_ADMIN_PIPE                  0x01
+#define NFC_HAL_HCI_HOST_ID_UICC0               0x02        /* Host ID for UICC 0 */
+#define NFC_HAL_HCI_HOST_ID_UICC1               0x03        /* Host ID for UICC 1 */
+#define NFC_HAL_HCI_COMMAND_TYPE                0x00
+
+/* NFC HAL transport configuration */
+typedef struct
+{
+    BOOLEAN         shared_transport;           /* TRUE if using shared HCI/NCI transport */
+    UINT8           userial_baud;
+    UINT8           userial_fc;
+} tNFC_HAL_TRANS_CFG;
+
+#ifdef TESTER
+#define NFC_HAL_TRANS_CFG_QUALIFIER               /* For Insight, ncit_cfg is runtime-configurable */
+#else
+#define NFC_HAL_TRANS_CFG_QUALIFIER   const       /* For all other platforms, ncit_cfg is constant */
+#endif
+extern NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg;
+
+/*****************************************************************************
+* BT HCI definitions
+*****************************************************************************/
+#define BT_HDR      NFC_HDR
+
+/* Tranport message type */
+#define HCIT_TYPE_COMMAND   0x01
+#define HCIT_TYPE_EVENT     0x04
+#define HCIT_TYPE_NFC       0x10
+
+/* Vendor-Specific BT HCI definitions */
+#define HCI_SUCCESS                         0x00
+#define HCI_GRP_VENDOR_SPECIFIC             (0x3F << 10)            /* 0xFC00 */
+#define HCI_BRCM_WRITE_SLEEP_MODE           (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS     (0x03 << 10)            /* 0x0C00 */
+#define HCI_RESET                           (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_COMMAND_COMPLETE_EVT            0x0E
+#define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH    12
+#define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH      0x06
+#define HCIE_PREAMBLE_SIZE                  2
+
+/****************************************************************************
+** Internal constants and definitions
+****************************************************************************/
+
+/* NFC HAL receiving states */
+enum
+{
+    NFC_HAL_RCV_IDLE_ST,            /* waiting for packet type byte             */
+    NFC_HAL_RCV_NCI_MSG_ST,         /* waiting for the first byte of NCI header */
+    NFC_HAL_RCV_NCI_HDR_ST,         /* reading NCI header                       */
+    NFC_HAL_RCV_NCI_PAYLOAD_ST,     /* reading NCI payload                      */
+    NFC_HAL_RCV_BT_MSG_ST,          /* waiting for the first byte of BT header  */
+    NFC_HAL_RCV_BT_HDR_ST,          /* reading BT HCI header                    */
+    NFC_HAL_RCV_BT_PAYLOAD_ST       /* reading BT HCI payload                   */
+};
+
+/* errors during NCI packet reassembly process */
+#define NFC_HAL_NCI_RAS_TOO_BIG             0x01
+#define NFC_HAL_NCI_RAS_ERROR               0x02
+typedef UINT8 tNFC_HAL_NCI_RAS;
+
+/* NFC HAL power mode */
+enum
+{
+    NFC_HAL_POWER_MODE_FULL,            /* NFCC is full power mode      */
+    NFC_HAL_POWER_MODE_LAST
+};
+typedef UINT8 tNFC_HAL_POWER_MODE;
+
+
+/* NFC HAL event for low power mode */
+enum
+{
+    NFC_HAL_LP_TX_DATA_EVT,                 /* DH is sending data to NFCC   */
+    NFC_HAL_LP_RX_DATA_EVT,                 /* DH received data from NFCC   */
+    NFC_HAL_LP_TIMEOUT_EVT,                 /* Timeout                      */
+    NFC_HAL_LP_LAST_EVT
+};
+typedef UINT8 tNFC_HAL_LP_EVT;
+
+#define NFC_HAL_ASSERT_NFC_WAKE      0x00   /* assert NFC_WAKE      */
+#define NFC_HAL_DEASSERT_NFC_WAKE    0x01   /* deassert NFC_WAKE    */
+
+#define NFC_HAL_BT_HCI_CMD_HDR_SIZE     3   /* opcode (2) +  length (1)    */
+#define NFC_HAL_CMD_TOUT            (2000)  /* timeout for NCI CMD (in ms) */
+
+#define NFC_HAL_SAVED_HDR_SIZE          (2)
+#define NFC_HAL_SAVED_CMD_SIZE          (2)
+
+#ifndef NFC_HAL_DEBUG
+#define NFC_HAL_DEBUG  TRUE
+#endif
+
+#if (NFC_HAL_DEBUG == TRUE)
+extern const char * const nfc_hal_init_state_str[];
+#define NFC_HAL_SET_INIT_STATE(state)  NCI_TRACE_DEBUG3 ("init state: %d->%d(%s)", nfc_hal_cb.dev_cb.initializing_state, state, nfc_hal_init_state_str[state]); nfc_hal_cb.dev_cb.initializing_state = state;
+#else
+#define NFC_HAL_SET_INIT_STATE(state)  nfc_hal_cb.dev_cb.initializing_state = state;
+#endif
+
+
+/* NFC HAL - NFCC initializing state */
+enum
+{
+    NFC_HAL_INIT_STATE_IDLE,               /* Initialization is done                */
+    NFC_HAL_INIT_STATE_W4_XTAL_SET,        /* Waiting for crystal setting rsp       */
+    NFC_HAL_INIT_STATE_W4_RESET,           /* Waiting for reset rsp                 */
+    NFC_HAL_INIT_STATE_W4_BUILD_INFO,      /* Waiting for build info rsp            */
+    NFC_HAL_INIT_STATE_W4_PATCH_INFO,      /* Waiting for patch info rsp            */
+    NFC_HAL_INIT_STATE_W4_APP_COMPLETE,    /* Waiting for complete from application */
+    NFC_HAL_INIT_STATE_W4_POST_INIT_DONE,  /* Waiting for complete of post init     */
+    NFC_HAL_INIT_STATE_W4_CONTROL_DONE,    /* Waiting for control release           */
+    NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE,/* Waiting for complete of prediscover   */
+    NFC_HAL_INIT_STATE_W4_RE_INIT,         /* Waiting for reset rsp on ReInit       */
+    NFC_HAL_INIT_STATE_CLOSING             /* Shutting down                         */
+};
+typedef UINT8 tNFC_HAL_INIT_STATE;
+
+/* NFC HAL - NFCC config items during post initialization */
+enum
+{
+    NFC_HAL_DM_CONFIG_LPTD,
+    NFC_HAL_DM_CONFIG_PLL_325,
+    NFC_HAL_DM_CONFIG_START_UP,
+    NFC_HAL_DM_CONFIG_I93_DATA_RATE,
+    NFC_HAL_DM_CONFIG_FW_FSM,
+    NFC_HAL_DM_CONFIG_START_UP_VSC,
+    NFC_HAL_DM_CONFIG_NONE
+};
+typedef UINT8 tNFC_HAL_DM_CONFIG;
+
+/* callback function prototype */
+typedef struct
+{
+    UINT16  opcode;
+    UINT16  param_len;
+    UINT8   *p_param_buf;
+} tNFC_HAL_BTVSC_CPLT;
+
+typedef void (tNFC_HAL_BTVSC_CPLT_CBACK) (tNFC_HAL_BTVSC_CPLT *p1);
+
+
+/* data type for NFC_HAL_HCI_RSP_NV_READ_EVT */
+typedef struct
+{
+    NFC_HDR           hdr;
+    UINT8             block;
+    UINT16            size;
+    tHAL_NFC_STATUS   status;
+} tNFC_HAL_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFC_HAL_HCI_RSP_NV_WRITE_EVT */
+typedef struct
+{
+    NFC_HDR           hdr;
+    tHAL_NFC_STATUS   status;
+} tNFC_HAL_HCI_RSP_NV_WRITE_EVT;
+
+
+/* union of all event data types */
+typedef union
+{
+    NFC_HDR                         hdr;
+    /* Internal events */
+    tNFC_HAL_HCI_RSP_NV_READ_EVT    nv_read;
+    tNFC_HAL_HCI_RSP_NV_WRITE_EVT   nv_write;
+} tNFC_HAL_HCI_EVENT_DATA;
+
+/*****************************************************************************
+** Control block for NFC HAL
+*****************************************************************************/
+
+/* Patch RAM Download Control block */
+
+/* PRM states */
+enum
+{
+    NFC_HAL_PRM_ST_IDLE,
+
+    /* Secure patch download stated */
+    NFC_HAL_PRM_ST_SPD_GET_VERSION,
+    NFC_HAL_PRM_ST_SPD_COMPARE_VERSION,
+    NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER,
+    NFC_HAL_PRM_ST_SPD_DOWNLOADING,
+    NFC_HAL_PRM_ST_SPD_AUTHENTICATING,
+    NFC_HAL_PRM_ST_SPD_AUTH_DONE
+};
+typedef UINT8 tNFC_HAL_PRM_STATE;
+
+/* Maximum number of patches (currently 2: LPM and FPM) */
+#define NFC_HAL_PRM_MAX_PATCH_COUNT    2
+#define NFC_HAL_PRM_PATCH_MASK_ALL     0xFFFFFFFF
+
+/* Structures for PRM Control Block */
+typedef struct
+{
+    UINT8               power_mode;
+    UINT16              len;
+} tNFC_HAL_PRM_PATCHDESC;
+
+typedef struct
+{
+    tNFC_HAL_PRM_STATE  state;                  /* download state */
+    UINT32              flags;                  /* internal flags */
+    UINT16              cur_patch_len_remaining;/* bytes remaining in patchfile to process     */
+    const UINT8*        p_cur_patch_data;       /* pointer to patch currently being downloaded */
+    UINT16              cur_patch_offset;       /* offset of next byte to process              */
+    UINT32              dest_ram;
+    TIMER_LIST_ENT      timer;                  /* Timer for patch download                    */
+
+    /* Secure Patch Download */
+    UINT32              spd_patch_needed_mask;  /* Mask of patches that need to be downloaded */
+    UINT32              spd_nvm_patch_mask;     /* Mask of patches currently in NVM */
+    UINT16              spd_project_id;         /* Current project_id of patch in nvm */
+    UINT16              spd_nvm_max_size;
+    UINT16              spd_patch_max_size;
+    UINT16              spd_fpm_patch_size;
+    UINT16              spd_lpm_patch_size;
+
+    UINT8               spd_patch_count;        /* Number of patches left to download */
+    UINT8               spd_cur_patch_idx;      /* Current patch being downloaded */
+    UINT16              spd_ver_major;          /* Current major version of patch in nvm */
+    UINT16              spd_ver_minor;          /* Current minor version of patch in nvm */
+    tNFC_HAL_PRM_PATCHDESC spd_patch_desc[NFC_HAL_PRM_MAX_PATCH_COUNT];
+
+    /* I2C-patch */
+    UINT8               *p_spd_patch;           /* pointer to spd patch             */
+    UINT16              spd_patch_len_remaining;/* patch length                     */
+    UINT16              spd_patch_offset;       /* offset of next byte to process   */
+
+    tNFC_HAL_PRM_FORMAT format;                 /* format of patch ram              */
+    tNFC_HAL_PRM_CBACK  *p_cback;               /* Callback for download status notifications */
+    UINT32              patchram_delay;         /* the dealy after patch */
+} tNFC_HAL_PRM_CB;
+
+/* Patch for I2C fix */
+typedef struct
+{
+    UINT8               *p_patch;               /* patch for i2c fix                */
+    UINT32              prei2c_delay;           /* the dealy after preI2C patch */
+    UINT16              len;                    /* i2c patch length                 */
+} tNFC_HAL_PRM_I2C_FIX_CB;
+
+/* Control block for NCI transport */
+typedef struct
+{
+    UINT8               nci_ctrl_size;      /* Max size for NCI messages                              */
+    UINT8               rcv_state;          /* current rx state                                       */
+    UINT16              rcv_len;            /* bytes remaining to be received in current rx state     */
+    NFC_HDR             *p_rcv_msg;         /* buffer to receive NCI message                          */
+    NFC_HDR             *p_frag_msg;        /* fragmented NCI message; waiting for last fragment      */
+    NFC_HDR             *p_pend_cmd;        /* pending NCI message; waiting for NFCC state to be free */
+    tNFC_HAL_NCI_RAS    nci_ras;            /* nci reassembly error status                            */
+    TIMER_LIST_ENT      nci_wait_rsp_timer; /* Timer for waiting for nci command response             */
+    tNFC_HAL_WAIT_RSP   nci_wait_rsp;       /* nci wait response flag                                 */
+    UINT8               last_hdr[NFC_HAL_SAVED_HDR_SIZE];/* part of last NCI command header           */
+    UINT8               last_cmd[NFC_HAL_SAVED_CMD_SIZE];/* part of last NCI command payload          */
+    void                *p_vsc_cback;       /* the callback function for last VSC command             */
+} tNFC_HAL_NCIT_CB;
+
+/* Control block for device initialization */
+typedef struct
+{
+    tNFC_HAL_INIT_STATE     initializing_state;     /* state of initializing NFCC               */
+
+    UINT32                  brcm_hw_id;             /* BRCM NFCC HW ID                          */
+    tNFC_HAL_DM_CONFIG      next_dm_config;         /* next config in post initialization       */
+    UINT8                   next_startup_vsc;       /* next start-up VSC offset in post init    */
+
+    tNFC_HAL_POWER_MODE     power_mode;             /* NFCC power mode                          */
+    UINT8                   snooze_mode;            /* current snooze mode                      */
+    UINT8                   new_snooze_mode;        /* next snooze mode after receiving cmpl    */
+    UINT8                   nfc_wake_active_mode;   /* NFC_HAL_LP_ACTIVE_LOW/HIGH               */
+    TIMER_LIST_ENT          lp_timer;               /* timer for low power mode                 */
+
+
+    tHAL_NFC_STATUS_CBACK   *p_prop_cback;          /* callback to notify complete of proprietary update */
+} tNFC_HAL_DEV_CB;
+
+/* data members for NFC_HAL-HCI */
+typedef struct
+{
+    TIMER_LIST_ENT          hci_timer;                /* Timer to avoid indefinitely waiting for response */
+    UINT8                   *p_hci_netwk_info_buf;    /* Buffer for reading HCI Network information */
+    UINT8                   *p_hci_netwk_dh_info_buf; /* Buffer for reading HCI Network DH information */
+    UINT8                   hci_netwk_config_block;   /* Rsp awaiting for hci network configuration block */
+    BOOLEAN                 b_wait_hcp_conn_create_rsp; /* Waiting for hcp connection create response */
+    BOOLEAN                 b_check_clear_all_pipe_cmd;
+    UINT8                   hcp_conn_id;
+} tNFC_HAL_HCI_CB;
+
+typedef struct
+{
+    tHAL_NFC_CBACK          *p_stack_cback;     /* Callback for HAL event notification  */
+    tHAL_NFC_DATA_CBACK     *p_data_cback;      /* Callback for data event notification  */
+
+    TIMER_LIST_Q            quick_timer_queue;  /* timer list queue                 */
+    TIMER_LIST_ENT          timer;              /* timer for NCI transport task     */
+
+    tNFC_HAL_NCIT_CB        ncit_cb;            /* NCI transport */
+    tNFC_HAL_DEV_CB         dev_cb;             /* device initialization */
+
+    /* Patchram control block */
+    tNFC_HAL_PRM_CB         prm;
+    tNFC_HAL_PRM_I2C_FIX_CB prm_i2c;
+
+    /* data members for NFC_HAL-HCI */
+    tNFC_HAL_HCI_CB         hci_cb;
+
+
+    tNFC_HAL_NCI_CBACK      *p_reinit_cback;
+    UINT8                   max_rf_credits;     /* NFC Max RF data credits */
+    UINT8                   trace_level;        /* NFC HAL trace level */
+} tNFC_HAL_CB;
+
+/* Global NCI data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+extern tNFC_HAL_CB   nfc_hal_cb;
+#else
+#define nfc_hal_cb (*nfc_hal_cb_ptr)
+extern tNFC_HAL_CB *nfc_hal_cb_ptr;
+#endif
+
+/****************************************************************************
+** Internal nfc functions
+****************************************************************************/
+
+/* From nfc_hal_main.c */
+UINT32 nfc_hal_main_task (UINT32 param);
+void   nfc_hal_main_init (void);
+void   nfc_hal_main_pre_init_done (tHAL_NFC_STATUS);
+void   nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+void   nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle);
+void   nfc_hal_main_send_error (tHAL_NFC_STATUS status);
+
+/* nfc_hal_nci.c */
+BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte);
+BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg);
+void    nfc_hal_nci_assemble_nci_msg (void);
+void    nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg);
+void    nfc_hal_nci_send_cmd (NFC_HDR *p_buf);
+void    nfc_hal_nci_cmd_timeout_cback (void *p_tle);
+
+/* nfc_hal_dm.c */
+void nfc_hal_dm_init (void);
+void nfc_hal_dm_set_xtal_freq_index (void);
+void nfc_hal_dm_send_reset_cmd (void);
+void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg);
+void nfc_hal_dm_config_nfcc (void);
+void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback);
+void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback);
+void nfc_hal_dm_set_nfc_wake (UINT8 cmd);
+void nfc_hal_dm_pre_init_nfcc (void);
+void nfc_hal_dm_shutting_down_nfcc (void);
+BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event);
+void nfc_hal_dm_send_pend_cmd (void);
+
+/* nfc_hal_prm.c */
+void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type);
+void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+void nfc_hal_prm_process_timeout (void *p_tle);
+
+/* nfc_hal_hci.c */
+void nfc_hal_hci_enable (void);
+void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data);
+void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data);
+void nfc_hal_hci_handle_hcp_pkt (UINT8 *p_data);
+void nfc_hal_hci_timeout_cback (void *p_tle);
+
+
+/* Define default NCI protocol trace function (if protocol tracing is enabled) */
+#if (defined(NFC_HAL_TRACE_PROTOCOL) && (NFC_HAL_TRACE_PROTOCOL == TRUE))
+#if !defined (DISP_NCI)
+#define DISP_NCI    (DispNci)
+void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+#endif  /* DISP_NCI */
+
+/* For displaying vendor-specific HCI commands */
+void DispHciCmd (BT_HDR *p_buf);
+void DispHciEvt (BT_HDR *p_buf);
+#endif /* NFC_HAL_TRACE_PROTOCOL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_H */
diff --git a/src/hal/int/nfc_hal_int_api.h b/src/hal/int/nfc_hal_int_api.h
new file mode 100644
index 0000000..5385bb4
--- /dev/null
+++ b/src/hal/int/nfc_hal_int_api.h
@@ -0,0 +1,293 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Internal NFC HAL API functions.
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_INT_API_H
+#define NFC_HAL_INT_API_H
+
+/****************************************************************************
+** Device Configuration definitions
+****************************************************************************/
+
+#define NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN     (2 + NCI_PARAM_LEN_PLL325_CFG_PARAM)
+
+/* Crystal Frequency Index (in 1 KHz) */
+enum
+{
+    NFC_HAL_XTAL_INDEX_9600,
+    NFC_HAL_XTAL_INDEX_13000,
+    NFC_HAL_XTAL_INDEX_16200,
+    NFC_HAL_XTAL_INDEX_19200,
+    NFC_HAL_XTAL_INDEX_24000,
+    NFC_HAL_XTAL_INDEX_26000,
+    NFC_HAL_XTAL_INDEX_38400,
+    NFC_HAL_XTAL_INDEX_52000,
+    NFC_HAL_XTAL_INDEX_37400,
+    NFC_HAL_XTAL_INDEX_MAX
+};
+typedef UINT8 tNFC_HAL_XTAL_INDEX;
+
+/* Broadcom specific device initialization before sending NCI reset */
+#define NFC_HAL_DEV_INIT_FLAGS_SET_XTAL_FREQ  0x02    /* set crystal frequency    */
+typedef UINT8 tNFC_HAL_DEV_INIT_FLAGS;
+
+typedef struct
+{
+    tNFC_HAL_DEV_INIT_FLAGS flags;
+    UINT16                  xtal_freq;
+} tNFC_HAL_DEV_INIT_CFG;
+
+/*****************************************************************************
+**  Low Power Mode definitions
+*****************************************************************************/
+
+#define NFC_HAL_LP_SNOOZE_MODE_NONE      NFC_SNOOZE_MODE_NONE       /* Snooze mode disabled    */
+#define NFC_HAL_LP_SNOOZE_MODE_UART      NFC_SNOOZE_MODE_UART       /* Snooze mode for UART    */
+#define NFC_HAL_LP_SNOOZE_MODE_SPI_I2C   NFC_SNOOZE_MODE_SPI_I2C    /* Snooze mode for SPI/I2C */
+
+#define NFC_HAL_LP_ACTIVE_LOW            NFC_SNOOZE_ACTIVE_LOW      /* high to low voltage is asserting */
+#define NFC_HAL_LP_ACTIVE_HIGH           NFC_SNOOZE_ACTIVE_HIGH     /* low to high voltage is asserting */
+
+/*****************************************************************************
+**  Patch RAM Constants
+*****************************************************************************/
+
+/* patch format type */
+#define NFC_HAL_PRM_FORMAT_BIN  0x00
+#define NFC_HAL_PRM_FORMAT_HCD  0x01
+#define NFC_HAL_PRM_FORMAT_NCD  0x02
+typedef UINT8 tNFC_HAL_PRM_FORMAT;
+
+/*****************************************************************************
+**  Patch RAM Callback for event notificaton
+*****************************************************************************/
+/* Events for tNFC_HAL_PRM_CBACK */
+enum
+{
+    NFC_HAL_PRM_CONTINUE_EVT,
+    NFC_HAL_PRM_COMPLETE_EVT,
+    NFC_HAL_PRM_ABORT_EVT,
+    NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT,       /* Patch is invalid (bad version, project id, or chip)  */
+    NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT,       /* Patch has invalid signature                          */
+    NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT,     /* Secure Patch Download: request for patchfile header  */
+    NFC_HAL_PRM_SPD_GET_NEXT_PATCH,            /* Get first command of next patch in patchfile         */
+    NFC_HAL_PRM_ABORT_NO_NVM_EVT               /* nfc_hal_prm_nvm_required is TRUE and NVM is unavail  */
+};
+
+typedef void (tNFC_HAL_PRM_CBACK) (UINT8 event);
+
+typedef UINT8 tNFC_HAL_NCI_EVT;     /* MT + Opcode */
+typedef void (tNFC_HAL_NCI_CBACK) (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPreInitDone
+**
+** Description      Notify that pre-initialization of NFCC is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcReInit
+**
+** Description      This function is called to send an RESET and GET_PATCH_VERSION
+**                  command to NFCC.
+**
+**                  p_cback         - The callback function to receive the command
+**                                    status
+**
+** Note             This function should be called only during the HAL init process
+**
+** Returns          HAL_NFC_STATUS_OK if successfully initiated
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcReInit (tNFC_HAL_NCI_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetSnoozeMode
+**
+** Description      Set snooze mode
+**                  snooze_mode
+**                      NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
+**                      NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
+**                      NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
+**
+**                  idle_threshold_dh/idle_threshold_nfcc
+**                      Idle Threshold Host in 100ms unit
+**
+**                  nfc_wake_active_mode/dh_wake_active_mode
+**                      NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
+**                      NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting
+**
+**                  p_snooze_cback
+**                      Notify status of operation
+**
+** Returns          tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode,
+                                      UINT8 idle_threshold_dh,
+                                      UINT8 idle_threshold_nfcc,
+                                      UINT8 nfc_wake_active_mode,
+                                      UINT8 dh_wake_active_mode,
+                                      tHAL_NFC_STATUS_CBACK *p_snooze_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadStart
+**
+** Description      Initiate patch download
+**
+** Input Params
+**                  format_type     patch format type
+**                                  (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
+**                                   NFC_HAL_PRM_FORMAT_NCD)
+**
+**                  dest_address    destination adderess (needed for BIN format only)
+**
+**                  p_patchram_buf  pointer to patchram buffer. If NULL,
+**                                  then app must call HAL_NfcPrmDownloadContinue when
+**                                  NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
+**                                  segment of patchram
+**
+**                  patchram_len    size of p_patchram_buf (if non-NULL)
+**
+**                  patchram_delay  The delay after each patch.
+**                                  If the given value is less than the size of the patchram,
+**                                  the size of patchram is used instead.
+**
+**                  p_cback         callback for download status
+**
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
+                                 UINT32              dest_address,
+                                 UINT8               *p_patchram_buf,
+                                 UINT32              patchram_len,
+                                 UINT32              patchram_delay,
+                                 tNFC_HAL_PRM_CBACK  *p_cback);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmDownloadContinue
+**
+** Description      Send next segment of patchram to controller. Called when
+**                  NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+**                  Only needed if HAL_NfcPrmDownloadStart was called with
+**                  p_patchram_buf=NULL
+**
+** Input Params     p_patch_data    pointer to patch data
+**                  patch_data_len  patch data len
+**
+** Returns          TRUE if successful, otherwise FALSE
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
+                                    UINT16 patch_data_len);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetI2cPatch
+**
+** Description      Specify patchfile for BCM20791B3 I2C fix. This fix
+**                  must be downloaded prior to initial patch download for I2C
+**                  transport
+**
+** Input Params     p_i2c_patchfile_buf: pointer to patch for i2c fix
+**                  i2c_patchfile_len: length of patch
+**                  prei2c_delay: the delay before downloading main patch
+**                                if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
+**
+** Returns          Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf,
+                      UINT16 i2c_patchfile_len, UINT32 prei2c_delay);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description      Set Host-to-NFCC NCI message size for secure patch download
+**
+**                  This API must be called before calling HAL_NfcPrmDownloadStart.
+**                  If the API is not called, then PRM will use the default
+**                  message size.
+**
+**                  Typically, this API is only called for platforms that have
+**                  message-size limitations in the transport/driver.
+**
+**                  Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns          HAL_NFC_STATUS_OK if successful
+**                  HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetMaxRfDataCredits
+**
+** Description      This function sets the maximum RF data credit for HAL.
+**                  If 0, use the value reported from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits);
+
+/*******************************************************************************
+**
+** Function         HAL_NfcSetTraceLevel
+**
+** Description      This function sets the trace level for HAL.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 HAL_NfcSetTraceLevel (UINT8 new_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_INT_API_H */
+
diff --git a/src/hal/int/nfc_hal_nv_ci.h b/src/hal/int/nfc_hal_nv_ci.h
new file mode 100644
index 0000000..a77c207
--- /dev/null
+++ b/src/hal/int/nfc_hal_nv_ci.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for non valtile memory call-in functions.
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_NV_CI_H
+#define NFC_HAL_NV_CI_H
+
+#include "nfc_hal_nv_co.h"
+
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_write
+**
+** Description      This function sends an event to NFAA indicating the phone
+**                  has written the number of bytes specified in the call-out
+**                  function, nfa_nv_co_write (), and is ready for more data.
+**                  This function is used to control the TX data flow.
+**                  Note: The data buffer is released by the stack aioer
+**                        calling this function.
+**
+** Parameters       status - NFA_NV_CO_OK, NFA_NV_CO_NOSPACE, or NFA_NV_CO_FAIL
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_write (tNFC_HAL_NV_CO_STATUS status);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_ci_read
+**
+** Description      This function sends an event to NCIT indicating the phone has
+**                  read in the requested amount of data specified in the
+**                  nfa_nv_co_read () call-out function.  It should only be called
+**                  when the requested number of bytes has been read.
+**
+** Parameters       num_bytes_read - number of bytes read into the buffer
+**                      specified in the read callout-function.
+**                  status - NFC_HAL_NV_CO_OK if full buffer of data,
+**                           NFC_HAL_NV_CO_EOF if the end of file has been reached,
+**                           NFC_HAL_NV_CO_FAIL if an error has occurred.
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_read (UINT16                  num_bytes_read,
+                         tNFC_HAL_NV_CO_STATUS   status,
+                         UINT8                   block);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_HAL_NV_CI_H */
+
diff --git a/src/hal/int/nfc_hal_nv_co.h b/src/hal/int/nfc_hal_nv_co.h
new file mode 100644
index 0000000..2264cfe
--- /dev/null
+++ b/src/hal/int/nfc_hal_nv_co.h
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for storing nv data
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_NV_CO_H
+#define NFC_HAL_NV_CO_H
+
+#include <time.h>
+
+
+/*****************************************************************************
+**  Constants and Data Types
+*****************************************************************************/
+
+
+/**************************
+**  Common Definitions
+***************************/
+
+/* Status codes returned by call-out functions, or in call-in functions as status */
+#define NFC_HAL_NV_CO_OK            0x00
+#define NFC_HAL_NV_CO_FAIL          0x01 /* Used to pass all other errors */
+#define NFC_HAL_NV_CO_EACCES        0x02
+#define NFC_HAL_NV_CO_ENOTEMPTY     0x03
+#define NFC_HAL_NV_CO_EOF           0x04
+#define NFC_HAL_NV_CO_EODIR         0x05
+#define NFC_HAL_NV_CO_ENOSPACE      0x06 /* Returned in nfa_nv_ci_open if no room */
+#define NFC_HAL_NV_CO_EIS_DIR       0x07
+#define NFC_HAL_NV_CO_RESUME        0x08 /* used in nfa_nv_ci_open, on resume */
+#define NFC_HAL_NV_CO_NONE          0x09 /* used in nfa_nv_ci_open, on resume (no file to resume) */
+
+typedef UINT8 tNFC_HAL_NV_CO_STATUS;
+
+#define  DH_NV_BLOCK            0x01
+#define  HC_F3_NV_BLOCK         0x02
+#define  HC_F4_NV_BLOCK         0x03
+#define  HC_DH_NV_BLOCK         0x04
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+/**************************
+**  Common Functions
+***************************/
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been read, the end of file has been detected,
+**                        or an error has occurred.
+**
+*******************************************************************************/
+void nfc_hal_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+/*******************************************************************************
+**
+** Function         nfc_hal_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write () is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+
+#endif /* NFC_HAL_NV_CO_H */
diff --git a/src/hal/int/nfc_hal_post_reset.h b/src/hal/int/nfc_hal_post_reset.h
new file mode 100644
index 0000000..95da455
--- /dev/null
+++ b/src/hal/int/nfc_hal_post_reset.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Post NCI reset routines
+ *
+ ******************************************************************************/
+#ifndef NFC_HAL_POST_RESET_H
+#define NFC_HAL_POST_RESET_H
+
+
+/*****************************************************************************
+** Application control block definitions
+******************************************************************************/
+#define NFA_APP_PATCHFILE_MAX_PATH          255
+
+typedef struct
+{
+    UINT8 prm_file[NFA_APP_PATCHFILE_MAX_PATH+1];   /* Filename of patchram */
+    UINT8 *p_prm_buf;                               /* Pointer to buffer for holding patchram data */
+
+    /* Patchfile for I2C fix */
+    UINT8 prm_i2c_patchfile[NFA_APP_PATCHFILE_MAX_PATH+1];
+    UINT8 *p_prm_i2c_buf;
+
+    UINT8 userial_baud;
+
+    tNFC_HAL_DEV_INIT_CFG dev_init_config;
+
+    /* snooze mode setting */
+    UINT8 snooze_mode;
+    UINT8 idle_threshold_dh;
+    UINT8 idle_threshold_nfcc;
+    UINT8 nfc_wake_active_mode;
+    UINT8 dh_wake_active_mode;
+
+} tNFC_POST_RESET_CB;
+extern tNFC_POST_RESET_CB nfc_post_reset_cb;
+
+/*
+** Post NCI reset handler
+**
+** This function is called to start device pre-initialization after NCI CORE-RESET.
+** When pre-initialization is completed,
+** HAL_NfcPreInitDone() must be called to proceed with stack start up.
+*/
+void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type);
+
+
+#endif  /* NFC_HAL_POST_RESET_H */
diff --git a/src/include/NfcAdaptation.h b/src/include/NfcAdaptation.h
new file mode 100644
index 0000000..6065f1c
--- /dev/null
+++ b/src/include/NfcAdaptation.h
@@ -0,0 +1,100 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+#pragma once
+#include <pthread.h>
+#ifndef UINT32
+typedef unsigned long   UINT32;
+#endif
+#include "nfc_hal_api.h"
+#include <hardware/nfc.h>
+
+
+class ThreadMutex
+{
+public:
+    ThreadMutex();
+    virtual ~ThreadMutex();
+    void lock();
+    void unlock();
+    operator pthread_mutex_t* () {return &mMutex;}
+private:
+    pthread_mutex_t mMutex;
+};
+
+class ThreadCondVar : public ThreadMutex
+{
+public:
+    ThreadCondVar();
+    virtual ~ThreadCondVar();
+    void signal();
+    void wait();
+    operator pthread_cond_t* () {return &mCondVar;}
+    operator pthread_mutex_t* () {return ThreadMutex::operator pthread_mutex_t*();}
+private:
+    pthread_cond_t  mCondVar;
+};
+
+class AutoThreadMutex
+{
+public:
+    AutoThreadMutex(ThreadMutex &m);
+    virtual ~AutoThreadMutex();
+    operator ThreadMutex& ()          {return mm;}
+    operator pthread_mutex_t* () {return (pthread_mutex_t*)mm;}
+private:
+    ThreadMutex  &mm;
+};
+
+class NfcAdaptation
+{
+public:
+    virtual ~NfcAdaptation();
+    void    Initialize();
+    void    Finalize();
+    static  NfcAdaptation& GetInstance();
+    tHAL_NFC_ENTRY* GetHalEntryFuncs ();
+
+private:
+    NfcAdaptation();
+    void    signal();
+    static  NfcAdaptation* mpInstance;
+    static  ThreadMutex sLock;
+    ThreadCondVar    mCondVar;
+    pthread_t mThreadId;
+    tHAL_NFC_ENTRY   mHalEntryFuncs; // function pointers for HAL entry points
+    static nfc_nci_device_t* mHalDeviceContext;
+    static tHAL_NFC_CBACK* mHalCallback;
+    static tHAL_NFC_DATA_CBACK* mHalDataCallback;
+
+    static UINT32 NFCA_TASK (UINT32 arg);
+    static UINT32 Thread (UINT32 arg);
+    void InitializeHalDeviceContext ();
+    static void HalDeviceContextCallback (nfc_event_t event, nfc_status_t event_status);
+    static void HalDeviceContextDataCallback (uint16_t data_len, uint8_t* p_data);
+
+    static void HalInitialize ();
+    static void HalTerminate ();
+    static void HalOpen (tHAL_NFC_CBACK* p_hal_cback, tHAL_NFC_DATA_CBACK* p_data_cback);
+    static void HalClose ();
+    static void HalCoreInitialized (UINT8* p_core_init_rsp_params);
+    static void HalWrite (UINT16 data_len, UINT8* p_data);
+    static BOOLEAN HalPrediscover ();
+    static void HalControlGranted ();
+    static void HalPowerCycle ();
+};
+
diff --git a/src/include/OverrideLog.h b/src/include/OverrideLog.h
new file mode 100644
index 0000000..2a9847f
--- /dev/null
+++ b/src/include/OverrideLog.h
@@ -0,0 +1,63 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Override the Android logging macro(s) from
+ *  /system/core/include/cutils/log.h. This header must be the first header
+ *  included by a *.cpp file so the original Android macro can be replaced.
+ *  Do not include this header in another header, because that will create
+ *  unnecessary dependency.
+ *
+ ******************************************************************************/
+#pragma once
+
+//Override Android's ALOGD macro by adding a boolean expression.
+#define ALOGD(...) ((void)ALOGD_IF(appl_trace_level>=BT_TRACE_LEVEL_DEBUG, __VA_ARGS__))
+
+
+#include <cutils/log.h> //define Android logging macros
+#include "bt_types.h" //define various BT_TRACE_LEVEL_*
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    extern unsigned char appl_trace_level; //defined in /external/libnfc-nci/
+#ifdef __cplusplus
+}
+#endif
+
+
+/*******************************************************************************
+**
+** Function:        initializeGlobalAppLogLevel
+**
+** Description:     Initialize and get global logging level from .conf or
+**                  Android property nfc.app_log_level.  The Android property
+**                  overrides .conf variable.
+**
+** Returns:         Global log level:
+**                  BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**                  BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**                  BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**                  BT_TRACE_LEVEL_API     3        * API traces
+**                  BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**                  BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char initializeGlobalAppLogLevel ();
diff --git a/src/include/bcm2079x.h b/src/include/bcm2079x.h
new file mode 100644
index 0000000..7bf095d
--- /dev/null
+++ b/src/include/bcm2079x.h
@@ -0,0 +1,44 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012 Broadcom Corporation
+ *
+ *  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 _BCM2079X_H
+#define _BCM2079X_H
+
+#define BCMNFC_MAGIC	0xFA
+
+/*
+ * BCMNFC power control via ioctl
+ * BCMNFC_POWER_CTL(0): power off
+ * BCMNFC_POWER_CTL(1): power on
+ * BCMNFC_WAKE_CTL(0): wake off
+ * BCMNFC_WAKE_CTL(1): wake on
+ */
+#define BCMNFC_POWER_CTL		_IO(BCMNFC_MAGIC, 0x01)
+#define BCMNFC_CHANGE_ADDR		_IO(BCMNFC_MAGIC, 0x02)
+#define BCMNFC_READ_FULL_PACKET		_IO(BCMNFC_MAGIC, 0x03)
+#define BCMNFC_SET_WAKE_ACTIVE_STATE	_IO(BCMNFC_MAGIC, 0x04)
+#define BCMNFC_WAKE_CTL			_IO(BCMNFC_MAGIC, 0x05)
+#define BCMNFC_READ_MULTI_PACKETS	_IO(BCMNFC_MAGIC, 0x06)
+
+struct bcm2079x_platform_data {
+	unsigned int irq_gpio;
+	unsigned int en_gpio;
+	int wake_gpio;
+};
+
+#endif
diff --git a/src/include/bt_target.h b/src/include/bt_target.h
new file mode 100644
index 0000000..d873a20
--- /dev/null
+++ b/src/include/bt_target.h
@@ -0,0 +1,4048 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 BT_TARGET_H
+#define BT_TARGET_H
+
+#include "data_types.h"
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+/* Include common GKI definitions used by this platform */
+#include "gki_target.h"
+
+#include "bt_types.h"   /* This must be defined AFTER buildcfg.h */
+#include "dyn_mem.h"    /* defines static and/or dynamic memory for components */
+
+/* #define BYPASS_AVDATATRACE */
+
+/******************************************************************************
+**
+** Platform-Specific
+**
+******************************************************************************/
+
+/* set to FALSE unless using Zeevo */
+#ifndef ZEEVO_CTRL_DEFINED
+#define ZEEVO_CTRL_DEFINED FALSE
+#endif
+
+/* Supporting GPS shared transport */
+#ifndef GPS_INCLUDED
+#define GPS_INCLUDED               TRUE
+#endif
+
+/* API macros for simulator */
+
+#define BTAPI
+
+#ifndef BTE_BSE_WRAPPER
+#ifdef  BTE_SIM_APP
+#undef  BTAPI
+#define BTAPI         __declspec(dllexport)
+#endif
+#endif
+
+#define BT_API          BTAPI
+#define BTU_API         BTAPI
+#define A2D_API         BTAPI
+#define VDP_API         BTAPI
+#define AVDT_API        BTAPI
+#define AVCT_API        BTAPI
+#define AVRC_API        BTAPI
+#define BIP_API         BTAPI
+#define BNEP_API        BTAPI
+#define BPP_API         BTAPI
+#define BTM_API         BTAPI
+#define CTP_API         BTAPI
+#define DUN_API         BTAPI
+#define FTP_API         BTAPI
+#define GAP_API         BTAPI
+#define GOEP_API        BTAPI
+#define HCI_API         BTAPI
+#define HCRP_API        BTAPI
+#define HID_API         BTAPI
+#define HFP_API         BTAPI
+#define HSP2_API        BTAPI
+#define ICP_API         BTAPI
+#define L2C_API         BTAPI
+#define OBX_API         BTAPI
+#define OPP_API         BTAPI
+#define PAN_API         BTAPI
+#define RFC_API         BTAPI
+#define RPC_API         BTAPI
+#define SDP_API         BTAPI
+#define SPP_API         BTAPI
+#define TCS_API         BTAPI
+#define XML_API         BTAPI
+#define BTA_API         BTAPI
+#define SBC_API         BTAPI
+#define LPM_API         BTAPI
+#define AMP_API         BTAPI
+#define MCE_API         BTAPI
+#define MCA_API         BTAPI
+#define GATT_API        BTAPI
+#define SMP_API         BTAPI
+
+
+/******************************************************************************
+**
+** GKI Buffer Pools
+**
+******************************************************************************/
+
+/* Receives HCI events from the lower-layer. */
+#ifndef HCI_CMD_POOL_ID
+#define HCI_CMD_POOL_ID             GKI_POOL_ID_2
+#endif
+
+#ifndef HCI_CMD_POOL_BUF_SIZE
+#define HCI_CMD_POOL_BUF_SIZE       GKI_BUF2_SIZE
+#endif
+
+/* Receives ACL data packets from thelower-layer. */
+#ifndef HCI_ACL_POOL_ID
+#define HCI_ACL_POOL_ID             GKI_POOL_ID_3
+#endif
+
+#ifndef HCI_ACL_POOL_BUF_SIZE
+#define HCI_ACL_POOL_BUF_SIZE       GKI_BUF3_SIZE
+#endif
+
+/* Maximum number of buffers available for ACL receive data. */
+#ifndef HCI_ACL_BUF_MAX
+#define HCI_ACL_BUF_MAX             GKI_BUF3_MAX
+#endif
+
+/* Receives SCO data packets from the lower-layer. */
+#ifndef HCI_SCO_POOL_ID
+#define HCI_SCO_POOL_ID             GKI_POOL_ID_6
+#endif
+
+/* Not used. */
+#ifndef HCI_DATA_DESCR_POOL_ID
+#define HCI_DATA_DESCR_POOL_ID      GKI_POOL_ID_0
+#endif
+
+/* Sends SDP data packets. */
+#ifndef SDP_POOL_ID
+#define SDP_POOL_ID                 GKI_POOL_ID_2
+#endif
+
+/* Sends RFCOMM command packets. */
+#ifndef RFCOMM_CMD_POOL_ID
+#define RFCOMM_CMD_POOL_ID          GKI_POOL_ID_2
+#endif
+
+#ifndef RFCOMM_CMD_POOL_BUF_SIZE
+#define RFCOMM_CMD_POOL_BUF_SIZE    GKI_BUF2_SIZE
+#endif
+
+/* Sends RFCOMM data packets. */
+#ifndef RFCOMM_DATA_POOL_ID
+#define RFCOMM_DATA_POOL_ID         GKI_POOL_ID_3
+#endif
+
+#ifndef RFCOMM_DATA_POOL_BUF_SIZE
+#define RFCOMM_DATA_POOL_BUF_SIZE   GKI_BUF3_SIZE
+#endif
+
+/* Sends L2CAP packets to the peer and HCI messages to the controller. */
+#ifndef L2CAP_CMD_POOL_ID
+#define L2CAP_CMD_POOL_ID           GKI_POOL_ID_2
+#endif
+
+/* Sends L2CAP segmented packets in ERTM mode */
+#ifndef L2CAP_FCR_TX_POOL_ID
+#define L2CAP_FCR_TX_POOL_ID        HCI_ACL_POOL_ID
+#endif
+
+/* Receives L2CAP segmented packets in ERTM mode */
+#ifndef L2CAP_FCR_RX_POOL_ID
+#define L2CAP_FCR_RX_POOL_ID        HCI_ACL_POOL_ID
+#endif
+
+/* Used by BTM when it sends HCI commands to the controller. */
+#ifndef BTM_CMD_POOL_ID
+#define BTM_CMD_POOL_ID             GKI_POOL_ID_2
+#endif
+
+/* Sends TCS messages. */
+#ifndef TCS_MSG_POOL_ID
+#define TCS_MSG_POOL_ID             GKI_POOL_ID_2
+#endif
+
+#ifndef OBX_CMD_POOL_SIZE
+#define OBX_CMD_POOL_SIZE           GKI_BUF2_SIZE
+#endif
+
+#ifndef OBX_LRG_DATA_POOL_SIZE
+#define OBX_LRG_DATA_POOL_SIZE      GKI_BUF4_SIZE
+#endif
+
+#ifndef OBX_LRG_DATA_POOL_ID
+#define OBX_LRG_DATA_POOL_ID        GKI_POOL_ID_4
+#endif
+
+/* Used for CTP discovery database. */
+#ifndef CTP_SDP_DB_POOL_ID
+#define CTP_SDP_DB_POOL_ID          GKI_POOL_ID_3
+#endif
+
+/* Used for CTP data exchange feature. */
+#ifndef CTP_DATA_EXCHG_POOL_ID
+#define CTP_DATA_EXCHG_POOL_ID      GKI_POOL_ID_2
+#endif
+
+/* Used to send data to L2CAP. */
+#ifndef GAP_DATA_POOL_ID
+#define GAP_DATA_POOL_ID            GKI_POOL_ID_3
+#endif
+
+/* Used for SPP inquiry and discovery databases. */
+#ifndef SPP_DB_POOL_ID
+#define SPP_DB_POOL_ID              GKI_POOL_ID_3
+#endif
+
+#ifndef SPP_DB_SIZE
+#define SPP_DB_SIZE                 GKI_BUF3_SIZE
+#endif
+
+/* HCRP protocol and internal commands. */
+#ifndef HCRP_CMD_POOL_ID
+#define HCRP_CMD_POOL_ID            GKI_POOL_ID_2
+#endif
+
+#ifndef HCRP_CMD_POOL_SIZE
+#define HCRP_CMD_POOL_SIZE          GKI_BUF2_SIZE
+#endif
+
+#ifndef BIP_EVT_POOL_SIZE
+#define BIP_EVT_POOL_SIZE           GKI_BUF3_SIZE
+#endif
+
+#ifndef BIP_DB_SIZE
+#define BIP_DB_SIZE                 GKI_BUF3_SIZE
+#endif
+
+
+/* BNEP data and protocol messages. */
+#ifndef BNEP_POOL_ID
+#define BNEP_POOL_ID                GKI_POOL_ID_3
+#endif
+
+/* RPC pool for temporary trace message buffers. */
+#ifndef RPC_SCRATCH_POOL_ID
+#define RPC_SCRATCH_POOL_ID         GKI_POOL_ID_2
+#endif
+
+/* RPC scratch buffer size (not related to RPC_SCRATCH_POOL_ID) */
+#ifndef RPC_SCRATCH_BUF_SIZE
+#define RPC_SCRATCH_BUF_SIZE        GKI_BUF3_SIZE
+#endif
+
+/* RPC pool for protocol messages */
+#ifndef RPC_MSG_POOL_ID
+#define RPC_MSG_POOL_ID             GKI_POOL_ID_3
+#endif
+
+#ifndef RPC_MSG_POOL_SIZE
+#define RPC_MSG_POOL_SIZE           GKI_BUF3_SIZE
+#endif
+
+/* AVDTP pool for protocol messages */
+#ifndef AVDT_CMD_POOL_ID
+#define AVDT_CMD_POOL_ID            GKI_POOL_ID_2
+#endif
+
+/* AVDTP pool size for media packets in case of fragmentation */
+#ifndef AVDT_DATA_POOL_SIZE
+#define AVDT_DATA_POOL_SIZE         GKI_BUF3_SIZE
+#endif
+
+#ifndef PAN_POOL_ID
+#define PAN_POOL_ID                 GKI_POOL_ID_3
+#endif
+
+/* UNV pool for read/write serialization */
+#ifndef UNV_MSG_POOL_ID
+#define UNV_MSG_POOL_ID             GKI_POOL_ID_2
+#endif
+
+#ifndef UNV_MSG_POOL_SIZE
+#define UNV_MSG_POOL_SIZE           GKI_BUF2_SIZE
+#endif
+
+/* AVCTP pool for protocol messages */
+#ifndef AVCT_CMD_POOL_ID
+#define AVCT_CMD_POOL_ID            GKI_POOL_ID_1
+#endif
+
+#ifndef AVCT_META_CMD_POOL_ID
+#define AVCT_META_CMD_POOL_ID       GKI_POOL_ID_2
+#endif
+
+/* AVRCP pool for protocol messages */
+#ifndef AVRC_CMD_POOL_ID
+#define AVRC_CMD_POOL_ID            GKI_POOL_ID_1
+#endif
+
+/* AVRCP pool size for protocol messages */
+#ifndef AVRC_CMD_POOL_SIZE
+#define AVRC_CMD_POOL_SIZE          GKI_BUF1_SIZE
+#endif
+
+/* AVRCP Metadata pool for protocol messages */
+#ifndef AVRC_META_CMD_POOL_ID
+#define AVRC_META_CMD_POOL_ID       GKI_POOL_ID_2
+#endif
+
+/* AVRCP Metadata pool size for protocol messages */
+#ifndef AVRC_META_CMD_POOL_SIZE
+#define AVRC_META_CMD_POOL_SIZE     GKI_BUF2_SIZE
+#endif
+
+
+/* AVRCP buffer size for browsing channel messages */
+#ifndef AVRC_BROWSE_POOL_SIZE
+#define AVRC_BROWSE_POOL_SIZE     GKI_MAX_BUF_SIZE
+#endif
+
+/*  HDP buffer size for the Pulse Oximeter  */
+#ifndef BTA_HL_LRG_DATA_POOL_SIZE
+#define BTA_HL_LRG_DATA_POOL_SIZE      GKI_BUF7_SIZE
+#endif
+
+#ifndef BTA_HL_LRG_DATA_POOL_ID
+#define BTA_HL_LRG_DATA_POOL_ID        GKI_POOL_ID_7
+#endif
+
+/* GATT Server Database pool ID */
+#ifndef GATT_DB_POOL_ID
+#define GATT_DB_POOL_ID                 GKI_POOL_ID_8
+#endif
+
+
+/******************************************************************************
+**
+** Lower Layer Interface
+**
+******************************************************************************/
+
+/* Sends ACL data received over HCI to the upper stack. */
+#ifndef HCI_ACL_DATA_TO_UPPER
+#define HCI_ACL_DATA_TO_UPPER(p)    {((BT_HDR *)p)->event = BT_EVT_TO_BTU_HCI_ACL; GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p);}
+#endif
+
+/* Sends SCO data received over HCI to the upper stack. */
+#ifndef HCI_SCO_DATA_TO_UPPER
+#define HCI_SCO_DATA_TO_UPPER(p)    {((BT_HDR *)p)->event = BT_EVT_TO_BTU_HCI_SCO; GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p);}
+#endif
+
+/* Sends an HCI event received over HCI to theupper stack. */
+#ifndef HCI_EVT_TO_UPPER
+#define HCI_EVT_TO_UPPER(p)         {((BT_HDR *)p)->event = BT_EVT_TO_BTU_HCI_EVT; GKI_send_msg (BTU_TASK, BTU_HCI_RCV_MBOX, p);}
+#endif
+
+/* HCI 4 wire power management protocol. */
+#ifndef HCILL_INCLUDED
+#define HCILL_INCLUDED              FALSE
+#endif
+
+/* Macro for allocating buffer for HCI commands */
+#ifndef HCI_GET_CMD_BUF
+#if (!defined(HCI_USE_VARIABLE_SIZE_CMD_BUF) || (HCI_USE_VARIABLE_SIZE_CMD_BUF == FALSE))
+/* Allocate fixed-size buffer from HCI_CMD_POOL (default case) */
+#define HCI_GET_CMD_BUF(paramlen)    ((BT_HDR *)GKI_getpoolbuf (HCI_CMD_POOL_ID))
+#else
+/* Allocate smallest possible buffer (for platforms with limited RAM) */
+#define HCI_GET_CMD_BUF(paramlen)    ((BT_HDR *)GKI_getbuf ((UINT16)(BT_HDR_SIZE + HCIC_PREAMBLE_SIZE + (paramlen))))
+#endif
+#endif  /* HCI_GET_CMD_BUF */
+
+/******************************************************************************
+**
+** HCI Services (H4)
+**
+******************************************************************************/
+#ifndef HCISU_H4_INCLUDED
+#define HCISU_H4_INCLUDED               FALSE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+BT_API extern void bte_ncisu_send (BT_HDR *p_pkt, UINT16 event);
+BT_API extern void bte_hcisu_send (BT_HDR *p_msg, UINT16 event);
+#if (HCISU_H4_INCLUDED == TRUE)
+BT_API extern void bte_hcisu_lp_allow_bt_device_sleep (void);
+BT_API extern void bte_hcisu_lp_wakeup_host (void);
+BT_API extern void bte_hcisu_lp_h4ibss_evt(UINT8 *p, UINT8 evt_len);
+#endif
+
+/* HCILL API for the applications */
+typedef void (tHCILL_SLEEP_ACK)(void);
+BT_API extern void HCILL_GoToSleep( tHCILL_SLEEP_ACK *sl_ack_fn);
+typedef void (tHCILL_STATE_CBACK)(BOOLEAN is_sleep);
+BT_API extern void HCILL_RegState( tHCILL_STATE_CBACK *p_cback);
+#ifdef __cplusplus
+}
+#endif
+
+/* Sends ACL data received from the upper stack to the BD/EDR HCI transport. */
+#ifndef HCI_ACL_DATA_TO_LOWER
+#define HCI_ACL_DATA_TO_LOWER(p)    bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_ACL);
+#endif
+
+#ifndef HCI_BLE_ACL_DATA_TO_LOWER
+#define HCI_BLE_ACL_DATA_TO_LOWER(p)    bte_hcisu_send((BT_HDR *)(p), (UINT16)(BT_EVT_TO_LM_HCI_ACL|LOCAL_BLE_CONTROLLER_ID));
+#endif
+
+/* Sends ACL data received from the upper stack to the AMP HCI transport. */
+#ifndef HCI_AMP_DATA_TO_LOWER
+#define HCI_AMP_DATA_TO_LOWER(p,x)    bte_hcisu_send((BT_HDR *)(p), (UINT16)(BT_EVT_TO_LM_HCI_ACL|((UINT16)(x))));
+#endif
+
+/* Sends SCO data received from the upper stack to the HCI transport. */
+#ifndef HCI_SCO_DATA_TO_LOWER
+#define HCI_SCO_DATA_TO_LOWER(p)    bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_SCO);
+#endif
+
+/* Sends an HCI command received from the upper stack to the BD/EDR HCI transport. */
+#ifndef HCI_CMD_TO_LOWER
+#define HCI_CMD_TO_LOWER(p)         bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_HCI_CMD);
+#endif
+
+/* Sends an HCI command received from the upper stack to the AMP HCI transport. */
+#ifndef HCI_CMD_TO_AMP
+#define HCI_CMD_TO_AMP(x,p)         bte_hcisu_send((BT_HDR *)(p), (UINT16)(BT_EVT_TO_LM_HCI_CMD|((UINT16)(x))));
+#endif
+
+/* Sends an LM Diagnosic command received from the upper stack to the HCI transport. */
+#ifndef HCI_LM_DIAG_TO_LOWER
+#define HCI_LM_DIAG_TO_LOWER(p)     bte_hcisu_send((BT_HDR *)(p), BT_EVT_TO_LM_DIAG);
+#endif
+
+/* Send HCISU a message to allow BT sleep */
+#ifndef HCI_LP_ALLOW_BT_DEVICE_SLEEP
+#if (HCISU_H4_INCLUDED == TRUE)
+#define HCI_LP_ALLOW_BT_DEVICE_SLEEP()       bte_hcisu_lp_allow_bt_device_sleep()
+#else
+#define HCI_LP_ALLOW_BT_DEVICE_SLEEP()       HCILP_AllowBTDeviceSleep()
+#endif
+#endif
+
+/* Send HCISU a message to wakeup host */
+#ifndef HCI_LP_WAKEUP_HOST
+#if (HCISU_H4_INCLUDED == TRUE)
+#define HCI_LP_WAKEUP_HOST()        bte_hcisu_lp_wakeup_host()
+#else
+#define HCI_LP_WAKEUP_HOST()        HCILP_WakeupHost()
+#endif
+#endif
+
+/* Send HCISU the received H4IBSS event from controller */
+#ifndef HCI_LP_RCV_H4IBSS_EVT
+#if (HCISU_H4_INCLUDED == TRUE)
+#define HCI_LP_RCV_H4IBSS_EVT(p1, p2)  bte_hcisu_lp_h4ibss_evt((UINT8*)(p1), (UINT8)(p2))
+#else
+#define HCI_LP_RCV_H4IBSS_EVT(p1, p2)  h4ibss_sleep_mode_evt((UINT8*)(p1), (UINT8)(p2))
+#endif
+#endif
+
+/* If nonzero, the upper-layer sends at most this number of HCI commands to the lower-layer. */
+#ifndef HCI_MAX_SIMUL_CMDS
+#define HCI_MAX_SIMUL_CMDS          0
+#endif
+
+/* Timeout for receiving response to HCI command */
+#ifndef BTU_CMD_CMPL_TIMEOUT
+#define BTU_CMD_CMPL_TIMEOUT        8
+#endif
+
+/* If TRUE, BTU task will check HCISU again when HCI command timer expires */
+#ifndef BTU_CMD_CMPL_TOUT_DOUBLE_CHECK
+#define BTU_CMD_CMPL_TOUT_DOUBLE_CHECK      FALSE
+#endif
+
+/* If TRUE, stack is compiled to include MM dual stack functionality */
+#ifndef BTU_DUAL_STACK_MM_INCLUDED
+#define BTU_DUAL_STACK_MM_INCLUDED     FALSE
+#endif
+
+/* If TRUE, stack is compiled to support Embedded Lite Stack in BT chip */
+#ifndef BTU_DUAL_STACK_BTC_INCLUDED
+#define BTU_DUAL_STACK_BTC_INCLUDED      FALSE
+#endif
+
+/* If TRUE, stack is compiled to support Embedded Lite Stack for AV SNK in BT chip */
+#ifndef BTU_BTC_SNK_INCLUDED
+#define BTU_BTC_SNK_INCLUDED        FALSE
+#endif
+
+/* If TRUE, stack is compiled as Lite Stack in Multimedia chip */
+/* If FALSE, stack is compiled as Full Stack in Baseband chip */
+#ifndef BTU_STACK_LITE_ENABLED
+#define BTU_STACK_LITE_ENABLED      FALSE
+#endif
+
+/* Transport pause time (BT slot(0.625ms) unit) when switching between BB and MM */
+/* FW is using a tick which is 20 slot unit so if timeout is between 0 to 20 slot */
+/* then actual timeout would be 0 to 12.5ms because it could be beteen ticks. */
+/* if timeout is between 20 to 40 slot then actual timeout would be 12.5 to 25ms */
+#ifndef BTU_DUAL_TRANSPORT_PAUSE_TIME
+#define BTU_DUAL_TRANSPORT_PAUSE_TIME     40
+#endif
+
+/* if UART baudrate is different between BB and MM, it will be updated during switching */
+#ifndef BTU_DUAL_TRANSPORT_BB_BAUDRATE
+#define BTU_DUAL_TRANSPORT_BB_BAUDRATE      115200
+#endif
+
+#ifndef BTU_DUAL_TRANSPORT_MM_BAUDRATE
+#define BTU_DUAL_TRANSPORT_MM_BAUDRATE      921600
+#endif
+
+/* If TRUE, stack is compiled to include the multi-av feature (A2DP packets are duplicated inside controller) */
+#ifndef BTU_MULTI_AV_INCLUDED
+#define BTU_MULTI_AV_INCLUDED       FALSE
+#endif
+
+/* Use 2 second for low-resolution systems, override to 1 for high-resolution systems */
+#ifndef BT_1SEC_TIMEOUT
+#define BT_1SEC_TIMEOUT             (2)
+#endif
+
+/* Quick Timer */
+/* if L2CAP_FCR_INCLUDED is TRUE then it should have 100 millisecond resolution */
+/* if HCILP_INCLUDED is TRUE     then it should have 100 millisecond resolution */
+/* if SLIP_INCLUDED is TRUE      then it should have 10 millisecond resolution  */
+/* if BCM2045_USE_DELAY is FALSE then it should have 10 millisecond resolution  */
+/* if none of them is included then QUICK_TIMER_TICKS_PER_SEC is set to 0 to exclude quick timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC   100       /* 10ms timer */
+#endif
+
+/******************************************************************************
+**
+** BTM
+**
+******************************************************************************/
+/* if set to TRUE, stack will automatically send an HCI reset at start-up. To be
+set to FALSE for advanced start-up / shut-down procedures using USER_HW_ENABLE_API
+and USER_HW_DISABLE_API macros */
+#ifndef BTM_AUTOMATIC_HCI_RESET
+#define BTM_AUTOMATIC_HCI_RESET      TRUE
+#endif
+
+/* Include BTM Discovery database and code. */
+#ifndef BTM_DISCOVERY_INCLUDED
+#define BTM_DISCOVERY_INCLUDED      TRUE
+#endif
+
+/* Include inquiry code. */
+#ifndef BTM_INQUIRY_INCLUDED
+#define BTM_INQUIRY_INCLUDED        TRUE
+#endif
+
+/* Cancel Inquiry on incoming SSP - Work around code for a FW issue (CQ#167446). */
+#ifndef BTM_NO_SSP_ON_INQUIRY
+#define BTM_NO_SSP_ON_INQUIRY       FALSE
+#endif
+
+/* Include periodic inquiry code (used when BTM_INQUIRY_INCLUDED is TRUE). */
+#ifndef BTM_PERIODIC_INQ_INCLUDED
+#define BTM_PERIODIC_INQ_INCLUDED   TRUE
+#endif
+
+/* Include security authorization code */
+#ifndef BTM_AUTHORIZATION_INCLUDED
+#define BTM_AUTHORIZATION_INCLUDED  TRUE
+#endif
+
+/* Include the implemenation needed by Pre-Lisbon controller (2.0_EDR or older) */
+#ifndef BTM_PRE_LISBON_INCLUDED
+#define BTM_PRE_LISBON_INCLUDED     TRUE
+#endif
+
+
+/* Includes SCO if TRUE */
+#ifndef BTM_SCO_INCLUDED
+#define BTM_SCO_INCLUDED            TRUE       /* TRUE includes SCO code */
+#endif
+
+/* Includes SCO if TRUE */
+#ifndef BTM_SCO_HCI_INCLUDED
+#define BTM_SCO_HCI_INCLUDED            FALSE       /* TRUE includes SCO over HCI code */
+#endif
+
+/* Includes WBS if TRUE */
+#ifndef BTM_WBS_INCLUDED
+#define BTM_WBS_INCLUDED            FALSE       /* TRUE includes WBS code */
+#endif
+
+/* Includes PCM2 support if TRUE */
+#ifndef BTM_PCM2_INCLUDED
+#define BTM_PCM2_INCLUDED           FALSE
+#endif
+
+/* If FALSE, AFH channel automatically adjusted based on AMP channel in use */
+/* Set TRUE, if want to bypass AFH channel automatic adjustment and use */
+/* BTA_DM_API_SET_AFH_CHANNELS_ API */
+
+#ifndef BTM_BYPASS_AMP_AUTO_AFH
+#define BTM_BYPASS_AMP_AUTO_AFH     FALSE
+#endif
+
+
+/**************************
+** Initial SCO TX credit
+*************************/
+/* max TX SCO data packet size */
+#ifndef BTM_SCO_DATA_SIZE_MAX
+#define BTM_SCO_DATA_SIZE_MAX       240
+#endif
+
+/* maximum BTM buffering capacity */
+#ifndef BTM_SCO_MAX_BUF_CAP
+#define BTM_SCO_MAX_BUF_CAP     (BTM_SCO_INIT_XMIT_CREDIT * 4)
+#endif
+
+/* The size in bytes of the BTM inquiry database. */
+#ifndef BTM_INQ_DB_SIZE
+#define BTM_INQ_DB_SIZE             12
+#endif
+
+/* This is set to enable automatic periodic inquiry at startup. */
+#ifndef BTM_ENABLE_AUTO_INQUIRY
+#define BTM_ENABLE_AUTO_INQUIRY     FALSE
+#endif
+
+/* This is set to always try to acquire the remote device name. */
+#ifndef BTM_INQ_GET_REMOTE_NAME
+#define BTM_INQ_GET_REMOTE_NAME     FALSE
+#endif
+
+/* The inquiry duration in 1.28 second units when auto inquiry is enabled. */
+#ifndef BTM_DEFAULT_INQ_DUR
+#define BTM_DEFAULT_INQ_DUR         5
+#endif
+
+/* The inquiry mode when auto inquiry is enabled. */
+#ifndef BTM_DEFAULT_INQ_MODE
+#define BTM_DEFAULT_INQ_MODE        BTM_GENERAL_INQUIRY
+#endif
+
+/* The default periodic inquiry maximum delay when auto inquiry is enabled, in 1.28 second units. */
+#ifndef BTM_DEFAULT_INQ_MAX_DELAY
+#define BTM_DEFAULT_INQ_MAX_DELAY   30
+#endif
+
+/* The default periodic inquiry minimum delay when auto inquiry is enabled, in 1.28 second units. */
+#ifndef BTM_DEFAULT_INQ_MIN_DELAY
+#define BTM_DEFAULT_INQ_MIN_DELAY   20
+#endif
+
+/* The maximum age of entries in inquiry database in seconds ('0' disables feature). */
+#ifndef BTM_INQ_MAX_AGE
+#define BTM_INQ_MAX_AGE             0
+#endif
+
+/* The maximum age of entries in inquiry database based on inquiry response failure ('0' disables feature). */
+#ifndef BTM_INQ_AGE_BY_COUNT
+#define BTM_INQ_AGE_BY_COUNT        0
+#endif
+
+/* TRUE if controller does not support inquiry event filtering. */
+#ifndef BTM_BYPASS_EVENT_FILTERING
+#define BTM_BYPASS_EVENT_FILTERING  FALSE
+#endif
+
+/* TRUE if inquiry filtering is desired from BTM. */
+#ifndef BTM_USE_INQ_RESULTS_FILTER
+#define BTM_USE_INQ_RESULTS_FILTER  TRUE
+#endif
+
+/* The default scan mode */
+#ifndef BTM_DEFAULT_SCAN_TYPE
+#define BTM_DEFAULT_SCAN_TYPE       BTM_SCAN_TYPE_INTERLACED
+#endif
+
+/* Should connections to unknown devices be allowed when not discoverable? */
+#ifndef BTM_ALLOW_CONN_IF_NONDISCOVER
+#define BTM_ALLOW_CONN_IF_NONDISCOVER   FALSE
+#endif
+
+/* When connectable mode is set to TRUE, the device will respond to paging. */
+#ifndef BTM_IS_CONNECTABLE
+#define BTM_IS_CONNECTABLE          FALSE
+#endif
+
+/* Sets the Page_Scan_Window:  the length of time that the device is performing a page scan. */
+#ifndef BTM_DEFAULT_CONN_WINDOW
+#define BTM_DEFAULT_CONN_WINDOW     0x0012
+#endif
+
+/* Sets the Page_Scan_Activity:  the interval between the start of two consecutive page scans. */
+#ifndef BTM_DEFAULT_CONN_INTERVAL
+#define BTM_DEFAULT_CONN_INTERVAL   0x0800
+#endif
+
+/* This is set to automatically perform inquiry scan on startup. */
+#ifndef BTM_IS_DISCOVERABLE
+#define BTM_IS_DISCOVERABLE         FALSE
+#endif
+
+/* When automatic inquiry scan is enabled, this sets the discovery mode. */
+#ifndef BTM_DEFAULT_DISC_MODE
+#define BTM_DEFAULT_DISC_MODE       BTM_GENERAL_DISCOVERABLE
+#endif
+
+/* When automatic inquiry scan is enabled, this sets the inquiry scan window. */
+#ifndef BTM_DEFAULT_DISC_WINDOW
+#define BTM_DEFAULT_DISC_WINDOW     0x0012
+#endif
+
+/* When automatic inquiry scan is enabled, this sets the inquiry scan interval. */
+#ifndef BTM_DEFAULT_DISC_INTERVAL
+#define BTM_DEFAULT_DISC_INTERVAL   0x0800
+#endif
+
+/* Sets the period, in seconds, to automatically perform service discovery. */
+#ifndef BTM_AUTO_DISCOVERY_PERIOD
+#define BTM_AUTO_DISCOVERY_PERIOD   0
+#endif
+
+/* The size in bytes of the BTM discovery database (if discovery is included). */
+#ifndef BTM_DISCOVERY_DB_SIZE
+#define BTM_DISCOVERY_DB_SIZE       4000
+#endif
+
+/* Number of milliseconds to delay BTU task startup upon device initialization. */
+#ifndef BTU_STARTUP_DELAY
+#define BTU_STARTUP_DELAY           0
+#endif
+
+/* Whether BTA is included in BTU task. */
+#ifndef BTU_BTA_INCLUDED
+#define BTU_BTA_INCLUDED            FALSE
+#endif
+
+/* Number of seconds to wait to send an HCI Reset command upon device initialization. */
+#ifndef BTM_FIRST_RESET_DELAY
+#define BTM_FIRST_RESET_DELAY       0
+#endif
+
+/* The number of seconds to wait for controller module to reset after issuing an HCI Reset command. */
+#ifndef BTM_AFTER_RESET_TIMEOUT
+#define BTM_AFTER_RESET_TIMEOUT     0
+#endif
+
+/* The default class of device. */
+#ifndef BTM_INIT_CLASS_OF_DEVICE
+#define BTM_INIT_CLASS_OF_DEVICE    "\x00\x1F\x00"
+#endif
+
+/* The number of SCO links. */
+#ifndef BTM_MAX_SCO_LINKS
+#define BTM_MAX_SCO_LINKS           3
+#endif
+
+/* The preferred type of SCO links (2-eSCO, 0-SCO). */
+#ifndef BTM_DEFAULT_SCO_MODE
+#define BTM_DEFAULT_SCO_MODE        2
+#endif
+
+/* The number of security records for peer devices. */
+#ifndef BTM_SEC_MAX_DEVICE_RECORDS
+#define BTM_SEC_MAX_DEVICE_RECORDS  8
+#endif
+
+/* The number of security records for services. */
+#ifndef BTM_SEC_MAX_SERVICE_RECORDS
+#define BTM_SEC_MAX_SERVICE_RECORDS 24
+#endif
+
+/* If True, force a retrieval of remote device name for each bond in case it's changed */
+#ifndef BTM_SEC_FORCE_RNR_FOR_DBOND
+#define BTM_SEC_FORCE_RNR_FOR_DBOND  TRUE
+#endif
+
+/* Maximum device name length used in btm database. */
+#ifndef BTM_MAX_REM_BD_NAME_LEN
+#define BTM_MAX_REM_BD_NAME_LEN     20
+#endif
+
+/* Maximum local device name length stored btm database.
+  '0' disables storage of the local name in BTM */
+#ifndef BTM_MAX_LOC_BD_NAME_LEN
+#define BTM_MAX_LOC_BD_NAME_LEN     31
+#endif
+
+/* TRUE if default string is used, FALSE if device name is set in the application */
+#ifndef BTM_USE_DEF_LOCAL_NAME
+#define BTM_USE_DEF_LOCAL_NAME      FALSE
+#endif
+
+/* Fixed Default String (Ignored if BTM_USE_DEF_LOCAL_NAME is FALSE) */
+#ifndef BTM_DEF_LOCAL_NAME
+#define BTM_DEF_LOCAL_NAME      ""
+#endif
+
+/* Maximum service name stored with security authorization (0 if not needed) */
+#ifndef BTM_SEC_SERVICE_NAME_LEN
+#define BTM_SEC_SERVICE_NAME_LEN    BT_MAX_SERVICE_NAME_LEN
+#endif
+
+/* Maximum number of pending security callback */
+#ifndef BTM_SEC_MAX_CALLBACKS
+#define BTM_SEC_MAX_CALLBACKS       7
+#endif
+
+/* Maximum length of the service name. */
+#ifndef BT_MAX_SERVICE_NAME_LEN
+#define BT_MAX_SERVICE_NAME_LEN     21
+#endif
+
+/* ACL buffer size in HCI Host Buffer Size command. */
+#ifndef BTM_ACL_BUF_SIZE
+#define BTM_ACL_BUF_SIZE            0
+#endif
+
+/* This is set to use the BTM power manager. */
+#ifndef BTM_PWR_MGR_INCLUDED
+#define BTM_PWR_MGR_INCLUDED        TRUE
+#endif
+
+/* The maximum number of clients that can register with the power manager. */
+#ifndef BTM_MAX_PM_RECORDS
+#define BTM_MAX_PM_RECORDS          2
+#endif
+
+/* This is set to show debug trace messages for the power manager. */
+#ifndef BTM_PM_DEBUG
+#define BTM_PM_DEBUG                FALSE
+#endif
+
+/* This is set to TRUE if link is to be unparked due to BTM_CreateSCO API. */
+#ifndef BTM_SCO_WAKE_PARKED_LINK
+#define BTM_SCO_WAKE_PARKED_LINK    TRUE
+#endif
+
+/* May be set to the the name of a function used for vendor specific chip initialization */
+#ifndef BTM_APP_DEV_INIT
+/* #define BTM_APP_DEV_INIT         myInitFunction() */
+#endif
+
+/* This is set to TRUE if the busy level change event is desired. (replace ACL change event) */
+#ifndef BTM_BUSY_LEVEL_CHANGE_INCLUDED
+#define BTM_BUSY_LEVEL_CHANGE_INCLUDED  TRUE
+#endif
+
+/* If the user does not respond to security process requests within this many seconds,
+ * a negative response would be sent automatically.
+ * It's recommended to use a value between 30 and OBX_TIMEOUT_VALUE
+ * 30 is LMP response timeout value */
+#ifndef BTM_SEC_TIMEOUT_VALUE
+#define BTM_SEC_TIMEOUT_VALUE           35
+#endif
+
+/* Maximum number of callbacks that can be registered using BTM_RegisterForVSEvents */
+#ifndef BTM_MAX_VSE_CALLBACKS
+#define BTM_MAX_VSE_CALLBACKS           3
+#endif
+
+/* Number of streams for dual stack */
+#ifndef BTM_SYNC_INFO_NUM_STR
+#define BTM_SYNC_INFO_NUM_STR           2
+#endif
+
+/* Number of streams for dual stack in BT Controller */
+#ifndef BTM_SYNC_INFO_NUM_STR_BTC
+#define BTM_SYNC_INFO_NUM_STR_BTC       2
+#endif
+
+/******************************************
+**    Lisbon Features
+*******************************************/
+/* This is set to TRUE if the server Extended Inquiry Response feature is desired. */
+/* server sends EIR to client */
+#ifndef BTM_EIR_SERVER_INCLUDED
+#define BTM_EIR_SERVER_INCLUDED         TRUE
+#endif
+
+/* This is set to TRUE if the client Extended Inquiry Response feature is desired. */
+/* client inquiry to server */
+#ifndef BTM_EIR_CLIENT_INCLUDED
+#define BTM_EIR_CLIENT_INCLUDED         TRUE
+#endif
+
+/* This is set to TRUE if the FEC is required for EIR packet. */
+#ifndef BTM_EIR_DEFAULT_FEC_REQUIRED
+#define BTM_EIR_DEFAULT_FEC_REQUIRED    TRUE
+#endif
+
+/* User defined UUID look up table */
+#ifndef BTM_EIR_UUID_LKUP_TBL
+#endif
+
+/* The IO capability of the local device (for Simple Pairing) */
+#ifndef BTM_LOCAL_IO_CAPS
+#define BTM_LOCAL_IO_CAPS               BTM_IO_CAP_IO
+#endif
+
+/* The default MITM Protection Requirement (for Simple Pairing)
+ * Possible values are BTM_AUTH_SP_YES or BTM_AUTH_SP_NO */
+#ifndef BTM_DEFAULT_AUTH_REQ
+#define BTM_DEFAULT_AUTH_REQ            BTM_AUTH_SP_NO
+#endif
+
+/* The default MITM Protection Requirement for dedicated bonding using Simple Pairing
+ * Possible values are BTM_AUTH_AP_YES or BTM_AUTH_AP_NO */
+#ifndef BTM_DEFAULT_DD_AUTH_REQ
+#define BTM_DEFAULT_DD_AUTH_REQ            BTM_AUTH_AP_YES
+#endif
+
+/* Include Out-of-Band implementation for Simple Pairing */
+#ifndef BTM_OOB_INCLUDED
+#define BTM_OOB_INCLUDED                TRUE
+#endif
+
+/* TRUE to include Sniff Subrating */
+#ifndef BTM_SSR_INCLUDED
+#define BTM_SSR_INCLUDED                TRUE
+#endif
+
+/*************************
+** End of Lisbon Features
+**************************/
+
+/* Used for conformance testing ONLY */
+#ifndef BTM_BLE_CONFORMANCE_TESTING
+#define BTM_BLE_CONFORMANCE_TESTING           FALSE
+#endif
+
+
+/******************************************************************************
+**
+** L2CAP
+**
+******************************************************************************/
+
+/* Flow control and retransmission mode */
+
+#ifndef L2CAP_FCR_INCLUDED
+#define L2CAP_FCR_INCLUDED FALSE
+#endif
+
+/* The maximum number of simultaneous links that L2CAP can support. */
+#ifndef MAX_L2CAP_LINKS
+#define MAX_L2CAP_LINKS             4
+#endif
+
+/* The maximum number of simultaneous channels that L2CAP can support. */
+#ifndef MAX_L2CAP_CHANNELS
+#define MAX_L2CAP_CHANNELS          10
+#endif
+
+/* The maximum number of simultaneous applications that can register with L2CAP. */
+#ifndef MAX_L2CAP_CLIENTS
+#define MAX_L2CAP_CLIENTS           8
+#endif
+
+/* The number of seconds of link inactivity before a link is disconnected. */
+#ifndef L2CAP_LINK_INACTIVITY_TOUT
+#define L2CAP_LINK_INACTIVITY_TOUT  3
+#endif
+
+/* The number of seconds of link inactivity after bonding before a link is disconnected. */
+#ifndef L2CAP_BONDING_TIMEOUT
+#define L2CAP_BONDING_TIMEOUT       3
+#endif
+
+/* The time from the HCI connection complete to disconnect if no channel is established. */
+#ifndef L2CAP_LINK_STARTUP_TOUT
+#define L2CAP_LINK_STARTUP_TOUT     60
+#endif
+
+/* The L2CAP MTU; must be in accord with the HCI ACL pool size. */
+#ifndef L2CAP_MTU_SIZE
+#define L2CAP_MTU_SIZE              1691
+#endif
+
+/* The L2CAP MPS over Bluetooth; must be in accord with the FCR tx pool size and ACL down buffer size. */
+#ifndef L2CAP_MPS_OVER_BR_EDR
+#define L2CAP_MPS_OVER_BR_EDR       1010
+#endif
+
+/* The L2CAP MPS over AMP; must be in accord with the FCR tx pool size and ACL down buffer size. */
+#ifndef L2CAP_MPS_OVER_AMP
+#define L2CAP_MPS_OVER_AMP          1480
+#endif
+
+/* This is set to enable host flow control. */
+#ifndef L2CAP_HOST_FLOW_CTRL
+#define L2CAP_HOST_FLOW_CTRL        FALSE
+#endif
+
+/* If host flow control enabled, this is the number of buffers the controller can have unacknowledged. */
+#ifndef L2CAP_HOST_FC_ACL_BUFS
+#define L2CAP_HOST_FC_ACL_BUFS      20
+#endif
+
+/* The percentage of the queue size allowed before a congestion event is sent to the L2CAP client (typically 120%). */
+#ifndef L2CAP_FWD_CONG_THRESH
+#define L2CAP_FWD_CONG_THRESH       120
+#endif
+
+/* This is set to enable L2CAP to  take the ACL link out of park mode when ACL data is to be sent. */
+#ifndef L2CAP_WAKE_PARKED_LINK
+#define L2CAP_WAKE_PARKED_LINK      TRUE
+#endif
+
+/* Whether link wants to be the master or the slave. */
+#ifndef L2CAP_DESIRED_LINK_ROLE
+#define L2CAP_DESIRED_LINK_ROLE     HCI_ROLE_SLAVE
+#endif
+
+/* Include Non-Flushable Packet Boundary Flag feature of Lisbon */
+#ifndef L2CAP_NON_FLUSHABLE_PB_INCLUDED
+#define L2CAP_NON_FLUSHABLE_PB_INCLUDED     TRUE
+#endif
+
+/* max queued Multi-AV packets per link including controller */
+#ifndef L2CAP_MULTI_AV_TOTAL_QUEUED_BUF
+#define L2CAP_MULTI_AV_TOTAL_QUEUED_BUF     6
+#endif
+
+/* max links supported by Multi-AV feature */
+#ifndef L2CAP_MAX_MULTI_AV_CID
+#define L2CAP_MAX_MULTI_AV_CID              5
+#endif
+
+/* Minimum number of ACL credit for high priority link */
+#ifndef L2CAP_HIGH_PRI_MIN_XMIT_QUOTA
+#define L2CAP_HIGH_PRI_MIN_XMIT_QUOTA       4
+#endif
+
+/* used for monitoring HCI ACL credit management */
+#ifndef L2CAP_HCI_FLOW_CONTROL_DEBUG
+#define L2CAP_HCI_FLOW_CONTROL_DEBUG        TRUE
+#endif
+
+/* Used for calculating transmit buffers off of */
+#ifndef L2CAP_NUM_XMIT_BUFFS
+#define L2CAP_NUM_XMIT_BUFFS                HCI_ACL_BUF_MAX
+#endif
+
+/* Unicast Connectionless Data */
+#ifndef L2CAP_UCD_INCLUDED
+#define L2CAP_UCD_INCLUDED                  FALSE
+#endif
+
+/* Unicast Connectionless Data MTU */
+#ifndef L2CAP_UCD_MTU
+#define L2CAP_UCD_MTU                       L2CAP_MTU_SIZE
+#endif
+
+/* Unicast Connectionless Data Idle Timeout */
+#ifndef L2CAP_UCD_IDLE_TIMEOUT
+#define L2CAP_UCD_IDLE_TIMEOUT              2
+#endif
+
+/* Unicast Connectionless Data Idle Timeout */
+#ifndef L2CAP_UCD_CH_PRIORITY
+#define L2CAP_UCD_CH_PRIORITY               L2CAP_CHNL_PRIORITY_MEDIUM
+#endif
+
+/* Max clients on Unicast Connectionless Data */
+#ifndef L2CAP_MAX_UCD_CLIENTS
+#define L2CAP_MAX_UCD_CLIENTS               5
+#endif
+
+/* Used for features using fixed channels; set to zero if no fixed channels supported (AMP, BLE, etc.) */
+/* Excluding L2CAP signaling channel and UCD */
+#ifndef L2CAP_NUM_FIXED_CHNLS
+#define L2CAP_NUM_FIXED_CHNLS               4
+#endif
+
+/* First fixed channel supported; 3 if AMP supported */
+#ifndef L2CAP_FIRST_FIXED_CHNL
+#define L2CAP_FIRST_FIXED_CHNL              3
+#endif
+
+#ifndef L2CAP_LAST_FIXED_CHNL
+#define L2CAP_LAST_FIXED_CHNL           (L2CAP_FIRST_FIXED_CHNL + L2CAP_NUM_FIXED_CHNLS - 1)
+#endif
+
+/* Round Robin service channels in link */
+#ifndef L2CAP_ROUND_ROBIN_CHANNEL_SERVICE
+#define L2CAP_ROUND_ROBIN_CHANNEL_SERVICE   TRUE
+#endif
+
+/* Reconfig after move channel between BR/EDR and AMP */
+#ifndef L2CAP_MOVE_CH_RECONFIG_INCLUDED
+#define L2CAP_MOVE_CH_RECONFIG_INCLUDED     FALSE
+#endif
+
+/* Initiate reconfig after move channel between BR/EDR and AMP */
+#ifndef L2CAP_MOVE_CH_RECONFIG_INTITIATOR
+#define L2CAP_MOVE_CH_RECONFIG_INTITIATOR   FALSE
+#endif
+
+/* Adjust our monitor timeout in ms plus peer's processing time on class 2 AMP controller */
+#ifndef L2CAP_AMP_ADJUST_MONITOR_TOUT
+#define L2CAP_AMP_ADJUST_MONITOR_TOUT       500
+#endif
+
+/* Adjust our retrans timeout in ms plus peer's processing time on class 2 AMP controller */
+#ifndef L2CAP_AMP_ADJUST_RETRANS_TOUT
+#define L2CAP_AMP_ADJUST_RETRANS_TOUT       500
+#endif
+
+/* Default local device's processing time (ms) */
+#ifndef L2CAP_AMP_PROCESSING_TIME
+#define L2CAP_AMP_PROCESSING_TIME           500
+#endif
+
+/* Used for calculating transmit buffers off of */
+#ifndef L2CAP_NUM_XMIT_BUFFS
+#define L2CAP_NUM_XMIT_BUFFS                HCI_ACL_BUF_MAX
+#endif
+
+/* Used for features using fixed channels; set to zero if no fixed channels supported (AMP, BLE, etc.) */
+#ifndef L2CAP_NUM_FIXED_CHNLS
+#define L2CAP_NUM_FIXED_CHNLS               1
+#endif
+
+/* First fixed channel supported; 3 if AMP supported */
+#ifndef L2CAP_FIRST_FIXED_CHNL
+#define L2CAP_FIRST_FIXED_CHNL              3
+#endif
+
+#ifndef L2CAP_LAST_FIXED_CHNL
+#define L2CAP_LAST_FIXED_CHNL           (L2CAP_FIRST_FIXED_CHNL + L2CAP_NUM_FIXED_CHNLS - 1)
+#endif
+
+/* used for monitoring eL2CAP data flow */
+#ifndef L2CAP_ERTM_STATS
+#define L2CAP_ERTM_STATS                    FALSE
+#endif
+
+/* USED FOR FCR TEST ONLY:  When TRUE generates bad tx and rx packets */
+#ifndef L2CAP_CORRUPT_ERTM_PKTS
+#define L2CAP_CORRUPT_ERTM_PKTS             FALSE
+#endif
+
+/* Used for conformance testing ONLY:  When TRUE lets scriptwrapper overwrite info response */
+#ifndef L2CAP_CONFORMANCE_TESTING
+#define L2CAP_CONFORMANCE_TESTING           FALSE
+#endif
+
+/******************************************************************************
+**
+** AMP
+**
+******************************************************************************/
+
+#ifndef AMP_INCLUDED
+#define AMP_INCLUDED            FALSE
+#endif
+
+/* TRUE if AMP includes debug functionality. */
+#ifndef AMP_DEBUG
+#define AMP_DEBUG               FALSE
+#endif
+
+/* Maximum number of simultaneous remote AMP Hosts in system */
+#ifndef AMP_MAX_REMOTE_HOSTS
+#define AMP_MAX_REMOTE_HOSTS    MAX_L2CAP_LINKS
+#endif
+
+/* Maximum number of simultaneous remote AMP controllers in system (BR/EDR excluded) */
+#ifndef AMP_MAX_REMOTE_CTRLS
+#define AMP_MAX_REMOTE_CTRLS    2
+#endif
+
+/* Maximum number of UUIDs per remote AMP host */
+#ifndef AMP_MAX_UUIDS_PER_REM_HOST
+#define AMP_MAX_UUIDS_PER_REM_HOST  4
+#endif
+
+/* Maximum number of simultaneous local AMP controllers in system (BR/EDR excluded) */
+#ifndef AMP_MAX_LOCAL_CTRLS
+#define AMP_MAX_LOCAL_CTRLS     1
+#endif
+
+/* Maximum number of simultaneous Physical Links in system */
+#ifndef AMP_MAX_PHYS_LINKS
+#define AMP_MAX_PHYS_LINKS      1
+#endif
+
+/* The maximum number of simultaneous AMP logical links that L2CAP can support. */
+#ifndef AMP_MAX_L2C_LOG_LINKS
+#define AMP_MAX_L2C_LOG_LINKS   (MAX_L2CAP_LINKS * 2)
+#endif
+
+/* The number of seconds of link inactivity on AMP fixed channel before the ACL is disconnected. */
+#ifndef AMP_L2C_INACTIVITY_TIMER
+#define AMP_L2C_INACTIVITY_TIMER    7
+#endif
+
+#ifndef AMP_NUM_ALWAYS_PRESENT_LOC_CTRLRS
+#define AMP_NUM_ALWAYS_PRESENT_LOC_CTRLRS       AMP_MAX_LOCAL_CTRLS
+#endif
+
+/* If this is non-zero value then l2cap overwrites total ACL credit on AMP. */
+/* This temporarily needs until number in dhd driver is finalized */
+#ifndef AMP_TOTAL_NUM_BLOCKS
+#define AMP_TOTAL_NUM_BLOCKS        0
+#endif
+
+/****************************
+** AMP Autoswitch Constants
+*****************************/
+/* AMP physical link inactivity timeout
+** This is started when the last logical channel got disconnected */
+#ifndef AMP_PHYS_LINK_INACT_DISC_TOUT
+#define AMP_PHYS_LINK_INACT_DISC_TOUT               20
+#endif
+
+/* interval between the moments to check if auto-switch ready connections
+** on this AMP controller have to be moved to BR/EDR and if yes - to
+** start to move the connections */
+#ifndef AMP_AS_TOUT_ON_AMP
+#define AMP_AS_TOUT_ON_AMP                          1
+#endif
+
+/* on timeout all auto-switch ready connections
+** have to be moved from BR/EDR to AMP */
+#ifndef AMP_AS_TOUT_ON_BR_EDR
+#define AMP_AS_TOUT_ON_BR_EDR                       1
+#endif
+
+/* min time to stay on BR/EDR after auto-switch from AMP
+** (during this time conditions to switch from BR/EDR to
+** AMP are ignored) */
+#ifndef AMP_AS_TOUT_NO_MOVE_TO_AMP
+#define AMP_AS_TOUT_NO_MOVE_TO_AMP                  4
+#endif
+
+/* TRUE means that "tout to check throughput on BR/EDR"
+** is restarted after "no move to AMP" timer expires,
+** i.e. move from BR/EDR will start not earlier than
+**  AMP_AS_TOUT_NO_MOVE_TO_AMP + AMP_AS_TOUT_ON_BR_EDR
+** FALSE means that "tout no move to AMP" and "tout
+** to check throughput on BR/EDR" run in parallel, i.e.
+** connections can be moved from BR/EDR any moment after
+** "tout no move to AMP" expires. */
+#ifndef AMP_AS_TOUT_ON_BR_EDR_AFTER_NO_MOVE_TO_AMP
+#define AMP_AS_TOUT_ON_BR_EDR_AFTER_NO_MOVE_TO_AMP  TRUE
+#endif
+
+/* Until the number of packets sent to L2CAP is <= than this
+** value preparations for auto-switch BR/EDR->AMP do not start.
+** If the number of packets sent to L2CAP falls to this
+** value preparations for auto-switch BR/EDR->AMP stop. */
+#ifndef AMP_AS_THRESHOLD_ON_BR_EDR
+#define AMP_AS_THRESHOLD_ON_BR_EDR                  3
+#endif
+
+/* the number of counters used to collect throughput data
+** on AMP controller. Check for auto-switch conditions starts
+** AMP_AMP_AS_COUNT_ARRAY_SIZE * AMP_AS_TOUT_ON_AMP
+** sec after the first auto-switch ready connection is moved
+** to this controller */
+#ifndef AMP_AMP_AS_COUNT_ARRAY_SIZE
+#define AMP_AMP_AS_COUNT_ARRAY_SIZE                 10
+#endif
+
+/* meaning: flow spec modify is never sent to controller
+**          best effort logical link is created with all
+**          parameters sent to unknown...*/
+#ifndef AMP_SIMPLISTIC_AGGREGATION
+#define AMP_SIMPLISTIC_AGGREGATION  TRUE
+#endif
+
+/* meaning: auto-switch ready connections start move
+** BR/EDR->AMP after throughput to remote host passes
+** some threshold in bytes (as opposite to move that
+** starts if during some time the number of UNACKED
+** L2CAP packets to remote host stays bigger than some
+** threshold) */
+#ifndef AMP_AUTO_SW_TO_AMP_BY_THROUGHPUT
+#define AMP_AUTO_SW_TO_AMP_BY_THROUGHPUT TRUE
+#endif
+
+/* the number of counters used to collect throughput data
+** on BR/EDR controller. Check for auto-switch conditions starts
+** AMP_BR_EDR_AS_COUNT_ARRAY_SIZE * AMP_AS_TOUT_ON_BR_EDR
+** sec after the first auto-switch ready connection is moved
+** to this controller */
+#ifndef AMP_BR_EDR_AS_COUNT_ARRAY_SIZE
+#define AMP_BR_EDR_AS_COUNT_ARRAY_SIZE              7
+#endif
+
+/* if it takes more than this amount of time to transfer object on BR/EDR
+** application(BTA) will initiate to AMP connection. */
+#ifndef AMP_AS_TRANSFER_TIME_ON_BR_EDR
+#define AMP_AS_TRANSFER_TIME_ON_BR_EDR              5
+#endif
+
+
+#ifndef AMP_RFC_TEST
+#define AMP_RFC_TEST            FALSE
+#endif
+
+#ifndef TIMER_PARAM_TYPE
+#ifdef  WIN2000
+#define TIMER_PARAM_TYPE    void *
+#else
+#define TIMER_PARAM_TYPE    UINT32
+#endif
+#endif
+
+/******************************************************************************
+**
+** BLE
+**
+******************************************************************************/
+
+#ifndef BLE_INCLUDED
+#define BLE_INCLUDED            FALSE
+#endif
+
+#ifndef LOCAL_BLE_CONTROLLER_ID
+#define LOCAL_BLE_CONTROLLER_ID         (AMP_MAX_LOCAL_CTRLS + 1)
+#endif
+
+/******************************************************************************
+**
+** ATT/GATT Protocol/Profile Settings
+**
+******************************************************************************/
+#ifndef ATT_INCLUDED
+#define ATT_INCLUDED         FALSE
+#endif
+
+#ifndef ATT_DEBUG
+#define ATT_DEBUG           FALSE
+#endif
+
+#ifndef GATT_SERVER_ENABLED
+#define GATT_SERVER_ENABLED          FALSE
+#endif
+
+#ifndef GATT_CLIENT_ENABLED
+#define GATT_CLIENT_ENABLED          FALSE
+#endif
+
+#ifndef GATT_MAX_SR_PROFILES
+#define GATT_MAX_SR_PROFILES        32 /* max is 32 */
+#endif
+
+#ifndef GATT_MAX_APPS
+#define GATT_MAX_APPS            10 /* note: 2 apps used internally GATT and GAP */
+#endif
+
+#ifndef GATT_MAX_PHY_CHANNEL
+#define GATT_MAX_PHY_CHANNEL        4
+#endif
+
+/* Used for conformance testing ONLY */
+#ifndef GATT_CONFORMANCE_TESTING
+#define GATT_CONFORMANCE_TESTING           FALSE
+#endif
+
+/* number of background connection device allowence, ideally to be the same as WL size
+*/
+#ifndef GATT_MAX_BG_CONN_DEV
+#define GATT_MAX_BG_CONN_DEV        32
+#endif
+
+/******************************************************************************
+**
+** SMP
+**
+******************************************************************************/
+#ifndef SMP_INCLUDED
+#define SMP_INCLUDED         FALSE
+#endif
+
+#ifndef SMP_DEBUG
+#define SMP_DEBUG            FALSE
+#endif
+
+#ifndef SMP_DEFAULT_AUTH_REQ
+#define SMP_DEFAULT_AUTH_REQ    SMP_AUTH_NB_ENC_ONLY
+#endif
+
+#ifndef SMP_MAX_ENC_KEY_SIZE
+#define SMP_MAX_ENC_KEY_SIZE    16
+#endif
+
+#ifndef SMP_MIN_ENC_KEY_SIZE
+#define SMP_MIN_ENC_KEY_SIZE    7
+#endif
+
+/* Used for conformance testing ONLY */
+#ifndef SMP_CONFORMANCE_TESTING
+#define SMP_CONFORMANCE_TESTING           FALSE
+#endif
+
+/******************************************************************************
+**
+** SDP
+**
+******************************************************************************/
+
+/* This is set to enable SDP server functionality. */
+#ifndef SDP_SERVER_ENABLED
+#define SDP_SERVER_ENABLED          TRUE
+#endif
+
+/* The maximum number of SDP records the server can support. */
+#ifndef SDP_MAX_RECORDS
+#define SDP_MAX_RECORDS             20
+#endif
+
+/* The maximum number of attributes in each record. */
+#ifndef SDP_MAX_REC_ATTR
+#if defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)
+#define SDP_MAX_REC_ATTR            25
+#else
+#define SDP_MAX_REC_ATTR            13
+#endif
+#endif
+
+#ifndef SDP_MAX_PAD_LEN
+#define SDP_MAX_PAD_LEN             350
+#endif
+
+/* The maximum length, in bytes, of an attribute. */
+#ifndef SDP_MAX_ATTR_LEN
+#if defined(HID_DEV_INCLUDED) && (HID_DEV_INCLUDED==TRUE)
+#define SDP_MAX_ATTR_LEN            80
+#else
+#define SDP_MAX_ATTR_LEN            100
+#endif
+#endif
+
+/* The maximum number of attribute filters supported by SDP databases. */
+#ifndef SDP_MAX_ATTR_FILTERS
+#define SDP_MAX_ATTR_FILTERS        12
+#endif
+
+/* The maximum number of UUID filters supported by SDP databases. */
+#ifndef SDP_MAX_UUID_FILTERS
+#define SDP_MAX_UUID_FILTERS        3
+#endif
+
+/* This is set to enable SDP client functionality. */
+#ifndef SDP_CLIENT_ENABLED
+#define SDP_CLIENT_ENABLED          TRUE
+#endif
+
+/* The maximum number of record handles retrieved in a search. */
+#ifndef SDP_MAX_DISC_SERVER_RECS
+#define SDP_MAX_DISC_SERVER_RECS    21
+#endif
+
+/* The size of a scratchpad buffer, in bytes, for storing the response to an attribute request. */
+#ifndef SDP_MAX_LIST_BYTE_COUNT
+#define SDP_MAX_LIST_BYTE_COUNT     1000
+#endif
+
+/* The maximum number of parameters in an SDP protocol element. */
+#ifndef SDP_MAX_PROTOCOL_PARAMS
+#define SDP_MAX_PROTOCOL_PARAMS     2
+#endif
+
+/* The maximum number of simultaneous client and server connections. */
+#ifndef SDP_MAX_CONNECTIONS
+#define SDP_MAX_CONNECTIONS         4
+#endif
+
+/* The MTU size for the L2CAP configuration. */
+#ifndef SDP_MTU_SIZE
+#define SDP_MTU_SIZE                256
+#endif
+
+/* The flush timeout for the L2CAP configuration. */
+#ifndef SDP_FLUSH_TO
+#define SDP_FLUSH_TO                0xFFFF
+#endif
+
+/* The name for security authorization. */
+#ifndef SDP_SERVICE_NAME
+#define SDP_SERVICE_NAME            "Service Discovery"
+#endif
+
+/* The security level for BTM. */
+#ifndef SDP_SECURITY_LEVEL
+#define SDP_SECURITY_LEVEL          BTM_SEC_NONE
+#endif
+
+/* Device identification feature. */
+#ifndef SDP_DI_INCLUDED
+#define SDP_DI_INCLUDED             FALSE
+#endif
+
+/******************************************************************************
+**
+** RFCOMM
+**
+******************************************************************************/
+
+#ifndef RFCOMM_INCLUDED
+#define RFCOMM_INCLUDED             FALSE
+#endif
+
+/* The maximum number of ports supported. */
+#ifndef MAX_RFC_PORTS
+#define MAX_RFC_PORTS               5
+#endif
+
+/* The maximum simultaneous links to different devices. */
+#ifndef MAX_BD_CONNECTIONS
+#define MAX_BD_CONNECTIONS          1
+#endif
+
+/* The port receive queue low watermark level, in bytes. */
+#ifndef PORT_RX_LOW_WM
+#define PORT_RX_LOW_WM              5000
+#endif
+
+/* The port receive queue high watermark level, in bytes. */
+#ifndef PORT_RX_HIGH_WM
+#define PORT_RX_HIGH_WM             8000
+#endif
+
+/* The port receive queue critical watermark level, in bytes. */
+#ifndef PORT_RX_CRITICAL_WM
+#define PORT_RX_CRITICAL_WM         12000
+#endif
+
+/* The port receive queue low watermark level, in number of buffers. */
+#ifndef PORT_RX_BUF_LOW_WM
+#define PORT_RX_BUF_LOW_WM          8
+#endif
+
+/* The port receive queue high watermark level, in number of buffers. */
+#ifndef PORT_RX_BUF_HIGH_WM
+#define PORT_RX_BUF_HIGH_WM         16
+#endif
+
+/* The port receive queue critical watermark level, in number of buffers. */
+#ifndef PORT_RX_BUF_CRITICAL_WM
+#define PORT_RX_BUF_CRITICAL_WM     22
+#endif
+
+/* The port transmit queue high watermark level, in bytes. */
+#ifndef PORT_TX_HIGH_WM
+#define PORT_TX_HIGH_WM             8000
+#endif
+
+/* The port transmit queue critical watermark level, in bytes. */
+#ifndef PORT_TX_CRITICAL_WM
+#define PORT_TX_CRITICAL_WM         10000
+#endif
+
+/* The port transmit queue high watermark level, in number of buffers. */
+#ifndef PORT_TX_BUF_HIGH_WM
+#define PORT_TX_BUF_HIGH_WM         16
+#endif
+
+/* The port transmit queue high watermark level, in number of buffers. */
+#ifndef PORT_TX_BUF_CRITICAL_WM
+#define PORT_TX_BUF_CRITICAL_WM     22
+#endif
+
+/* The RFCOMM multiplexer preferred flow control mechanism. */
+#ifndef PORT_FC_DEFAULT
+#define PORT_FC_DEFAULT             PORT_FC_CREDIT
+#endif
+
+/* The maximum number of credits receiver sends to peer when using credit-based flow control. */
+#ifndef PORT_CREDIT_RX_MAX
+#define PORT_CREDIT_RX_MAX          16
+#endif
+
+/* The credit low watermark level. */
+#ifndef PORT_CREDIT_RX_LOW
+#define PORT_CREDIT_RX_LOW          8
+#endif
+
+/* Test code allowing l2cap FEC on RFCOMM.*/
+#ifndef PORT_ENABLE_L2CAP_FCR_TEST
+#define PORT_ENABLE_L2CAP_FCR_TEST  FALSE
+#endif
+
+/* if application like BTA, Java or script test engine is running on other than BTU thread, */
+/* PORT_SCHEDULE_LOCK shall be defined as GKI_sched_lock() or GKI_disable() */
+#ifndef PORT_SCHEDULE_LOCK
+#define PORT_SCHEDULE_LOCK          GKI_disable()
+#endif
+
+/* if application like BTA, Java or script test engine is running on other than BTU thread, */
+/* PORT_SCHEDULE_LOCK shall be defined as GKI_sched_unlock() or GKI_enable() */
+#ifndef PORT_SCHEDULE_UNLOCK
+#define PORT_SCHEDULE_UNLOCK        GKI_enable()
+#endif
+
+/******************************************************************************
+**
+** TCS
+**
+******************************************************************************/
+
+#ifndef TCS_INCLUDED
+#define TCS_INCLUDED                FALSE
+#endif
+
+/* If set to TRUE, gives lean TCS state machine configuration. */
+#ifndef TCS_LEAN
+#define TCS_LEAN                    FALSE
+#endif
+
+/* To include/exclude point-to-multipoint broadcast SETUP configuration. */
+#ifndef TCS_BCST_SETUP_INCLUDED
+#define TCS_BCST_SETUP_INCLUDED     TRUE
+#endif
+
+/* To include/exclude supplementary services. */
+#ifndef TCS_SUPP_SVCS_INCLUDED
+#define TCS_SUPP_SVCS_INCLUDED      TRUE
+#endif
+
+/* To include/exclude WUG master role. */
+#ifndef TCS_WUG_MASTER_INCLUDED
+#define TCS_WUG_MASTER_INCLUDED     TRUE
+#endif
+
+/* To include/exclude WUG member role. */
+#ifndef TCS_WUG_MEMBER_INCLUDED
+#define TCS_WUG_MEMBER_INCLUDED     TRUE
+#endif
+
+/* Maximum number of WUG members. */
+#ifndef TCS_MAX_WUG_MEMBERS
+#define TCS_MAX_WUG_MEMBERS         7
+#endif
+
+/* Widcomm specific acknowledgement message to ensure fast and robust operation of WUG FIMA procedure. */
+#ifndef TCS_WUG_LISTEN_ACPT_ACK_INCLUDED
+#define TCS_WUG_LISTEN_ACPT_ACK_INCLUDED TRUE
+#endif
+
+/* The number of simultaneous calls supported. */
+#ifndef TCS_MAX_NUM_SIMUL_CALLS
+#define TCS_MAX_NUM_SIMUL_CALLS     3
+#endif
+
+/* The number of devices the device can connect to. */
+#ifndef TCS_MAX_NUM_ACL_CONNS
+#define TCS_MAX_NUM_ACL_CONNS       7
+#endif
+
+/* The maximum length, in bytes, of the company specific information element. */
+#ifndef TCS_MAX_CO_SPEC_LEN
+#define TCS_MAX_CO_SPEC_LEN         40
+#endif
+
+/* The maximum length, in bytes, of the audio control information element . */
+#ifndef TCS_MAX_AUDIO_CTL_LEN
+#define TCS_MAX_AUDIO_CTL_LEN       40
+#endif
+
+/* (Dis)allow EDR ESCO */
+#ifndef TCS_AUDIO_USE_ESCO_EDR
+#define TCS_AUDIO_USE_ESCO_EDR      FALSE
+#endif
+
+/******************************************************************************
+**
+** OBX
+**
+******************************************************************************/
+#ifndef OBX_INCLUDED
+#define OBX_INCLUDED               FALSE
+#endif
+
+#ifndef OBX_CLIENT_INCLUDED
+#define OBX_CLIENT_INCLUDED        TRUE
+#endif
+
+#ifndef OBX_SERVER_INCLUDED
+#define OBX_SERVER_INCLUDED        TRUE
+#endif
+
+/* TRUE to include OBEX authentication/MD5 code */
+#ifndef OBX_MD5_INCLUDED
+#define OBX_MD5_INCLUDED           TRUE
+#endif
+
+/* TRUE to include OBEX authentication/MD5 test code */
+#ifndef OBX_MD5_TEST_INCLUDED
+#define OBX_MD5_TEST_INCLUDED       FALSE
+#endif
+
+/* TRUE to include OBEX 1.4 enhancement (including Obex Over L2CAP) */
+#ifndef OBX_14_INCLUDED
+#define OBX_14_INCLUDED             FALSE
+#endif
+/* MD5 code is required to use OBEX 1.4 features (Reliable session) */
+#if (OBX_MD5_INCLUDED == FALSE)
+#undef OBX_14_INCLUDED
+#define OBX_14_INCLUDED             FALSE
+#endif
+
+/* L2CAP FCR/eRTM mode is required to use OBEX Over L2CAP */
+#if (L2CAP_FCR_INCLUDED == FALSE)
+#undef OBX_14_INCLUDED
+#define OBX_14_INCLUDED             FALSE
+#endif
+
+/* The timeout value (in seconds) for reliable sessions to remain in suspend. 0xFFFFFFFF for no timeout event. */
+#ifndef OBX_SESS_TIMEOUT_VALUE
+#define OBX_SESS_TIMEOUT_VALUE      600
+#endif
+
+/* The idle timeout value. 0 for no timeout event. */
+#ifndef OBX_TIMEOUT_VALUE
+#define OBX_TIMEOUT_VALUE           60
+#endif
+
+/* Timeout value used for disconnect */
+#ifndef OBX_DISC_TOUT_VALUE
+#define OBX_DISC_TOUT_VALUE         5
+#endif
+
+/* The maximum number of registered servers. */
+#ifndef OBX_NUM_SERVERS
+#define OBX_NUM_SERVERS             12
+#endif
+
+/* The maximum number of sessions per registered server. */
+#ifndef OBX_MAX_SR_SESSION
+#define OBX_MAX_SR_SESSION          4
+#endif
+
+/* The maximum number of sessions for all registered servers.
+ * (must be equal or bigger than OBX_NUM_SERVERS) */
+#ifndef OBX_NUM_SR_SESSIONS
+#define OBX_NUM_SR_SESSIONS         26
+#endif
+
+/* The maximum number of sessions per registered server.
+ * must be less than MAX_BD_CONNECTIONS */
+#ifndef OBX_MAX_SR_SESSION
+#define OBX_MAX_SR_SESSION          4
+#endif
+
+/* The maximum number of suspended sessions per registered servers. */
+#ifndef OBX_MAX_SUSPEND_SESSIONS
+#define OBX_MAX_SUSPEND_SESSIONS    4
+#endif
+
+/* The maximum number of active clients. */
+#ifndef OBX_NUM_CLIENTS
+#define OBX_NUM_CLIENTS             8
+#endif
+
+/* The maximum length of OBEX target header.*/
+#ifndef OBX_MAX_TARGET_LEN
+#define OBX_MAX_TARGET_LEN          16
+#endif
+
+/* The maximum length of authentication challenge realm.*/
+#ifndef OBX_MAX_REALM_LEN
+#define OBX_MAX_REALM_LEN           30
+#endif
+
+/* The maximum of GKI buffer queued at OBX before flow control L2CAP */
+#ifndef OBX_MAX_RX_QUEUE_COUNT
+#define OBX_MAX_RX_QUEUE_COUNT      3
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+   Pool ID where to reassemble the SDU.
+   This Pool will allow buffers to be used that are larger than
+   the L2CAP_MAX_MTU. */
+#ifndef OBX_USER_RX_POOL_ID
+#define OBX_USER_RX_POOL_ID     OBX_LRG_DATA_POOL_ID
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+   Pool ID where to hold the SDU.
+   This Pool will allow buffers to be used that are larger than
+   the L2CAP_MAX_MTU. */
+#ifndef OBX_USER_TX_POOL_ID
+#define OBX_USER_TX_POOL_ID     OBX_LRG_DATA_POOL_ID
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
+*/
+#ifndef OBX_FCR_RX_POOL_ID
+#define OBX_FCR_RX_POOL_ID      HCI_ACL_POOL_ID
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+GKI Buffer Pool ID used to hold MPS segments used in (re)transmissions.
+L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
+Note:  This pool needs to have enough buffers to hold two times the window size negotiated
+ in the L2CA_SetFCROptions (2 * tx_win_size)  to allow for retransmissions.
+ The size of each buffer must be able to hold the maximum MPS segment size passed in
+ L2CA_SetFCROptions plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
+*/
+#ifndef OBX_FCR_TX_POOL_ID
+#define OBX_FCR_TX_POOL_ID      HCI_ACL_POOL_ID
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+Size of the transmission window when using enhanced retransmission mode. Not used
+in basic and streaming modes. Range: 1 - 63
+This is used when AMP_INCLUDED == FALSE
+*/
+#ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR
+#define OBX_FCR_OPT_TX_WINDOW_SIZE_BR_EDR       20
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+Size of the transmission window when using enhanced retransmission mode. Not used
+in basic and streaming modes. Range: 1 - 63
+This is used when AMP_INCLUDED == TRUE
+*/
+#ifndef OBX_FCR_OPT_TX_WINDOW_SIZE_AMP
+#define OBX_FCR_OPT_TX_WINDOW_SIZE_AMP          45
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+Number of transmission attempts for a single I-Frame before taking
+Down the connection. Used In ERTM mode only. Value is Ignored in basic and
+Streaming modes.
+Range: 0, 1-0xFF
+0 - infinite retransmissions
+1 - single transmission
+*/
+#ifndef OBX_FCR_OPT_MAX_TX_B4_DISCNT
+#define OBX_FCR_OPT_MAX_TX_B4_DISCNT    20
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+Retransmission Timeout
+Range: Minimum 2000 (2 secs) on BR/EDR when supporting PBF.
+ */
+#ifndef OBX_FCR_OPT_RETX_TOUT
+#define OBX_FCR_OPT_RETX_TOUT           2000
+#endif
+
+/* This option is application when OBX_14_INCLUDED=TRUE
+Monitor Timeout
+Range: Minimum 12000 (12 secs) on BR/EDR when supporting PBF.
+*/
+#ifndef OBX_FCR_OPT_MONITOR_TOUT
+#define OBX_FCR_OPT_MONITOR_TOUT        12000
+#endif
+
+/******************************************************************************
+**
+** BNEP
+**
+******************************************************************************/
+
+#ifndef BNEP_INCLUDED
+#define BNEP_INCLUDED               FALSE
+#endif
+
+/* Protocol filtering is an optional feature. Bydefault it will be turned on */
+#ifndef BNEP_SUPPORTS_PROT_FILTERS
+#define BNEP_SUPPORTS_PROT_FILTERS          TRUE
+#endif
+
+/* Multicast filtering is an optional feature. Bydefault it will be turned on */
+#ifndef BNEP_SUPPORTS_MULTI_FILTERS
+#define BNEP_SUPPORTS_MULTI_FILTERS         TRUE
+#endif
+
+/* BNEP status API call is used mainly to get the L2CAP handle */
+#ifndef BNEP_SUPPORTS_STATUS_API
+#define BNEP_SUPPORTS_STATUS_API            TRUE
+#endif
+
+/* This is just a debug function */
+#ifndef BNEP_SUPPORTS_DEBUG_DUMP
+#define BNEP_SUPPORTS_DEBUG_DUMP            TRUE
+#endif
+
+#ifndef BNEP_SUPPORTS_ALL_UUID_LENGTHS
+#define BNEP_SUPPORTS_ALL_UUID_LENGTHS      TRUE    /* Otherwise it will support only 16bit UUIDs */
+#endif
+
+/*
+** When BNEP connection changes roles after the connection is established
+** we will do an authentication check again on the new role
+*/
+#ifndef BNEP_DO_AUTH_FOR_ROLE_SWITCH
+#define BNEP_DO_AUTH_FOR_ROLE_SWITCH        TRUE
+#endif
+
+
+/* Maximum number of protocol filters supported. */
+#ifndef BNEP_MAX_PROT_FILTERS
+#define BNEP_MAX_PROT_FILTERS       5
+#endif
+
+/* Maximum number of multicast filters supported. */
+#ifndef BNEP_MAX_MULTI_FILTERS
+#define BNEP_MAX_MULTI_FILTERS      5
+#endif
+
+/* Minimum MTU size. */
+#ifndef BNEP_MIN_MTU_SIZE
+#define BNEP_MIN_MTU_SIZE           L2CAP_MTU_SIZE
+#endif
+
+/* Preferred MTU size. */
+#ifndef BNEP_MTU_SIZE
+#define BNEP_MTU_SIZE               BNEP_MIN_MTU_SIZE
+#endif
+
+/* Maximum size of user data, in bytes.  */
+#ifndef BNEP_MAX_USER_DATA_SIZE
+#define BNEP_MAX_USER_DATA_SIZE     1500
+#endif
+
+/* Maximum number of buffers allowed in transmit data queue. */
+#ifndef BNEP_MAX_XMITQ_DEPTH
+#define BNEP_MAX_XMITQ_DEPTH        20
+#endif
+
+/* Maximum number BNEP of connections supported. */
+#ifndef BNEP_MAX_CONNECTIONS
+#define BNEP_MAX_CONNECTIONS        7
+#endif
+
+
+/******************************************************************************
+**
+** AVDTP
+**
+******************************************************************************/
+
+#ifndef AVDT_INCLUDED
+#define AVDT_INCLUDED               FALSE
+#endif
+
+/* Include reporting capability in AVDTP */
+#ifndef AVDT_REPORTING
+#define AVDT_REPORTING              TRUE
+#endif
+
+/* Include multiplexing capability in AVDTP */
+#ifndef AVDT_MULTIPLEXING
+#define AVDT_MULTIPLEXING           TRUE
+#endif
+
+/* Number of simultaneous links to different peer devices. */
+#ifndef AVDT_NUM_LINKS
+#define AVDT_NUM_LINKS              2
+#endif
+
+/* Number of simultaneous stream endpoints. */
+#ifndef AVDT_NUM_SEPS
+#define AVDT_NUM_SEPS               3
+#endif
+
+/* Number of transport channels setup per media stream(audio or video) */
+#ifndef AVDT_NUM_CHANNELS
+
+#if AVDT_REPORTING == TRUE
+/* signaling, media and reporting channels */
+#define AVDT_NUM_CHANNELS   3
+#else
+/* signaling and media channels */
+#define AVDT_NUM_CHANNELS   2
+#endif
+
+#endif
+
+/* Number of transport channels setup by AVDT for all media streams
+ * AVDT_NUM_CHANNELS * Number of simultaneous streams.
+ */
+#ifndef AVDT_NUM_TC_TBL
+#define AVDT_NUM_TC_TBL             6
+#endif
+
+
+/* Maximum size in bytes of the codec capabilities information element. */
+#ifndef AVDT_CODEC_SIZE
+#define AVDT_CODEC_SIZE             10
+#endif
+
+/* Maximum size in bytes of the content protection information element. */
+#ifndef AVDT_PROTECT_SIZE
+#define AVDT_PROTECT_SIZE           90
+#endif
+
+/* Maximum number of GKI buffers in the fragment queue (for video frames).
+ * Must be less than the number of buffers in the buffer pool of size AVDT_DATA_POOL_SIZE */
+#ifndef AVDT_MAX_FRAG_COUNT
+#define AVDT_MAX_FRAG_COUNT         15
+#endif
+
+/******************************************************************************
+**
+** PAN
+**
+******************************************************************************/
+
+#ifndef PAN_INCLUDED
+#define PAN_INCLUDED                     FALSE
+#endif
+
+/* This will enable the PANU role */
+#ifndef PAN_SUPPORTS_ROLE_PANU
+#define PAN_SUPPORTS_ROLE_PANU              TRUE
+#endif
+
+/* This will enable the GN role */
+#ifndef PAN_SUPPORTS_ROLE_GN
+#define PAN_SUPPORTS_ROLE_GN                TRUE
+#endif
+
+/* This will enable the NAP role */
+#ifndef PAN_SUPPORTS_ROLE_NAP
+#define PAN_SUPPORTS_ROLE_NAP               TRUE
+#endif
+
+/* This is just for debugging purposes */
+#ifndef PAN_SUPPORTS_DEBUG_DUMP
+#define PAN_SUPPORTS_DEBUG_DUMP             TRUE
+#endif
+
+
+/* Maximum number of PAN connections allowed */
+#ifndef MAX_PAN_CONNS
+#define MAX_PAN_CONNS                    7
+#endif
+
+/* Default service name for NAP role */
+#ifndef PAN_NAP_DEFAULT_SERVICE_NAME
+#define PAN_NAP_DEFAULT_SERVICE_NAME    "Network Access Point Service"
+#endif
+
+/* Default service name for GN role */
+#ifndef PAN_GN_DEFAULT_SERVICE_NAME
+#define PAN_GN_DEFAULT_SERVICE_NAME     "Group Network Service"
+#endif
+
+/* Default service name for PANU role */
+#ifndef PAN_PANU_DEFAULT_SERVICE_NAME
+#define PAN_PANU_DEFAULT_SERVICE_NAME   "PAN User Service"
+#endif
+
+/* Default description for NAP role service */
+#ifndef PAN_NAP_DEFAULT_DESCRIPTION
+#define PAN_NAP_DEFAULT_DESCRIPTION     "Public NAP"
+#endif
+
+/* Default description for GN role service */
+#ifndef PAN_GN_DEFAULT_DESCRIPTION
+#define PAN_GN_DEFAULT_DESCRIPTION      "Widcomm GN"
+#endif
+
+/* Default description for PANU role service */
+#ifndef PAN_PANU_DEFAULT_DESCRIPTION
+#define PAN_PANU_DEFAULT_DESCRIPTION    "Laptop's PANU"
+#endif
+
+/* Default Security level for PANU role. */
+#ifndef PAN_PANU_SECURITY_LEVEL
+#define PAN_PANU_SECURITY_LEVEL          0
+#endif
+
+/* Default Security level for GN role. */
+#ifndef PAN_GN_SECURITY_LEVEL
+#define PAN_GN_SECURITY_LEVEL            0
+#endif
+
+/* Default Security level for NAP role. */
+#ifndef PAN_NAP_SECURITY_LEVEL
+#define PAN_NAP_SECURITY_LEVEL           0
+#endif
+
+
+
+
+/******************************************************************************
+**
+** GAP
+**
+******************************************************************************/
+
+#ifndef GAP_INCLUDED
+#define GAP_INCLUDED                FALSE
+#endif
+
+/* This is set to enable use of GAP L2CAP connections. */
+#ifndef GAP_CONN_INCLUDED
+#define GAP_CONN_INCLUDED           TRUE
+#endif
+
+/* This is set to enable posting event for data write */
+#ifndef GAP_CONN_POST_EVT_INCLUDED
+#define GAP_CONN_POST_EVT_INCLUDED  FALSE
+#endif
+
+/* The maximum number of simultaneous GAP L2CAP connections. */
+#ifndef GAP_MAX_CONNECTIONS
+#define GAP_MAX_CONNECTIONS         8
+#endif
+
+/******************************************************************************
+**
+** CTP
+**
+******************************************************************************/
+
+#ifndef CTP_INCLUDED
+#define CTP_INCLUDED                FALSE
+#endif
+
+/* To include CTP gateway functionality or not. */
+#ifndef CTP_GW_INCLUDED
+#define CTP_GW_INCLUDED             TRUE
+#endif
+
+/* The number of terminals supported. */
+#ifndef CTP_MAX_NUM_TLS
+#define CTP_MAX_NUM_TLS             7
+#endif
+
+/* If the controller can not support sniff mode when the SCO is up, set this to FALSE. */
+#ifndef CTP_USE_SNIFF_ON_SCO
+#define CTP_USE_SNIFF_ON_SCO        FALSE
+#endif
+
+/* When ACL link between TL and GW is idle for more than this amount of seconds, the ACL may be put to low power mode. */
+#ifndef CTP_TL_IDLE_TIMEOUT
+#define CTP_TL_IDLE_TIMEOUT         90
+#endif
+
+/* To include CTP terminal functionality or not. */
+#ifndef CTP_TL_INCLUDED
+#define CTP_TL_INCLUDED             TRUE
+#endif
+
+/* To include CTP device discovery functionality or not. */
+#ifndef CTP_DISCOVERY_INCLUDED
+#define CTP_DISCOVERY_INCLUDED      TRUE
+#endif
+
+/* set to TRUE for controllers that do not support multi-point */
+#ifndef CTP_TL_WAIT_DISC
+#define CTP_TL_WAIT_DISC            TRUE
+#endif
+
+/* The CTP inquiry database size. */
+#ifndef CTP_INQ_DB_SIZE
+#define CTP_INQ_DB_SIZE             CTP_DISC_REC_SIZE
+#endif
+
+/* The CTP discovery record size. */
+#ifndef CTP_DISC_REC_SIZE
+#define CTP_DISC_REC_SIZE           60
+#endif
+
+/* CTP TL would try to re-establish L2CAP channel after channel is disconnected for this amount of seconds. */
+#ifndef CTP_GUARD_LINK_LOST
+#define CTP_GUARD_LINK_LOST         1
+#endif
+
+/* The link policy bitmap. */
+#ifndef CTP_DEFAULT_LINK_POLICY
+#define CTP_DEFAULT_LINK_POLICY     0x000F
+#endif
+
+/* The minimum period interval used for the sniff and park modes. */
+#ifndef CTP_DEF_LOWPWR_MIN_PERIOD
+#define CTP_DEF_LOWPWR_MIN_PERIOD   0x100
+#endif
+
+/* The maximum period interval used for the sniff and park modes. */
+#ifndef CTP_DEF_LOWPWR_MAX_PERIOD
+#define CTP_DEF_LOWPWR_MAX_PERIOD   0x1E0
+#endif
+
+/* The number of baseband receive slot sniff attempts. */
+#ifndef CTP_DEF_LOWPWR_ATTEMPT
+#define CTP_DEF_LOWPWR_ATTEMPT      0x200
+#endif
+
+/* The number of baseband receive slots for sniff timeout. */
+#ifndef CTP_DEF_LOWPWR_TIMEOUT
+#define CTP_DEF_LOWPWR_TIMEOUT      0x200
+#endif
+
+/* This is set if CTP is to use park mode. */
+#ifndef CTP_PARK_INCLUDED
+#define CTP_PARK_INCLUDED           TRUE
+#endif
+
+/* This is set if CTP is to use sniff mode. */
+#ifndef CTP_SNIFF_INCLUDED
+#define CTP_SNIFF_INCLUDED          TRUE
+#endif
+
+/* To include CTP data exchange functionality or not. */
+#ifndef CTP_DATA_EXCHG_FEATURE
+#define CTP_DATA_EXCHG_FEATURE      FALSE
+#endif
+
+/* To include CTP GW intercom functionality or not. */
+#ifndef CTP_GW_INTERCOM_FEATURE
+#define CTP_GW_INTERCOM_FEATURE     FALSE
+#endif
+
+/* The MTU size for L2CAP channel. */
+#ifndef CTP_MTU_SIZE
+#define CTP_MTU_SIZE                200
+#endif
+
+/* The L2CAP PSM for the data exchange feature. */
+#ifndef CTP_DATA_EXCHG_PSM
+#define CTP_DATA_EXCHG_PSM          13
+#endif
+
+/* The flush timeout for L2CAP channels. */
+#ifndef CTP_FLUSH_TO
+#define CTP_FLUSH_TO                0xFFFF
+#endif
+
+/* The default service name for CTP. */
+#ifndef CTP_DEFAULT_SERVICE_NAME
+#define CTP_DEFAULT_SERVICE_NAME    "Cordless Telephony"
+#endif
+
+/* The CTP security level. */
+#ifndef CTP_SECURITY_LEVEL
+#define CTP_SECURITY_LEVEL          (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)
+#endif
+
+/* The number of lines to the external network. */
+#ifndef CTP_MAX_LINES
+#define CTP_MAX_LINES               1
+#endif
+
+/* Test if the number of resources in TCS is consistent with CTP setting. */
+#ifndef CTP_TEST_FULL_TCS
+#define CTP_TEST_FULL_TCS           TRUE
+#endif
+
+/* The default inquiry mode. */
+#ifndef CTP_DEFAULT_INQUIRY_MODE
+#define CTP_DEFAULT_INQUIRY_MODE    BTM_GENERAL_INQUIRY
+#endif
+
+/* The default inquiry duration. */
+#ifndef CTP_DEFAULT_INQ_DURATION
+#define CTP_DEFAULT_INQ_DURATION    4
+#endif
+
+/* The maximum number of inquiry responses. */
+#ifndef CTP_DEFAULT_INQ_MAX_RESP
+#define CTP_DEFAULT_INQ_MAX_RESP    3
+#endif
+
+/* When TL does not create another L2CAP channel within this period of time GW declares that it's "Connected Limited". */
+#ifndef CTP_TL_CONN_TIMEOUT
+#define CTP_TL_CONN_TIMEOUT         5
+#endif
+
+/* The delay for ACL to completely disconnect (for intercom) before sending the connect request to GW. */
+#ifndef CTP_RECONNECT_DELAY
+#define CTP_RECONNECT_DELAY         5
+#endif
+
+/* How many times to retry connection when it has failed. */
+#ifndef CTP_RETRY_ON_CONN_ERR
+#define CTP_RETRY_ON_CONN_ERR       5
+#endif
+
+/******************************************************************************
+**
+** ICP
+**
+******************************************************************************/
+
+#ifndef ICP_INCLUDED
+#define ICP_INCLUDED                FALSE
+#endif
+
+/* The ICP default MTU. */
+#ifndef ICP_MTU_SIZE
+#define ICP_MTU_SIZE                100
+#endif
+
+/* The ICP security level. */
+#ifndef ICP_SECURITY_LEVEL
+#define ICP_SECURITY_LEVEL          BTM_SEC_NONE
+#endif
+
+/* The default service name for ICP. */
+#ifndef ICP_DEFAULT_SERVICE_NAME
+#define ICP_DEFAULT_SERVICE_NAME    "Intercom"
+#endif
+
+/* The flush timeout for L2CAP channels. */
+#ifndef ICP_FLUSH_TO
+#define ICP_FLUSH_TO                0xFFFF
+#endif
+
+/******************************************************************************
+**
+** SPP
+**
+******************************************************************************/
+
+#ifndef SPP_INCLUDED
+#define SPP_INCLUDED                FALSE
+#endif
+
+/* The SPP default MTU. */
+#ifndef SPP_DEFAULT_MTU
+#define SPP_DEFAULT_MTU             127
+#endif
+
+/* The interval, in seconds, that a client tries to reconnect to a service. */
+#ifndef SPP_RETRY_CONN_INTERVAL
+#define SPP_RETRY_CONN_INTERVAL     1
+#endif
+
+/* The SPP discoverable mode: limited or general. */
+#ifndef SPP_DISCOVERABLE_MODE
+#define SPP_DISCOVERABLE_MODE       BTM_GENERAL_DISCOVERABLE
+#endif
+
+/* The maximum number of inquiry results returned in by inquiry procedure. */
+#ifndef SPP_DEF_INQ_MAX_RESP
+#define SPP_DEF_INQ_MAX_RESP        10
+#endif
+
+/* The SPP discovery record size. */
+#ifndef SPP_DISC_REC_SIZE
+#define SPP_DISC_REC_SIZE           60
+#endif
+
+#ifndef SPP_MAX_RECS_PER_DEVICE
+#define SPP_MAX_RECS_PER_DEVICE     (SPP_DB_SIZE / SPP_DISC_REC_SIZE)
+#endif
+
+/* Inquiry duration in 1.28 second units. */
+#ifndef SPP_DEF_INQ_DURATION
+#define SPP_DEF_INQ_DURATION        9
+#endif
+
+/* keep the raw data received from SDP server in database. */
+#ifndef SDP_RAW_DATA_INCLUDED
+#define SDP_RAW_DATA_INCLUDED       FALSE
+#endif
+
+/* TRUE, to allow JV to create L2CAP connection on SDP PSM. */
+#ifndef SDP_FOR_JV_INCLUDED
+#define SDP_FOR_JV_INCLUDED         FALSE
+#endif
+
+/* Inquiry duration in 1.28 second units. */
+#ifndef SDP_DEBUG
+#define SDP_DEBUG                   TRUE
+#endif
+
+/******************************************************************************
+**
+** HSP2, HFP
+**
+******************************************************************************/
+
+#ifndef HSP2_INCLUDED
+#define HSP2_INCLUDED               FALSE
+#endif
+
+/* Include the ability to perform inquiry for peer devices. */
+#ifndef HSP2_INQUIRY_INCLUDED
+#define HSP2_INQUIRY_INCLUDED       TRUE
+#endif
+
+/* Include Audio Gateway specific code. */
+#ifndef HSP2_AG_INCLUDED
+#define HSP2_AG_INCLUDED            TRUE
+#endif
+
+/* Include Headset Specific Code. */
+#ifndef HSP2_HS_INCLUDED
+#define HSP2_HS_INCLUDED            TRUE
+#endif
+
+/* Include the ability to open an SCO connection for In-Band Ringing. */
+#ifndef HSP2_IB_RING_INCLUDED
+#define HSP2_IB_RING_INCLUDED       TRUE
+#endif
+
+/* Include the ability to repeat a ring. */
+#ifndef HSP2_AG_REPEAT_RING
+#define HSP2_AG_REPEAT_RING         TRUE
+#endif
+
+#ifndef HSP2_APP_CLOSES_ON_CKPD
+#define HSP2_APP_CLOSES_ON_CKPD     FALSE
+#endif
+
+
+/* Include the ability to park a connection. */
+#ifndef HSP2_PARK_INCLUDED
+#define HSP2_PARK_INCLUDED          TRUE
+#endif
+
+/* Include HSP State Machine debug trace messages. */
+#ifndef HSP2_FSM_DEBUG
+#define HSP2_FSM_DEBUG              TRUE
+#endif
+
+/* The Module's Inquiry Scan Window. */
+#ifndef HSP2_INQ_SCAN_WINDOW
+#define HSP2_INQ_SCAN_WINDOW        0
+#endif
+
+/* The Module's Inquiry Scan Interval. */
+#ifndef HSP2_INQ_SCAN_INTERVAL
+#define HSP2_INQ_SCAN_INTERVAL      0
+#endif
+
+/* The Module's Page Scan Interval. */
+#ifndef HSP2_PAGE_SCAN_INTERVAL
+#define HSP2_PAGE_SCAN_INTERVAL     0
+#endif
+
+/* The Module's Page Scan Window. */
+#ifndef HSP2_PAGE_SCAN_WINDOW
+#define HSP2_PAGE_SCAN_WINDOW       0
+#endif
+
+/* The Park Mode's Minimum Beacon Period. */
+#ifndef HSP2_BEACON_MIN_PERIOD
+#define HSP2_BEACON_MIN_PERIOD      450
+#endif
+
+/* The Park Mode's Maximum Beacon Period. */
+#ifndef HSP2_BEACON_MAX_PERIOD
+#define HSP2_BEACON_MAX_PERIOD      500
+#endif
+
+/* The duration of the inquiry in seconds. */
+#ifndef HSP2_INQ_DURATION
+#define HSP2_INQ_DURATION           4
+#endif
+
+/* Maximum number of peer responses during an inquiry. */
+#ifndef HSP2_INQ_MAX_NUM_RESPS
+#define HSP2_INQ_MAX_NUM_RESPS      3
+#endif
+
+/* Maximum number of times to retry an inquiry prior to failure. */
+#ifndef HSP2_MAX_INQ_RETRY
+#define HSP2_MAX_INQ_RETRY          6
+#endif
+
+/* Maximum number of times to retry an RFCOMM connection prior to failure. */
+#ifndef HSP2_MAX_CONN_RETRY
+#define HSP2_MAX_CONN_RETRY         3
+#endif
+
+/* If the connect request failed for authentication reasons, do not retry */
+#ifndef HSP2_NO_RETRY_ON_AUTH_FAIL
+#define HSP2_NO_RETRY_ON_AUTH_FAIL  TRUE
+#endif
+
+/* Maximum number of characters in an HSP2 device name. */
+#ifndef HSP2_MAX_NAME_LEN
+#define HSP2_MAX_NAME_LEN           32
+#endif
+
+/* The minimum speaker and/or microphone gain setting. */
+#ifndef HSP2_MIN_GAIN
+#define HSP2_MIN_GAIN               0
+#endif
+
+/* The maximum speaker and/or microphone setting. */
+#ifndef HSP2_MAX_GAIN
+#define HSP2_MAX_GAIN               15
+#endif
+
+/* The default value to send on an AT+CKPD. */
+#ifndef HSP2_KEYPRESS_DEFAULT
+#define HSP2_KEYPRESS_DEFAULT       200
+#endif
+
+/* Maximum amount a data that can be received per RFCOMM frame. */
+#ifndef HSP2_MAX_RFC_READ_LEN
+#define HSP2_MAX_RFC_READ_LEN       128
+#endif
+
+/* The time in seconds to wait for completion of a partial AT command or response from the peer. */
+#ifndef HSP2_AT_TO_INTERVAL
+#define HSP2_AT_TO_INTERVAL         30
+#endif
+
+/* The time to wait before repeating a ring to a peer Headset. */
+#ifndef HSP2_REPEAT_RING_TO
+#define HSP2_REPEAT_RING_TO         4
+#endif
+
+/* Time to wait for a response for an AT command */
+#ifndef HSP2_AT_RSP_TO
+#define HSP2_AT_RSP_TO              20
+#endif
+
+/* SCO packet type(s) to use (bitmask: see spec), 0 - device default (recommended) */
+#ifndef HSP2_SCO_PKT_TYPES
+#define HSP2_SCO_PKT_TYPES          ((UINT16)0x0000)
+#endif
+
+/* The default settings of the SCO voice link. */
+#ifndef HSP2_DEFAULT_VOICE_SETTINGS
+#define HSP2_DEFAULT_VOICE_SETTINGS (HCI_INP_CODING_LINEAR | HCI_INP_DATA_FMT_2S_COMPLEMENT | HCI_INP_SAMPLE_SIZE_16BIT | HCI_AIR_CODING_FORMAT_CVSD)
+#endif
+
+#ifndef HSP2_MAX_AT_CMD_LENGTH
+#define HSP2_MAX_AT_CMD_LENGTH       16
+#endif
+
+#ifndef HSP2_MAX_AT_VAL_LENGTH
+#if (defined(HFP_INCLUDED) && HFP_INCLUDED == TRUE)
+#define HSP2_MAX_AT_VAL_LENGTH       310
+#else
+#define HSP2_MAX_AT_VAL_LENGTH       5
+#endif
+#endif
+
+
+#ifndef HSP2_SDP_DB_SIZE
+#define HSP2_SDP_DB_SIZE             300
+#endif
+
+
+/******************************************************************************
+**
+** HFP
+**
+******************************************************************************/
+
+#ifndef HFP_INCLUDED
+#define HFP_INCLUDED                FALSE
+#endif
+
+/* Include Audio Gateway specific code. */
+#ifndef HFP_AG_INCLUDED
+#define HFP_AG_INCLUDED             TRUE
+#endif
+
+/* Include Hand Free Specific Code. */
+#ifndef HFP_HF_INCLUDED
+#define HFP_HF_INCLUDED             TRUE
+#endif
+
+/* Use AT interface instead of full blown API */
+#ifndef AT_INTERFACE
+#define AT_INTERFACE            FALSE
+#endif
+
+/* HFP Manages SCO establishement for various procedures */
+#ifndef HFP_SCO_MGMT_INCLUDED
+#define HFP_SCO_MGMT_INCLUDED             TRUE
+#endif
+
+/* CCAP compliant features and behavior desired */
+#ifndef CCAP_COMPLIANCE
+#define CCAP_COMPLIANCE             TRUE
+#endif
+
+/* Caller ID string, part of +CLIP result code */
+#ifndef HFP_MAX_CLIP_INFO
+#define HFP_MAX_CLIP_INFO             45
+#endif
+
+#ifndef HFP_RPT_PEER_INFO_INCLUDED
+#define HFP_RPT_PEER_INFO_INCLUDED  TRUE  /* Reporting of peer features enabled */
+#endif
+
+/******************************************************************************
+**
+** HID
+**
+******************************************************************************/
+
+/* HID Device Role Included */
+#ifndef HID_DEV_INCLUDED
+#define HID_DEV_INCLUDED             FALSE
+#endif
+
+#ifndef HID_DEV_PM_INCLUDED
+#define HID_DEV_PM_INCLUDED         TRUE
+#endif
+
+/* The HID Device is a virtual cable */
+#ifndef HID_DEV_VIRTUAL_CABLE
+#define HID_DEV_VIRTUAL_CABLE       TRUE
+#endif
+
+/* The HID device initiates the reconnections */
+#ifndef HID_DEV_RECONN_INITIATE
+#define HID_DEV_RECONN_INITIATE     TRUE
+#endif
+
+/* THe HID device is normally connectable */
+#ifndef HID_DEV_NORMALLY_CONN
+#define HID_DEV_NORMALLY_CONN       FALSE
+#endif
+
+/* The device is battery powered */
+#ifndef HID_DEV_BATTERY_POW
+#define HID_DEV_BATTERY_POW         TRUE
+#endif
+
+/* Device is capable of waking up the host */
+#ifndef HID_DEV_REMOTE_WAKE
+#define HID_DEV_REMOTE_WAKE         TRUE
+#endif
+
+/* Device needs host to close SDP channel after SDP is over */
+#ifndef HID_DEV_SDP_DISABLE
+#define HID_DEV_SDP_DISABLE         TRUE
+#endif
+
+#ifndef HID_DEV_MTU_SIZE
+#define HID_DEV_MTU_SIZE                 64
+#endif
+
+#ifndef HID_DEV_FLUSH_TO
+#define HID_DEV_FLUSH_TO                 0xffff
+#endif
+
+#ifndef HID_DEV_PAGE_SCAN_WIN
+#define HID_DEV_PAGE_SCAN_WIN       (0)
+#endif
+
+#ifndef HID_DEV_PAGE_SCAN_INT
+#define HID_DEV_PAGE_SCAN_INT       (0)
+#endif
+
+#ifndef HID_DEV_MAX_CONN_RETRY
+#define HID_DEV_MAX_CONN_RETRY      (15)
+#endif
+
+#ifndef HID_DEV_REPAGE_WIN
+#define HID_DEV_REPAGE_WIN          (1)
+#endif
+
+#ifndef HID_DEV_SVC_NAME
+#define HID_DEV_SVC_NAME            "HID"
+#endif
+
+#ifndef HID_DEV_SVC_DESCR
+#define HID_DEV_SVC_DESCR           "3-button mouse and keyboard"
+#endif
+
+#ifndef HID_DEV_PROVIDER_NAME
+#define HID_DEV_PROVIDER_NAME       "Widcomm"
+#endif
+
+#ifndef HID_DEV_REL_NUM
+#define HID_DEV_REL_NUM             0x0100
+#endif
+
+#ifndef HID_DEV_PARSER_VER
+#define HID_DEV_PARSER_VER          0x0111
+#endif
+
+#ifndef HID_DEV_SUBCLASS
+#define HID_DEV_SUBCLASS            COD_MINOR_POINTING
+#endif
+
+#ifndef HID_DEV_COUNTRY_CODE
+#define HID_DEV_COUNTRY_CODE        0x33
+#endif
+
+#ifndef HID_DEV_SUP_TOUT
+#define HID_DEV_SUP_TOUT            0x8000
+#endif
+
+#ifndef HID_DEV_NUM_LANGS
+#define HID_DEV_NUM_LANGS           1
+#endif
+
+#ifndef HID_DEV_INACT_TIMEOUT
+#define HID_DEV_INACT_TIMEOUT       60
+#endif
+
+#ifndef HID_DEV_BUSY_MODE_PARAMS
+#define HID_DEV_BUSY_MODE_PARAMS    { 320, 160, 10, 20, HCI_MODE_ACTIVE }
+#endif
+
+#ifndef HID_DEV_IDLE_MODE_PARAMS
+#define HID_DEV_IDLE_MODE_PARAMS    { 320, 160, 10, 20, HCI_MODE_SNIFF }
+#endif
+
+#ifndef HID_DEV_SUSP_MODE_PARAMS
+#define HID_DEV_SUSP_MODE_PARAMS    { 640, 320,  0,    0, HCI_MODE_PARK }
+#endif
+
+#ifndef HID_DEV_MAX_DESCRIPTOR_SIZE
+#define HID_DEV_MAX_DESCRIPTOR_SIZE      128     /* Max descriptor size          */
+#endif
+
+#ifndef HID_DEV_LANGUAGELIST
+#define HID_DEV_LANGUAGELIST             {0x35, 0x06, 0x09, 0x04, 0x09, 0x09, 0x01, 0x00}
+#endif
+
+#ifndef HID_DEV_LINK_SUPERVISION_TO
+#define HID_DEV_LINK_SUPERVISION_TO      0x8000
+#endif
+
+#ifndef HID_CONTROL_POOL_ID
+#define HID_CONTROL_POOL_ID             2
+#endif
+
+#ifndef HID_INTERRUPT_POOL_ID
+#define HID_INTERRUPT_POOL_ID           2
+#endif
+
+#ifndef UCD_HID_INCLUDED
+#define UCD_HID_INCLUDED    FALSE
+#endif
+
+#ifndef BRR_HID_INCLUDED
+#define BRR_HID_INCLUDED    FALSE
+#endif
+
+/*************************************************************************
+** Definitions for Both HID-Host & Device
+*/
+#ifndef HID_MAX_SVC_NAME_LEN
+#define HID_MAX_SVC_NAME_LEN  32
+#endif
+
+#ifndef HID_MAX_SVC_DESCR_LEN
+#define HID_MAX_SVC_DESCR_LEN 32
+#endif
+
+#ifndef HID_MAX_PROV_NAME_LEN
+#define HID_MAX_PROV_NAME_LEN 32
+#endif
+
+/*************************************************************************
+** Definitions for HID-Host
+*/
+#ifndef  HID_HOST_INCLUDED
+#define HID_HOST_INCLUDED           FALSE
+#endif
+
+#ifndef HID_HOST_MAX_DEVICES
+#define HID_HOST_MAX_DEVICES        7
+#endif
+
+#ifndef HID_HOST_MTU
+#define HID_HOST_MTU                640
+#endif
+
+#ifndef HID_HOST_FLUSH_TO
+#define HID_HOST_FLUSH_TO                 0xffff
+#endif
+
+#ifndef HID_HOST_MAX_CONN_RETRY
+#define HID_HOST_MAX_CONN_RETRY     (15)
+#endif
+
+#ifndef HID_HOST_REPAGE_WIN
+#define HID_HOST_REPAGE_WIN          (2)
+#endif
+
+
+/******************************************************************************
+**
+** DUN and FAX
+**
+******************************************************************************/
+
+#ifndef DUN_INCLUDED
+#define DUN_INCLUDED                FALSE
+#endif
+
+
+/******************************************************************************
+**
+** GOEP
+**
+******************************************************************************/
+
+#ifndef GOEP_INCLUDED
+#define GOEP_INCLUDED               FALSE
+#endif
+
+/* This is set to enable GOEP non-blocking file system access functions. */
+#ifndef GOEP_FS_INCLUDED
+#define GOEP_FS_INCLUDED        TRUE
+#endif
+
+/* GOEP authentication key size. */
+#ifndef GOEP_MAX_AUTH_KEY_SIZE
+#define GOEP_MAX_AUTH_KEY_SIZE      16
+#endif
+
+/* Maximum size of the realm authentication string. */
+#ifndef GOEP_MAX_AUTH_REALM_SIZE
+#define GOEP_MAX_AUTH_REALM_SIZE    16
+#endif
+
+/* Realm Character Set */
+#ifndef GOEP_REALM_CHARSET
+#define GOEP_REALM_CHARSET          0       /* ASCII */
+#endif
+
+/* This is set to the maximum length of path name allowed in the system (_MAX_PATH). */
+#ifndef GOEP_MAX_PATH_SIZE
+#define GOEP_MAX_PATH_SIZE          255
+#endif
+
+/* Specifies whether or not client's user id is required during obex authentication */
+#ifndef GOEP_SERVER_USERID_REQUIRED
+#define GOEP_SERVER_USERID_REQUIRED FALSE
+#endif
+
+/* This is set to the maximum length of file name allowed in the system (_MAX_FNAME). */
+#ifndef GOEP_MAX_FILE_SIZE
+#define GOEP_MAX_FILE_SIZE          128
+#endif
+
+/* Character used as path separator */
+#ifndef GOEP_PATH_SEPARATOR
+#define GOEP_PATH_SEPARATOR         ((char) 0x5c)   /* 0x2f ('/'), or 0x5c ('\') */
+#endif
+
+/******************************************************************************
+**
+** OPP
+**
+******************************************************************************/
+
+#ifndef OPP_INCLUDED
+#define OPP_INCLUDED                FALSE
+#endif
+
+/* This is set to enable OPP client capabilities. */
+#ifndef OPP_CLIENT_INCLUDED
+#define OPP_CLIENT_INCLUDED         FALSE
+#endif
+
+/* This is set to enable OPP server capabilities. */
+#ifndef OPP_SERVER_INCLUDED
+#define OPP_SERVER_INCLUDED         FALSE
+#endif
+
+/* if the optional formating functions are to be included or not */
+#ifndef OPP_FORMAT_INCLUDED
+#define OPP_FORMAT_INCLUDED         FALSE
+#endif
+
+/* Maximum number of client sessions allowed by server */
+#ifndef OPP_MAX_SRVR_SESS
+#define OPP_MAX_SRVR_SESS           3
+#endif
+
+/******************************************************************************
+**
+** FTP
+**
+******************************************************************************/
+
+#ifndef FTP_INCLUDED
+#define FTP_INCLUDED                FALSE
+#endif
+
+/* This is set to enable FTP client capabilities. */
+#ifndef FTP_CLIENT_INCLUDED
+#define FTP_CLIENT_INCLUDED         TRUE
+#endif
+
+/* This is set to enable FTP server capabilities. */
+#ifndef FTP_SERVER_INCLUDED
+#define FTP_SERVER_INCLUDED         TRUE
+#endif
+
+/******************************************************************************
+**
+** XML Parser
+**
+******************************************************************************/
+
+#ifndef XML_STACK_SIZE
+#define XML_STACK_SIZE             7
+#endif
+
+/******************************************************************************
+**
+** BPP Printer
+**
+******************************************************************************/
+#ifndef BPP_DEBUG
+#define BPP_DEBUG            FALSE
+#endif
+
+#ifndef BPP_INCLUDED
+#define BPP_INCLUDED                FALSE
+#endif
+
+#ifndef BPP_SND_INCLUDED
+#define BPP_SND_INCLUDED            FALSE
+#endif
+
+/* Maximum number of senders allowed to connect simultaneously
+** The maximum is 6 or (OBX_NUM_SERVERS / 2), whichever is smaller
+*/
+#ifndef BPP_PR_MAX_CON
+#define BPP_PR_MAX_CON         3
+#endif
+
+/* Service Name. maximum length: 248
+#ifndef BPP_SERVICE_NAME
+#define BPP_SERVICE_NAME            "Basic Printing"
+#endif
+ */
+/* Document Format Supported. ASCII comma-delimited list of MIME type:version string
+#ifndef BPP_DOC_FORMAT_SUPPORTED
+#define BPP_DOC_FORMAT_SUPPORTED    "application/vnd.pwg-xhtml-print:1.0,application/vnd.hp-PCL:5E,application/PDF"
+#endif
+
+#ifndef BPP_DOC_FORMAT_SUPPORTED_LEN
+#define BPP_DOC_FORMAT_SUPPORTED_LEN    77
+#endif
+ */
+/* Character repertoires.
+#ifndef BPP_CHARACTER_REPERTOIRES
+#define BPP_CHARACTER_REPERTOIRES {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}
+#endif
+ */
+/* XHTML formats.
+#ifndef BPP_XHTML_PRINT_FORMATS
+#define BPP_XHTML_PRINT_FORMATS     "image/gif:89A,image/jpeg"
+#endif
+
+#ifndef BPP_XHTML_PRINT_FORMATS_LEN
+#define BPP_XHTML_PRINT_FORMATS_LEN 24
+#endif
+ */
+/* Color supported.
+#ifndef BPP_COLOR_SUPORTED
+#define BPP_COLOR_SUPORTED          FALSE
+#endif
+ */
+/* 1284 ID string. First 2 bytes are the length.
+#ifndef BPP_1284ID
+#define BPP_1284ID                  "\x00\x48MANUFACTURER:ACME Manufacturing;COMMAND SET:PCL,MPL;MODEL:LaserBeam \?;"
+#endif
+
+#ifndef BPP_1284ID_LEN
+#define BPP_1284ID_LEN              72
+#endif
+ */
+/* Printer name.
+#ifndef BPP_PRINTER_NAME
+#define BPP_PRINTER_NAME            "My Printer"
+#endif
+
+#ifndef BPP_PRINTER_NAME_LEN
+#define BPP_PRINTER_NAME_LEN        10
+#endif
+ */
+
+/* Printer location.
+#ifndef BPP_PRINTER_LOCATION
+#define BPP_PRINTER_LOCATION        "Hotel Lobby"
+#endif
+
+#ifndef BPP_PRINTER_LOCATION_LEN
+#define BPP_PRINTER_LOCATION_LEN    11
+#endif
+ */
+/* Duplex printing supported.
+#ifndef BPP_DUPLEX_SUPPORTED
+#define BPP_DUPLEX_SUPPORTED        TRUE
+#endif
+ */
+
+/* Media types supported.
+#ifndef BPP_MEDIA_TYPES_SUPPORTED
+#define BPP_MEDIA_TYPES_SUPPORTED   "stationary,continuous-long,photographic-high-gloss,cardstock"
+#endif
+
+#ifndef BPP_MEDIA_TYPES_SUPPORTED_LEN
+#define BPP_MEDIA_TYPES_SUPPORTED_LEN   60
+#endif
+ */
+/* Maximum media with supported.
+#ifndef BPP_MAX_MEDIA_WIDTH
+#define BPP_MAX_MEDIA_WIDTH         205
+#endif
+ */
+/* Maximum media length supported.
+#ifndef BPP_MAX_MEDIA_LENGTH
+#define BPP_MAX_MEDIA_LENGTH        285
+#endif
+ */
+/* the maximum string len for the media size of medium loaded */
+#ifndef BPP_MEDIA_SIZE_LEN
+#define BPP_MEDIA_SIZE_LEN          33
+#endif
+
+/* Debug Trace the SOAP object, if TRUE */
+#ifndef BPP_TRACE_XML
+#define BPP_TRACE_XML               TRUE
+#endif
+
+/* in case that the SOAP object does not all come in one OBEX packet,
+ * this size of data may be kept in the BPP control block for continuing parsing.
+ * The maximum is the size of the biggest GKI buffer (GKI_MAX_BUF_SIZE) */
+#ifndef BPP_SOAP_KEEP_SIZE
+#define BPP_SOAP_KEEP_SIZE          200
+#endif
+
+
+/******************************************************************************
+**
+** BIP
+**
+******************************************************************************/
+#ifndef BIP_INCLUDED
+#define BIP_INCLUDED                FALSE
+#endif
+
+/* TRUE to include imaging initiator */
+#ifndef BIP_INITR_INCLUDED
+#define BIP_INITR_INCLUDED          FALSE
+#endif
+
+/* TRUE to include imaging responder */
+#ifndef BIP_RSPDR_INCLUDED
+#define BIP_RSPDR_INCLUDED          FALSE
+#endif
+
+/* TRUE to include image push feature */
+#ifndef BIP_PUSH_INCLUDED
+#define BIP_PUSH_INCLUDED           TRUE
+#endif
+
+/* TRUE to include image pull feature */
+#ifndef BIP_PULL_INCLUDED
+#define BIP_PULL_INCLUDED           TRUE
+#endif
+
+/* TRUE to include advanced image printing feature */
+#ifndef BIP_PRINTING_INCLUDED
+#define BIP_PRINTING_INCLUDED       TRUE
+#endif
+
+/* TRUE to include automatic archive feature */
+#ifndef BIP_ARCHIVE_INCLUDED
+#define BIP_ARCHIVE_INCLUDED        TRUE
+#endif
+
+/* TRUE to include remote camera feature */
+#ifndef BIP_CAMERA_INCLUDED
+#define BIP_CAMERA_INCLUDED         TRUE
+#endif
+
+/* TRUE to include remote display feature */
+#ifndef BIP_DISPLAY_INCLUDED
+#define BIP_DISPLAY_INCLUDED        TRUE
+#endif
+
+/* TRUE to include sanity check code for API functions */
+#ifndef BIP_SANITY_CHECKS
+#define BIP_SANITY_CHECKS           TRUE
+#endif
+
+/* TRUE to show the received XML object in trace for conformance tests */
+#ifndef BIP_TRACE_XML
+#define BIP_TRACE_XML               TRUE
+#endif
+
+/* in case that the received XML object is not complete, the XML parser state machine needs
+ * to keep a copy of the data from the last '<'
+ * This macro specifies the maximun amount of data for this purpose */
+#ifndef BIP_XML_CARRY_OVER_LEN
+#define BIP_XML_CARRY_OVER_LEN      100
+#endif
+
+/* minimum 4, maximum is 255. The value should be set to the maximum size of encoding string + 1. JPEG2000.
+ * If vendor specific format is supported, it might be bigger than 9 */
+#ifndef BIP_IMG_ENCODE_SIZE
+#define BIP_IMG_ENCODE_SIZE         9
+#endif
+
+/* MIME type: text/plain */
+#ifndef BIP_TYPE_SIZE
+#define BIP_TYPE_SIZE               20
+#endif
+
+/* example: iso-8895-1 */
+#ifndef BIP_CHARSET_SIZE
+#define BIP_CHARSET_SIZE            10
+#endif
+
+/* friendly name */
+#ifndef BIP_FNAME_SIZE
+#define BIP_FNAME_SIZE              20
+#endif
+
+/* service name */
+#ifndef BIP_SNAME_SIZE
+#define BIP_SNAME_SIZE              60
+#endif
+
+/* temporary storage file name(for file system access, may include path) */
+#ifndef BIP_TEMP_NAME_SIZE
+#define BIP_TEMP_NAME_SIZE          200
+#endif
+
+/* image file name */
+#ifndef BIP_IMG_NAME_SIZE
+#define BIP_IMG_NAME_SIZE           200
+#endif
+
+/* attachment file name */
+#ifndef BIP_ATT_NAME_SIZE
+#define BIP_ATT_NAME_SIZE           200
+#endif
+
+/* object (image, attachment, thumbnail) file name (may be used for file system) */
+#ifndef BIP_OBJ_NAME_SIZE
+#define BIP_OBJ_NAME_SIZE           200
+#endif
+
+
+
+/******************************************************************************
+**
+** HCRP
+**
+******************************************************************************/
+
+#ifndef HCRP_INCLUDED
+#define HCRP_INCLUDED               FALSE
+#endif
+
+/* This is set to enable server. */
+#ifndef HCRP_SERVER_INCLUDED
+#define HCRP_SERVER_INCLUDED       FALSE
+#endif
+
+/* This is set to enable client. */
+#ifndef HCRP_CLIENT_INCLUDED
+#define HCRP_CLIENT_INCLUDED        FALSE
+#endif
+
+/* TRUE enables the notification option of the profile. */
+#ifndef HCRP_NOTIFICATION_INCLUDED
+#define HCRP_NOTIFICATION_INCLUDED  TRUE
+#endif
+
+/* TRUE enables the vendor specific option of the profile. */
+#ifndef HCRP_VENDOR_SPEC_INCLUDED
+#define HCRP_VENDOR_SPEC_INCLUDED   TRUE
+#endif
+
+/* TRUE enables state machine traces. */
+#ifndef HCRP_FSM_DEBUG
+#define HCRP_FSM_DEBUG              FALSE
+#endif
+
+/* TRUE enables protocol message traces. */
+#ifndef HCRP_PROTO_DEBUG
+#define HCRP_PROTO_DEBUG            FALSE
+#endif
+
+/* Maximum length used to store the service name (Minimum 1). */
+#ifndef HCRP_MAX_SERVICE_NAME_LEN
+#define HCRP_MAX_SERVICE_NAME_LEN   32
+#endif
+
+/* Maximum length used to store the device name (Minimum 1). */
+#ifndef HCRP_MAX_DEVICE_NAME_LEN
+#define HCRP_MAX_DEVICE_NAME_LEN    32
+#endif
+
+/* Maximum length of device location (Minimum 1) */
+#ifndef HCRP_MAX_DEVICE_LOC_LEN
+#define HCRP_MAX_DEVICE_LOC_LEN     32
+#endif
+
+/* Maximum length used to store the friendly name (Minimum 1). */
+#ifndef HCRP_MAX_FRIENDLY_NAME_LEN
+#define HCRP_MAX_FRIENDLY_NAME_LEN  32
+#endif
+
+/* Maximum length used to store the 1284 id string (Minimum 2 byte length field). */
+#ifndef HCRP_MAX_SDP_1284_ID_LEN
+#define HCRP_MAX_SDP_1284_ID_LEN    128
+#endif
+
+/* Maximum length for parameters to be processed for vendor specific commands. */
+#ifndef HCRP_MAX_VEND_SPEC_LEN
+#define HCRP_MAX_VEND_SPEC_LEN      4
+#endif
+
+/* Number of seconds to wait for 2nd GAP to open. */
+#ifndef HCRP_OPEN_CHAN_TOUT
+#define HCRP_OPEN_CHAN_TOUT         5
+#endif
+
+/* Number of seconds to wait for 2nd GAP to close. */
+#ifndef HCRP_CLOSE_CHAN_TOUT
+#define HCRP_CLOSE_CHAN_TOUT        3
+#endif
+
+/* Number of seconds to wait for the application to respond to a protocol request. */
+#ifndef HCRP_APPL_RSP_TOUT
+#define HCRP_APPL_RSP_TOUT          5
+#endif
+
+/* Number of seconds to wait for the peer device to respond to a protocol request. */
+#ifndef HCRP_CMD_RSP_TOUT
+#define HCRP_CMD_RSP_TOUT           7
+#endif
+
+/* Number of seconds between subsequent credit requests to the server when the send watermark has been exceeded. */
+#ifndef HCRP_CREDIT_REQ_UPDATES
+#define HCRP_CREDIT_REQ_UPDATES     1
+#endif
+
+/* Maximum number of results to return in a HCRP_FindServices search. */
+#ifndef HCRP_MAX_SEARCH_RESULTS
+#define HCRP_MAX_SEARCH_RESULTS     1
+#endif
+
+/* Maximum number of bytes to be reserved for searching for the client's notification record. */
+#ifndef HCRP_MAX_NOTIF_DISC_BUF
+#define HCRP_MAX_NOTIF_DISC_BUF     300
+#endif
+
+/* Maximum number of clients the server will allow to be registered for notifications. */
+#ifndef HCRP_MAX_NOTIF_CLIENTS
+#define HCRP_MAX_NOTIF_CLIENTS      3
+#endif
+
+/* Spec says minimum of two notification retries. */
+#ifndef HCRP_NOTIF_NUM_RETRIES
+#define HCRP_NOTIF_NUM_RETRIES      4
+#endif
+
+/*************************************************************************
+** Definitions for Multi-Client Server HCRP
+** Note: Many of the above HCRP definitions are also used
+** Maximum number of clients allowed to connect simultaneously
+** Must be less than ((GAP_MAX_CONNECTIONS - 1) / 2)
+*/
+#ifndef HCRPM_MAX_CLIENTS
+#define HCRPM_MAX_CLIENTS           3
+#endif
+
+
+/******************************************************************************
+**
+** PAN
+**
+******************************************************************************/
+
+#ifndef PAN_INCLUDED
+#define PAN_INCLUDED                FALSE
+#endif
+
+
+/******************************************************************************
+**
+** SAP
+**
+******************************************************************************/
+
+#ifndef SAP_SERVER_INCLUDED
+#define SAP_SERVER_INCLUDED         FALSE
+#endif
+
+
+/*************************************************************************
+ * A2DP Definitions
+ */
+#ifndef A2D_INCLUDED
+#define A2D_INCLUDED            FALSE
+#endif
+
+/* TRUE to include SBC utility functions */
+#ifndef A2D_SBC_INCLUDED
+#define A2D_SBC_INCLUDED        A2D_INCLUDED
+#endif
+
+/* TRUE to include MPEG-1,2 (mp3) utility functions */
+#ifndef A2D_M12_INCLUDED
+#define A2D_M12_INCLUDED        A2D_INCLUDED
+#endif
+
+/* TRUE to include MPEG-2,4 (aac) utility functions */
+#ifndef A2D_M24_INCLUDED
+#define A2D_M24_INCLUDED        A2D_INCLUDED
+#endif
+
+/*************************************************************************
+ * VDP Definitions
+ */
+#ifndef VDP_INCLUDED
+#define VDP_INCLUDED            FALSE
+#endif
+
+/******************************************************************************
+**
+** AVCTP
+**
+******************************************************************************/
+
+#ifndef AVCT_INCLUDED
+#define AVCT_INCLUDED               FALSE
+#endif
+
+/* Number of simultaneous ACL links to different peer devices. */
+#ifndef AVCT_NUM_LINKS
+#define AVCT_NUM_LINKS              2
+#endif
+
+/* Number of simultaneous AVCTP connections. */
+#ifndef AVCT_NUM_CONN
+#define AVCT_NUM_CONN               3
+#endif
+
+/* TRUE to support the browsing channel. */
+#ifndef AVCT_BROWSE_INCLUDED
+#define AVCT_BROWSE_INCLUDED        TRUE
+#endif
+
+#if ((L2CAP_FCR_INCLUDED == FALSE) && (AVCT_BROWSE_INCLUDED == TRUE))
+#undef AVCT_BROWSE_INCLUDED
+#define AVCT_BROWSE_INCLUDED        FALSE
+#endif
+
+/* Pool ID where to reassemble the SDU.
+   This Pool allows buffers to be used that are larger than
+   the L2CAP_MAX_MTU. */
+#ifndef AVCT_BR_USER_RX_POOL_ID
+#define AVCT_BR_USER_RX_POOL_ID     HCI_ACL_POOL_ID
+#endif
+
+/* Pool ID where to hold the SDU.
+   This Pool allows buffers to be used that are larger than
+   the L2CAP_MAX_MTU. */
+#ifndef AVCT_BR_USER_TX_POOL_ID
+#define AVCT_BR_USER_TX_POOL_ID     HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
+*/
+#ifndef AVCT_BR_FCR_RX_POOL_ID
+#define AVCT_BR_FCR_RX_POOL_ID      HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments used in (re)transmissions.
+L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
+Note:  This pool needs to have enough buffers to hold two times the window size negotiated
+ in the tL2CAP_FCR_OPTIONS (2 * tx_win_size)  to allow for retransmissions.
+ The size of each buffer must be able to hold the maximum MPS segment size passed in
+ tL2CAP_FCR_OPTIONS plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
+*/
+#ifndef AVCT_BR_FCR_TX_POOL_ID
+#define AVCT_BR_FCR_TX_POOL_ID      HCI_ACL_POOL_ID
+#endif
+
+/* AVCTP Browsing channel FCR Option:
+Size of the transmission window when using enhanced retransmission mode. Not used
+in basic and streaming modes. Range: 1 - 63
+*/
+#ifndef AVCT_BR_FCR_OPT_TX_WINDOW_SIZE
+#define AVCT_BR_FCR_OPT_TX_WINDOW_SIZE      10
+#endif
+
+/* AVCTP Browsing channel FCR Option:
+Number of transmission attempts for a single I-Frame before taking
+Down the connection. Used In ERTM mode only. Value is Ignored in basic and
+Streaming modes.
+Range: 0, 1-0xFF
+0 - infinite retransmissions
+1 - single transmission
+*/
+#ifndef AVCT_BR_FCR_OPT_MAX_TX_B4_DISCNT
+#define AVCT_BR_FCR_OPT_MAX_TX_B4_DISCNT    20
+#endif
+
+/* AVCTP Browsing channel FCR Option: Retransmission Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost I-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 2000 (2 secs) when supporting PBF.
+ */
+#ifndef AVCT_BR_FCR_OPT_RETX_TOUT
+#define AVCT_BR_FCR_OPT_RETX_TOUT           2000
+#endif
+
+/* AVCTP Browsing channel FCR Option: Monitor Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost S-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 12000 (12 secs) when supporting PBF.
+*/
+#ifndef AVCT_BR_FCR_OPT_MONITOR_TOUT
+#define AVCT_BR_FCR_OPT_MONITOR_TOUT        12000
+#endif
+
+/******************************************************************************
+**
+** AVRCP
+**
+******************************************************************************/
+
+#ifndef AVRC_INCLUDED
+#define AVRC_INCLUDED               FALSE
+#endif
+
+/* TRUE to support AVRCP 1.3 - Metadata. */
+#ifndef AVRC_METADATA_INCLUDED
+#define AVRC_METADATA_INCLUDED      TRUE
+#endif
+
+/* TRUE to support AVRCP 1.4 - Advanced Control. */
+#ifndef AVRC_ADV_CTRL_INCLUDED
+#define AVRC_ADV_CTRL_INCLUDED      TRUE
+#endif
+
+/******************************************************************************
+**
+** MCAP
+**
+******************************************************************************/
+#ifndef MCA_INCLUDED
+#define MCA_INCLUDED                FALSE
+#endif
+
+/* TRUE to support Clock Synchronization OpCodes */
+#ifndef MCA_SYNC_INCLUDED
+#define MCA_SYNC_INCLUDED           FALSE
+#endif
+
+/* The MTU size for the L2CAP configuration on control channel. 48 is the minimal */
+#ifndef MCA_CTRL_MTU
+#define MCA_CTRL_MTU    60
+#endif
+
+/* The maximum number of registered MCAP instances. */
+#ifndef MCA_NUM_REGS
+#define MCA_NUM_REGS    3
+#endif
+
+/* The maximum number of control channels (to difference devices) per registered MCAP instances. */
+#ifndef MCA_NUM_LINKS
+#define MCA_NUM_LINKS   3
+#endif
+
+/* The maximum number of MDEP (including HDP echo) per registered MCAP instances. */
+#ifndef MCA_NUM_DEPS
+#define MCA_NUM_DEPS    3
+#endif
+
+/* The maximum number of MDL link per control channel. */
+#ifndef MCA_NUM_MDLS
+#define MCA_NUM_MDLS    4
+#endif
+
+/* Pool ID where to reassemble the SDU. */
+#ifndef MCA_USER_RX_POOL_ID
+#define MCA_USER_RX_POOL_ID     HCI_ACL_POOL_ID
+#endif
+
+/* Pool ID where to hold the SDU. */
+#ifndef MCA_USER_TX_POOL_ID
+#define MCA_USER_TX_POOL_ID     HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments during SDU reassembly
+*/
+#ifndef MCA_FCR_RX_POOL_ID
+#define MCA_FCR_RX_POOL_ID      HCI_ACL_POOL_ID
+#endif
+
+/*
+GKI Buffer Pool ID used to hold MPS segments used in (re)transmissions.
+L2CAP_DEFAULT_ERM_POOL_ID is specified to use the HCI ACL data pool.
+Note:  This pool needs to have enough buffers to hold two times the window size negotiated
+ in the tL2CAP_FCR_OPTIONS (2 * tx_win_size)  to allow for retransmissions.
+ The size of each buffer must be able to hold the maximum MPS segment size passed in
+ tL2CAP_FCR_OPTIONS plus BT_HDR (8) + HCI preamble (4) + L2CAP_MIN_OFFSET (11 - as of BT 2.1 + EDR Spec).
+*/
+#ifndef MCA_FCR_TX_POOL_ID
+#define MCA_FCR_TX_POOL_ID      HCI_ACL_POOL_ID
+#endif
+
+/* MCAP control channel FCR Option:
+Size of the transmission window when using enhanced retransmission mode.
+1 is defined by HDP specification for control channel.
+*/
+#ifndef MCA_FCR_OPT_TX_WINDOW_SIZE
+#define MCA_FCR_OPT_TX_WINDOW_SIZE      1
+#endif
+
+/* MCAP control channel FCR Option:
+Number of transmission attempts for a single I-Frame before taking
+Down the connection. Used In ERTM mode only. Value is Ignored in basic and
+Streaming modes.
+Range: 0, 1-0xFF
+0 - infinite retransmissions
+1 - single transmission
+*/
+#ifndef MCA_FCR_OPT_MAX_TX_B4_DISCNT
+#define MCA_FCR_OPT_MAX_TX_B4_DISCNT    20
+#endif
+
+/* MCAP control channel FCR Option: Retransmission Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost I-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 2000 (2 secs) when supporting PBF.
+ */
+#ifndef MCA_FCR_OPT_RETX_TOUT
+#define MCA_FCR_OPT_RETX_TOUT           2000
+#endif
+
+/* MCAP control channel FCR Option: Monitor Timeout
+The AVRCP specification set a value in the range of 300 - 2000 ms
+Timeout (in msecs) to detect Lost S-Frames. Only used in Enhanced retransmission mode.
+Range: Minimum 12000 (12 secs) when supporting PBF.
+*/
+#ifndef MCA_FCR_OPT_MONITOR_TOUT
+#define MCA_FCR_OPT_MONITOR_TOUT        12000
+#endif
+
+/* MCAP control channel FCR Option: Maximum PDU payload size.
+The maximum number of payload octets that the local device can receive in a single PDU.
+*/
+#ifndef MCA_FCR_OPT_MPS_SIZE
+#define MCA_FCR_OPT_MPS_SIZE            1000
+#endif
+
+/* Shared transport */
+#ifndef NFC_SHARED_TRANSPORT_ENABLED
+#define NFC_SHARED_TRANSPORT_ENABLED    FALSE
+#endif
+
+/******************************************************************************
+**
+** SER
+**
+******************************************************************************/
+
+#ifndef SER_INCLUDED
+#define SER_INCLUDED                FALSE
+#endif
+
+/* Task which runs the serial application. */
+#ifndef SER_TASK
+#define SER_TASK                    BTE_APPL_TASK
+#endif
+
+/* Mailbox used by serial application. */
+#ifndef SER_MBOX
+#define SER_MBOX                    TASK_MBOX_1
+#endif
+
+/* Mailbox mask. */
+#ifndef SER_MBOX_MASK
+#define SER_MBOX_MASK               TASK_MBOX_1_EVT_MASK
+#endif
+
+/* TX path application event. */
+#ifndef SER_TX_PATH_APPL_EVT
+#define SER_TX_PATH_APPL_EVT        EVENT_MASK(APPL_EVT_3)
+#endif
+
+/* RX path application event. */
+#ifndef SER_RX_PATH_APPL_EVT
+#define SER_RX_PATH_APPL_EVT        EVENT_MASK(APPL_EVT_4)
+#endif
+
+/******************************************************************************
+**
+** HCI Services
+**
+******************************************************************************/
+/* Event mask reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_EVT_MASK
+#define HCISU_EVT_MASK              EVENT_MASK(APPL_EVT_0)
+#endif
+
+/* MBox reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_MBOX
+#define HCISU_MBOX                  TASK_MBOX_2
+#endif
+
+/* MBox event mask reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_MBOX_EVT_MASK
+#define HCISU_MBOX_EVT_MASK         TASK_MBOX_2_EVT_MASK
+#endif
+
+/* Timer reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_TIMER
+#define HCISU_TIMER                 TIMER_2
+#endif
+
+/* Timer event mask reserved for handling HCIS events HCISU_TASK */
+#ifndef HCISU_TIMER_EVT_MASK
+#define HCISU_TIMER_EVT_MASK        TIMER_2_EVT_MASK
+#endif
+
+/******************************************************************************
+**
+** HCI UART
+**
+******************************************************************************/
+#ifndef BAUDRATE_UPDATE_ENCODED_INCLUDED
+#define BAUDRATE_UPDATE_ENCODED_INCLUDED    FALSE
+#endif
+
+/******************************************************************************
+**
+** HCI Services (H5 3 wired uart), H4 plus SLIP enabled
+**
+******************************************************************************/
+#ifndef SLIP_INCLUDED
+#define SLIP_INCLUDED                   TRUE
+#endif
+
+#ifndef SLIP_STATIS_INCLUDED
+#define SLIP_STATIS_INCLUDED            TRUE
+#endif
+
+#ifndef SLIP_SW_FLOW_CTRL
+#define SLIP_SW_FLOW_CTRL               TRUE
+#endif
+
+#ifndef BT_TRACE_SLIP
+#define BT_TRACE_SLIP                   FALSE
+#endif
+
+#ifndef SLIP_HOST_SLIDING_WINDOW_SIZE
+#define SLIP_HOST_SLIDING_WINDOW_SIZE   7
+#endif
+
+#ifndef SLIP_MAX_RETRANSMIT
+#define SLIP_MAX_RETRANSMIT             10
+#endif
+
+/* time (in ms) interval between WAKEUP messages */
+#ifndef SLIP_WAKEUP_INTERVAL
+#define SLIP_WAKEUP_INTERVAL            10
+#endif
+
+/* max trial to send WAKEUP messages up to 255 */
+#ifndef SLIP_MAX_WAKEUP_TRIAL
+#define SLIP_MAX_WAKEUP_TRIAL           10
+#endif
+
+/*
+The H5 work around sequence will be:
+
+1. controller sends CONFIG with configuration field. (This is not spec compliance.
+   Controller shall not have configuration field. This initiates work around.)
+2. host ignore the configuration field.
+3. Host sends CONFIG with configuration field.
+4. controller reponse CONFIG_RESPONSE with configuration field. This shall be the
+   final configuration both FW and STACK use. (spec compliance).
+5. Host copied the configuration field over and sent CONFIG_RESPONSE with this
+   configuration field (workaround)
+*/
+
+#ifndef SLIP_CONFIG_FIELD_WORK_AROUND_INCLUDED
+#define SLIP_CONFIG_FIELD_WORK_AROUND_INCLUDED       TRUE
+#endif
+
+/******************************************************************************
+**
+** Sleep Mode (Low Power Mode)
+**
+******************************************************************************/
+#ifndef HCILP_INCLUDED
+#define HCILP_INCLUDED                  TRUE
+#endif
+
+/* sleep mode
+
+    0: disable
+    1: UART with Host wake/BT wake out of band signals
+    4: H4IBSS, UART with in band signal without Host/BT wake
+    9: H5 with in band signal of SLIP without Host/BT wake
+*/
+#ifndef HCILP_SLEEP_MODE
+#define HCILP_SLEEP_MODE                (0)
+#endif
+
+/* Host Stack Idle Threshold in 300ms or 25ms, it depends on controller
+
+  In sleep mode 1, this is the number of firmware loops executed with no activity
+    before the Host wake line is deasserted. Activity includes HCI traffic excluding
+    certain sleep mode commands and the presence of SCO connections if the
+    "Allow Host Sleep During SCO" flag is not set to 1. Each count of this
+    parameter is roughly equivalent to 300ms or 25ms.
+
+  Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_IDLE_THRESHOLD
+#define HCILP_IDLE_THRESHOLD             (1)
+#endif
+
+/* Host Controller Idle Threshold in 300ms or 25ms, it depends on controller
+
+    This is the number of firmware loops executed with no activity before the HC is
+    considered idle. Depending on the mode, HC may then attempt to sleep.
+    Activity includes HCI traffic excluding certain sleep mode commands and
+    the presence of ACL/SCO connections.
+
+  Not applicable for sleep mode 4(H4IBSS)
+*/
+#ifndef HCILP_HC_IDLE_THRESHOLD
+#define HCILP_HC_IDLE_THRESHOLD          (1)
+#endif
+
+/* GPIO for BT_WAKE signal */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_BT_WAKE_GPIO
+#define HCILP_BT_WAKE_GPIO              UPIO_GENERAL1
+#endif
+
+/* GPIO for HOST_WAKE signal */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_HOST_WAKE_GPIO
+#define HCILP_HOST_WAKE_GPIO            UPIO_GENERAL2
+#endif
+
+/* BT_WAKE Polarity - 0=Active Low, 1= Active High */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_BT_WAKE_POLARITY
+#define HCILP_BT_WAKE_POLARITY          0
+#endif
+
+/* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
+/* Not applicable for sleep mode 4(H4IBSS) and 9(H5) */
+#ifndef HCILP_HOST_WAKE_POLARITY
+#define HCILP_HOST_WAKE_POLARITY        0
+#endif
+
+/* HCILP_ALLOW_HOST_SLEEP_DURING_SCO
+
+    When this flag is set to 0, the host is not allowed to sleep while
+    an SCO is active. In sleep mode 1, the device will keep the host
+    wake line asserted while an SCO is active.
+    When this flag is set to 1, the host can sleep while an SCO is active.
+    This flag should only be set to 1 if SCO traffic is directed to the PCM interface.
+
+    Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_ALLOW_HOST_SLEEP_DURING_SCO
+#define HCILP_ALLOW_HOST_SLEEP_DURING_SCO       1
+#endif
+
+/* HCILP_COMBINE_SLEEP_MODE_AND_LPM
+
+    In Mode 0, always set byte 7 to 0. In sleep mode 1, device always
+    requires permission to sleep between scans / periodic inquiries regardless
+    of the setting of this byte. In sleep mode 1, if byte is set, device must
+    have "permission" to sleep during the low power modes of sniff, hold, and park.
+    If byte is not set, device can sleep without permission during these modes.
+    Permission to sleep in Mode 1 is obtained if the BT_WAKE signal is not asserted.
+
+    Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_COMBINE_SLEEP_MODE_AND_LPM
+#define HCILP_COMBINE_SLEEP_MODE_AND_LPM        1
+#endif
+
+/* HCILP_ENABLE_UART_TXD_TRI_STATE
+
+    When set to 0, the device will not tristate its UART TX line before going to sleep.
+    When set to 1, the device will tristate its UART TX line before going to sleep.
+
+    Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_ENABLE_UART_TXD_TRI_STATE
+#define HCILP_ENABLE_UART_TXD_TRI_STATE        0
+#endif
+
+/* HCILP_PULSED_HOST_WAKE
+
+    Not applicable for sleep mode 4(H4IBSS) and 9(H5)
+*/
+#ifndef HCILP_PULSED_HOST_WAKE
+#define HCILP_PULSED_HOST_WAKE        0
+#endif
+
+/* HCILP_SLEEP_GUARD_TIME
+
+    Only for sleep mode 4(H4IBSS)
+    Time in 12.5ms between starting to monitor controller's CTS and raising its RTS
+*/
+#ifndef HCILP_SLEEP_GUARD_TIME
+#define HCILP_SLEEP_GUARD_TIME                 5
+#endif
+
+/* HCILP_WAKEUP_GUARD_TIME
+
+    Only for sleep mode 4(H4IBSS)
+    Time in 12.5ms between starting to monitor controller's CTS and lowering its RTS
+*/
+#ifndef HCILP_WAKEUP_GUARD_TIME
+#define HCILP_WAKEUP_GUARD_TIME                 5
+#endif
+
+/* HCILP_TXD_CONFIG
+
+    Only for sleep mode 4(H4IBSS)
+    0: controller's TXD stays low in sleep mode
+    1: controller's TXD stays high in sleep mode (default)
+*/
+#ifndef HCILP_TXD_CONFIG
+#define HCILP_TXD_CONFIG                        1
+#endif
+
+/* HCILP_BT_WAKE_IDLE_TIMEOUT
+
+    host's idle time in ms before initiating sleep procedure
+*/
+#ifndef HCILP_BT_WAKE_IDLE_TIMEOUT
+#define HCILP_BT_WAKE_IDLE_TIMEOUT              50
+#endif
+
+#ifndef H4IBSS_INCLUDED
+#define H4IBSS_INCLUDED                 TRUE
+#endif
+
+/* display H4IBSS state and event in text */
+#ifndef H4IBSS_DEBUG
+#define H4IBSS_DEBUG                    TRUE
+#endif
+
+/* time interval before going into sleep after having sent or received SLEEP_REQ_ACK */
+/* Valid range is 20 - 50 ms */
+#ifndef H4IBSS_SLEEP_GUARD_TIME
+#define H4IBSS_SLEEP_GUARD_TIME         (40)
+#endif
+
+/* timeout(msec) to wait for response of sleep request */
+#ifndef H4IBSS_SLEEP_REQ_RESP_TIME
+#define H4IBSS_SLEEP_REQ_RESP_TIME      (50)
+#endif
+
+/******************************************************************************
+**
+** RPC
+**
+******************************************************************************/
+
+#ifndef RPC_INCLUDED
+#define RPC_INCLUDED                FALSE
+#endif
+
+/* RPCT task mailbox ID for messages coming from rpcgen code. */
+#ifndef RPCT_MBOX
+#define RPCT_MBOX                   TASK_MBOX_0
+#endif
+
+/* RPCT task event for mailbox. */
+#ifndef RPCT_RPC_MBOX_EVT
+#define RPCT_RPC_MBOX_EVT           TASK_MBOX_0_EVT_MASK
+#endif
+
+/* RPCT task event from driver indicating RX data is ready. */
+#ifndef RPCT_RX_READY_EVT
+#define RPCT_RX_READY_EVT           APPL_EVT_0
+#endif
+
+/* RPCT task event from driver indicating data TX is done. */
+#ifndef RPCT_TX_DONE_EVT
+#define RPCT_TX_DONE_EVT            APPL_EVT_1
+#endif
+
+/* RPCT task event indicating data is in the circular buffer. */
+#ifndef RPCT_UCBUF_EVT
+#define RPCT_UCBUF_EVT              APPL_EVT_2
+#endif
+
+/* Task ID of RPCGEN task. */
+#ifndef RPCGEN_TASK
+#define RPCGEN_TASK                 BTU_TASK
+#endif
+
+/* RPCGEN task event for messages coming from RPCT. */
+#ifndef RPCGEN_MSG_EVT
+#define RPCGEN_MSG_EVT              TASK_MBOX_1_EVT_MASK
+#endif
+
+#ifndef RPCGEN_MSG_MBOX
+#define RPCGEN_MSG_MBOX             TASK_MBOX_1
+#endif
+
+/* Size of circular buffer used to store diagnostic messages. */
+#ifndef RPCT_UCBUF_SIZE
+#define RPCT_UCBUF_SIZE             2000
+#endif
+
+/******************************************************************************
+**
+** SAP - Sample ICP and HSP applications
+**
+******************************************************************************/
+
+#ifndef SAP_INCLUDED
+#define SAP_INCLUDED                FALSE
+#endif
+
+#ifndef ICA_INCLUDED
+#define ICA_INCLUDED                FALSE
+#endif
+
+#ifndef HSA_HS_INCLUDED
+#define HSA_HS_INCLUDED             FALSE
+#endif
+
+#ifndef HSA_AG_INCLUDED
+#define HSA_AG_INCLUDED             FALSE
+#endif
+
+#ifndef MMI_INCLUDED
+#define MMI_INCLUDED                FALSE
+#endif
+
+/* MMI task event from driver indicating RX data is ready. */
+#ifndef MMI_RX_READY_EVT
+#define MMI_RX_READY_EVT           APPL_EVT_0
+#endif
+
+/******************************************************************************
+**
+** APPL - Application Task
+**
+******************************************************************************/
+/* When TRUE indicates that an application task is to be run */
+#ifndef APPL_INCLUDED
+#define APPL_INCLUDED                FALSE
+#endif
+
+/* When TRUE remote terminal code included (RPC MUST be included) */
+#ifndef RSI_INCLUDED
+#define RSI_INCLUDED                FALSE
+#endif
+
+
+
+#define L2CAP_FEATURE_REQ_ID      73
+#define L2CAP_FEATURE_RSP_ID     173
+
+
+#define L2CAP_ENHANCED_FEATURES   0
+
+
+
+/* Use gki_delay for patch ram */
+#ifndef BCM2045_USE_DELAY
+#if ( SLIP_INCLUDED == TRUE )
+/* H5 need to be initialized after sending download mini driver HCI command */
+#define BCM2045_USE_DELAY           FALSE
+#else
+#define BCM2045_USE_DELAY           TRUE
+#endif
+#endif
+
+/******************************************************************************
+**
+** BTA
+**
+******************************************************************************/
+/* BTA EIR canned UUID list (default is dynamic) */
+#ifndef BTA_EIR_CANNED_UUID_LIST
+#define BTA_EIR_CANNED_UUID_LIST FALSE
+#endif
+
+/* Number of supported customer UUID in EIR */
+#ifndef BTA_EIR_SERVER_NUM_CUSTOM_UUID
+#define BTA_EIR_SERVER_NUM_CUSTOM_UUID     8
+#endif
+
+/******************************************************************************
+**
+** BTE
+**
+******************************************************************************/
+#ifndef BTE_PLATFORM_IDLE
+#define BTE_PLATFORM_IDLE
+#endif
+
+#ifndef BTE_IDLE_TASK_INCLUDED
+#define BTE_IDLE_TASK_INCLUDED TRUE
+#endif
+
+#ifndef BTE_PLATFORM_INITHW
+#define BTE_PLATFORM_INITHW
+#endif
+
+#ifndef BTE_BTA_CODE_INCLUDED
+#define BTE_BTA_CODE_INCLUDED FALSE
+#endif
+
+
+/******************************************************************************
+**
+** BTTRC
+**
+******************************************************************************/
+/* Whether to parse and display traces-> Platform specific implementation */
+#ifndef BTTRC_DISP
+#define BTTRC_DISP        BTTRC_DispOnInsight
+#endif
+
+/******************************************************************************
+**
+** Tracing:  Include trace header file here.
+**
+******************************************************************************/
+
+#include "bt_trace.h"
+
+#endif /* BT_TARGET_H */
+
diff --git a/src/include/bt_trace.h b/src/include/bt_trace.h
new file mode 100644
index 0000000..d9c58dd
--- /dev/null
+++ b/src/include/bt_trace.h
@@ -0,0 +1,4837 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 BT_TRACE_H
+#define BT_TRACE_H
+
+#ifndef BTTRC_INCLUDED
+#define BTTRC_INCLUDED  FALSE
+#endif
+#ifndef BTTRC_PARSER_INCLUDED
+#define BTTRC_PARSER_INCLUDED FALSE
+#endif
+#ifndef MAX_TRACE_RAM_SIZE
+#define MAX_TRACE_RAM_SIZE 10000
+#endif
+
+/* BTE tracing IDs for debug purposes */
+/* LayerIDs for stack */
+#define BTTRC_ID_STK_GKI                   1
+#define BTTRC_ID_STK_BTU                   2
+#define BTTRC_ID_STK_HCI                   3
+#define BTTRC_ID_STK_L2CAP                 4
+#define BTTRC_ID_STK_RFCM_MX               5
+#define BTTRC_ID_STK_RFCM_PRT              6
+#define BTTRC_ID_STK_OBEX_C                7
+#define BTTRC_ID_STK_OBEX_S                8
+#define BTTRC_ID_STK_AVCT                  9
+#define BTTRC_ID_STK_AVDT                  10
+#define BTTRC_ID_STK_AVRC                  11
+#define BTTRC_ID_STK_BIC                   12
+#define BTTRC_ID_STK_BIS                   13
+#define BTTRC_ID_STK_BNEP                  14
+#define BTTRC_ID_STK_BPP                   15
+#define BTTRC_ID_STK_BTM_ACL               16
+#define BTTRC_ID_STK_BTM_PM                17
+#define BTTRC_ID_STK_BTM_DEV_CTRL          18
+#define BTTRC_ID_STK_BTM_SVC_DSC           19
+#define BTTRC_ID_STK_BTM_INQ               20
+#define BTTRC_ID_STK_BTM_SCO               21
+#define BTTRC_ID_STK_BTM_SEC               22
+#define BTTRC_ID_STK_DUN                   23
+#define BTTRC_ID_STK_HID                   24
+#define BTTRC_ID_STK_HSP2                  25
+#define BTTRC_ID_STK_CTP                   26
+#define BTTRC_ID_STK_FTC                   27
+#define BTTRC_ID_STK_FTS                   28
+#define BTTRC_ID_STK_GAP                   29
+#define BTTRC_ID_STK_GOEP                  30
+#define BTTRC_ID_STK_HCRP                  31
+#define BTTRC_ID_STK_ICP                   32
+#define BTTRC_ID_STK_OPC                   33
+#define BTTRC_ID_STK_OPS                   34
+#define BTTRC_ID_STK_PAN                   35
+#define BTTRC_ID_STK_SAP                   36
+#define BTTRC_ID_STK_SDP                   37
+#define BTTRC_ID_STK_SLIP                  38
+#define BTTRC_ID_STK_SPP                   39
+#define BTTRC_ID_STK_TCS                   40
+#define BTTRC_ID_STK_VDP                   41
+#define BTTRC_ID_STK_AMP                   42
+#define BTTRC_ID_STK_MCAP                  43
+#define BTTRC_ID_STK_GATT                  44
+#define BTTRC_ID_STK_SMP                   45
+#define BTTRC_ID_STK_NFC                   46
+#define BTTRC_ID_STK_NCI                   47
+#define BTTRC_ID_STK_IDEP                  48
+#define BTTRC_ID_STK_NDEP                  49
+#define BTTRC_ID_STK_LLCP                  50
+#define BTTRC_ID_STK_RW                    51
+#define BTTRC_ID_STK_CE                    52
+#define BTTRC_ID_STK_SNEP                  53
+#define BTTRC_ID_STK_NDEF                  54
+
+
+/* LayerIDs for BTA */
+#define BTTRC_ID_BTA_ACC                   55         /* Advanced Camera Client */
+#define BTTRC_ID_BTA_AG                    56         /* audio gateway */
+#define BTTRC_ID_BTA_AV                    57         /* Advanced audio */
+#define BTTRC_ID_BTA_BIC                   58         /* Basic Imaging Client */
+#define BTTRC_ID_BTA_BIS                   59         /* Basic Imaging Server */
+#define BTTRC_ID_BTA_BP                    60         /* Basic Printing Client */
+#define BTTRC_ID_BTA_CG                    61
+#define BTTRC_ID_BTA_CT                    62         /* cordless telephony terminal */
+#define BTTRC_ID_BTA_DG                    63         /* data gateway */
+#define BTTRC_ID_BTA_DM                    64         /* device manager */
+#define BTTRC_ID_BTA_DM_SRCH               65         /* device manager search */
+#define BTTRC_ID_BTA_DM_SEC                66         /* device manager security */
+#define BTTRC_ID_BTA_FM                    67
+#define BTTRC_ID_BTA_FTC                   68         /* file transfer client */
+#define BTTRC_ID_BTA_FTS                   69         /* file transfer server */
+#define BTTRC_ID_BTA_HIDH                  70
+#define BTTRC_ID_BTA_HIDD                  71
+#define BTTRC_ID_BTA_JV                    72
+#define BTTRC_ID_BTA_OPC                   73         /* object push client */
+#define BTTRC_ID_BTA_OPS                   74         /* object push server */
+#define BTTRC_ID_BTA_PAN                   75         /* Personal Area Networking */
+#define BTTRC_ID_BTA_PR                    76         /* Printer client */
+#define BTTRC_ID_BTA_SC                    77         /* SIM Card Access server */
+#define BTTRC_ID_BTA_SS                    78         /* synchronization server */
+#define BTTRC_ID_BTA_SYS                   79         /* system manager */
+#define BTTRC_ID_AVDT_SCB                  80         /* avdt scb */
+#define BTTRC_ID_AVDT_CCB                  81         /* avdt ccb */
+
+/* LayerIDs for BT APP */
+#define BTTRC_ID_BTAPP                     82
+#define BTTRC_ID_MAX_ID                    BTTRC_ID_BTAPP
+#define BTTRC_ID_ALL_LAYERS                0xFF       /* all trace layers */
+typedef UINT8 tBTTRC_LAYER_ID;
+
+/* Trace type definitions. Note that these are mutually exclusive in a trace. This
+means that any trace can be either error,warning,api,event or dbg */
+#if (BTU_STACK_LITE_ENABLED == TRUE)
+#define BTTRC_TYPE_ERROR                   0x81
+#define BTTRC_TYPE_WARNING                 0x82
+#define BTTRC_TYPE_API                     0x84
+#define BTTRC_TYPE_EVENT                   0x88
+#define BTTRC_TYPE_ACTION                  0x90
+#define BTTRC_TYPE_DBG                     0xA0
+#else
+#define BTTRC_TYPE_ERROR                   0x01       /* Traces for error situation */
+#define BTTRC_TYPE_WARNING	               0x02       /* Traces for warning situation */
+#define BTTRC_TYPE_API                     0x04       /* Traces for API */
+#define BTTRC_TYPE_EVENT                   0x08       /* Traces for EVENT */
+#define BTTRC_TYPE_ACTION                  0x10       /* Traces for Action functions */
+#define BTTRC_TYPE_DBG                     0x20       /* Traces for debugging purpose */
+#endif
+typedef UINT8 tBTTRC_TYPE;
+
+/* Masks to identify the stack that originated the trace */
+#define BTTRC_TRACE_LITE                   0x80       /* MM Lite stack */
+#define BTTRC_TRACE_EMBD                   0x40       /* Embedded host stack */
+
+/* Parameter datatypes used in Trace APIs */
+#define BTTRC_PARAM_UINT8                  1
+#define BTTRC_PARAM_UINT16                 2
+#define BTTRC_PARAM_UINT32                 3
+typedef UINT8 tBTTRC_PARAM_TYPE;
+
+/* Special token definitions */
+#define BTTRC_TOKEN_SM_STATE               0xFFFF     /* Token indicating the State of a State m/c */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* External declaration for appl_trace_level here to avoid to add the declaration in all the files using APPL_TRACExxx macros */
+extern UINT8 appl_trace_level ;
+
+/* Prototype for message logging function. */
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+extern void LogMsg_0 (UINT32 trace_set_mask, const char *p_str);
+extern void LogMsg_1 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1);
+extern void LogMsg_2 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2);
+extern void LogMsg_3 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3);
+extern void LogMsg_4 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3, UINT32 p4);
+extern void LogMsg_5 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3, UINT32 p4, UINT32 p5);
+extern void LogMsg_6 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2,
+                      UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6);
+
+/* Prototype for stack tracing function. */
+EXPORT_API extern void BTTRC_StackTrace0(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token);
+EXPORT_API extern void BTTRC_StackTrace1(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val);
+EXPORT_API extern void BTTRC_StackTrace2(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val);
+EXPORT_API extern void BTTRC_StackTrace3(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val);
+EXPORT_API extern void BTTRC_StackTrace4(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+                                   tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val);
+EXPORT_API extern void BTTRC_StackTrace5(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+                                   tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val,
+                                   tBTTRC_PARAM_TYPE p5_type, UINT32 p5_val);
+EXPORT_API extern void BTTRC_StackTrace6(tBTTRC_LAYER_ID layer_id,
+                                   tBTTRC_TYPE type,
+                                   UINT16 token,
+                                   tBTTRC_PARAM_TYPE p1_type, UINT32 p1_val,
+                                   tBTTRC_PARAM_TYPE p2_type, UINT32 p2_val,
+                                   tBTTRC_PARAM_TYPE p3_type, UINT32 p3_val,
+                                   tBTTRC_PARAM_TYPE p4_type, UINT32 p4_val,
+                                   tBTTRC_PARAM_TYPE p5_type, UINT32 p5_val,
+                                   tBTTRC_PARAM_TYPE p6_type, UINT32 p6_val);
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************************
+**
+** Trace configurable parameters
+**
+******************************************************************************/
+
+/* Enables or disables verbose trace information. */
+#ifndef BT_TRACE_VERBOSE
+#define BT_TRACE_VERBOSE    FALSE
+#endif
+
+/* Enables or disables all trace messages. */
+#ifndef BT_USE_TRACES
+#define BT_USE_TRACES       TRUE
+#endif
+
+/* Enables or disables protocol trace information. */
+#ifndef BT_TRACE_PROTOCOL
+#define BT_TRACE_PROTOCOL   TRUE  /* Android requires TRUE */
+#endif
+
+/******************************************************************************
+**
+** Trace Levels
+**
+** The following values may be used for different levels:
+**      BT_TRACE_LEVEL_NONE    0        * No trace messages to be generated
+**      BT_TRACE_LEVEL_ERROR   1        * Error condition trace messages
+**      BT_TRACE_LEVEL_WARNING 2        * Warning condition trace messages
+**      BT_TRACE_LEVEL_API     3        * API traces
+**      BT_TRACE_LEVEL_EVENT   4        * Debug messages for events
+**      BT_TRACE_LEVEL_DEBUG   5        * Debug messages (general)
+******************************************************************************/
+
+/* Core Stack default trace levels */
+#ifndef HCI_INITIAL_TRACE_LEVEL
+#define HCI_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BTM_INITIAL_TRACE_LEVEL
+#define BTM_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef L2CAP_INITIAL_TRACE_LEVEL
+#define L2CAP_INITIAL_TRACE_LEVEL           BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef LLCP_INITIAL_TRACE_LEVEL
+#define LLCP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AMP_INITIAL_TRACE_LEVEL
+#define AMP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef RFCOMM_INITIAL_TRACE_LEVEL
+#define RFCOMM_INITIAL_TRACE_LEVEL          BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef OBX_INITIAL_TRACE_LEVEL
+#define OBX_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SDP_INITIAL_TRACE_LEVEL
+#define SDP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef TCS_INITIAL_TRACE_LEVEL
+#define TCS_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+/* Profile default trace levels */
+#ifndef DUN_INITIAL_TRACE_LEVEL
+#define DUN_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GAP_INITIAL_TRACE_LEVEL
+#define GAP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GOEP_INITIAL_TRACE_LEVEL
+#define GOEP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HSP2_INITIAL_TRACE_LEVEL
+#define HSP2_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SPP_INITIAL_TRACE_LEVEL
+#define SPP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef ICP_INITIAL_TRACE_LEVEL
+#define ICP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef CTP_INITIAL_TRACE_LEVEL
+#define CTP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HCRP_INITIAL_TRACE_LEVEL
+#define HCRP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HCRPM_INITIAL_TRACE_LEVEL
+#define HCRPM_INITIAL_TRACE_LEVEL           BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BPP_INITIAL_TRACE_LEVEL
+#define BPP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BIP_INITIAL_TRACE_LEVEL
+#define BIP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BNEP_INITIAL_TRACE_LEVEL
+#define BNEP_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef PAN_INITIAL_TRACE_LEVEL
+#define PAN_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SAP_INITIAL_TRACE_LEVEL
+#define SAP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef FTP_INITIAL_TRACE_LEVEL
+#define FTP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef OPP_INITIAL_TRACE_LEVEL
+#define OPP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HFP_INITIAL_TRACE_LEVEL
+#define HFP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef A2D_INITIAL_TRACE_LEVEL
+#define A2D_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef VDP_INITIAL_TRACE_LEVEL
+#define VDP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVDT_INITIAL_TRACE_LEVEL
+#define AVDT_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVCT_INITIAL_TRACE_LEVEL
+#define AVCT_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef AVRC_INITIAL_TRACE_LEVEL
+#define AVRC_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef MCA_INITIAL_TRACE_LEVEL
+#define MCA_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef HID_INITIAL_TRACE_LEVEL
+#define HID_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+/* Application and other default trace levels */
+#ifndef RPC_INITIAL_TRACE_LEVEL
+#define RPC_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef APPL_INITIAL_TRACE_LEVEL
+#define APPL_INITIAL_TRACE_LEVEL            BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef BT_TRACE_APPL
+#define BT_TRACE_APPL   BT_USE_TRACES
+#endif
+
+#ifndef NFC_INITIAL_TRACE_LEVEL
+#define NFC_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef GATT_INITIAL_TRACE_LEVEL
+#define GATT_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+#ifndef SMP_INITIAL_TRACE_LEVEL
+#define SMP_INITIAL_TRACE_LEVEL             BT_TRACE_LEVEL_DEBUG
+#endif
+
+
+#if (BTTRC_INCLUDED == TRUE)
+/***************************************************************************************/
+/* BTTRC MACROS */
+
+#define BTTRC_EVENT(lid, event, state)   \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_EVENT, event, BTTRC_PARAM_UINT8, state);}
+#define BTTRC_ACTION(lid, action)  \
+            {BTTRC_StackTrace0(lid, BTTRC_TYPE_ACTION, action);}
+#define BTTRC_STATE(lid, state)   \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_EVENT, BTTRC_TOKEN_SM_STATE, BTTRC_PARAM_UINT8, state);}
+
+#define BTTRC_API0(lid, api)  \
+            {BTTRC_StackTrace0(lid, BTTRC_TYPE_API, api);}
+#define BTTRC_API1(lid, api, p1_t,p1_v)  \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_API, api, p1_t,p1_v);}
+#define BTTRC_API2(lid, api, p1_t,p1_v,p2_t,p2_v)  \
+            {BTTRC_StackTrace2(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v);}
+#define BTTRC_API3(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            {BTTRC_StackTrace3(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v);}
+#define BTTRC_API4(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            {BTTRC_StackTrace4(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v);}
+#define BTTRC_API5(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            {BTTRC_StackTrace5(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v);}
+#define BTTRC_API6(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            {BTTRC_StackTrace6(lid, BTTRC_TYPE_API, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v);}
+
+
+#define BTTRC_DBG0(lid, dbg)  \
+            {BTTRC_StackTrace0(lid, BTTRC_TYPE_DBG, dbg);}
+#define BTTRC_DBG1(lid, dbg, p1_t,p1_v)  \
+            {BTTRC_StackTrace1(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v);}
+#define BTTRC_DBG2(lid, dbg, p1_t,p1_v,p2_t,p2_v)  \
+            {BTTRC_StackTrace2(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v);}
+#define BTTRC_DBG3(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            {BTTRC_StackTrace3(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v);}
+#define BTTRC_DBG4(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            {BTTRC_StackTrace4(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v);}
+#define BTTRC_DBG5(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            {BTTRC_StackTrace5(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v);}
+#define BTTRC_DBG6(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            {BTTRC_StackTrace6(lid, BTTRC_TYPE_DBG, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v);}
+
+/***************************************************************************************/
+/*AVDT MACROS */
+
+#define BTTRC_AVDT_API0(api)   \
+        BTTRC_API0(BTTRC_ID_STK_AVDT, api)
+#define BTTRC_AVDT_API1(api, p1_t, p1_v) \
+        BTTRC_API1(BTTRC_ID_STK_AVDT, api, p1_t, p1_v)
+#define BTTRC_AVDT_API2(api, p1_t, p1_v, p2_t, p2_v) \
+        BTTRC_API2(BTTRC_ID_STK_AVDT, api, p1_t, p1_v, p2_t, p2_v)
+/***************************************************************************************/
+/*AVDT_SCB MACROS */
+
+#define BTTRC_AVDT_SCB_EVENT(event, state)   \
+            BTTRC_EVENT(BTTRC_ID_AVDT_SCB, event, state)
+#define BTTRC_AVDT_SCB_ACTION(action)  \
+            BTTRC_ACTION(BTTRC_ID_AVDT_SCB, action)
+#define BTTRC_AVDT_SCB_STATE(next_state)   \
+            BTTRC_STATE(BTTRC_ID_AVDT_SCB, next_state)
+
+#define BTTRC_AVDT_SCB_DBG0(dbg)  \
+            BTTRC_DBG0(BTTRC_ID_AVDT_SCB, dbg)
+#define BTTRC_AVDT_SCB_DBG1(dbg, p1_t,p1_v)  \
+            BTTRC_DBG1(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v)
+#define BTTRC_AVDT_SCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)  \
+            BTTRC_DBG2(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_SCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            BTTRC_DBG3(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_SCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            BTTRC_DBG4(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_SCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            BTTRC_DBG5(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_SCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            BTTRC_DBG6(BTTRC_ID_AVDT_SCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+/***************************************************************************************/
+/*AVDT_CCB MACROS */
+
+#define BTTRC_AVDT_CCB_EVENT(event, state)   \
+            BTTRC_EVENT(BTTRC_ID_AVDT_CCB, event, state)
+#define BTTRC_AVDT_CCB_ACTION(action)  \
+            BTTRC_ACTION(BTTRC_ID_AVDT_CCB, action)
+#define BTTRC_AVDT_CCB_STATE(next_state)   \
+            BTTRC_STATE(BTTRC_ID_AVDT_CCB, next_state)
+
+#define BTTRC_AVDT_CCB_DBG0(dbg)  \
+            BTTRC_DBG0(BTTRC_ID_AVDT_CCB, dbg)
+#define BTTRC_AVDT_CCB_DBG1(dbg, p1_t,p1_v)  \
+            BTTRC_DBG1(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v)
+#define BTTRC_AVDT_CCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)  \
+            BTTRC_DBG2(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_CCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)  \
+            BTTRC_DBG3(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_CCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)  \
+            BTTRC_DBG4(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_CCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)  \
+            BTTRC_DBG5(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_CCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)  \
+            BTTRC_DBG6(BTTRC_ID_AVDT_CCB, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+/***************************************************************************************/
+
+#else /*BTTRC_INCLUDED*/
+
+/***************************************************************************************/
+/* BTTRC MACROS */
+
+#define BTTRC_EVENT(lid, event, state)
+#define BTTRC_ACTION(lid, action)
+#define BTTRC_STATE(lid, state)
+
+#define BTTRC_API0(lid, api)
+#define BTTRC_API1(lid, api, p1_t, p1_v)
+#define BTTRC_API2(lid, api, p1_t, p1_v, p2_t, p2_v)
+#define BTTRC_API3(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_API4(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_API5(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_API6(lid, api, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+
+#define BTTRC_DBG0(lid, dbg)
+#define BTTRC_DBG1(lid, dbg, p1_t,p1_v)
+#define BTTRC_DBG2(lid, dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_DBG3(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_DBG4(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_DBG5(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_DBG6(lid, dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+/*AVDT MACROS */
+#define BTTRC_AVDT_API0(api)
+#define BTTRC_AVDT_API1(api, p1_t,p1_v)
+#define BTTRC_AVDT_API2(api, p1_t,p1_v,p2_t,p2_v)
+/***************************************************************************************/
+/*AVDT_SCB MACROS */
+
+#define BTTRC_AVDT_SCB_EVENT(event, state)
+#define BTTRC_AVDT_SCB_ACTION(action)
+#define BTTRC_AVDT_SCB_STATE(next_state)
+
+#define BTTRC_AVDT_SCB_DBG0(dbg)
+#define BTTRC_AVDT_SCB_DBG1(dbg, p1_t,p1_v)
+#define BTTRC_AVDT_SCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_SCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_SCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_SCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_SCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+/*AVDT_CCB MACROS */
+
+#define BTTRC_AVDT_CCB_EVENT(event, state)
+#define BTTRC_AVDT_CCB_ACTION(action)
+#define BTTRC_AVDT_CCB_STATE(next_state)
+
+#define BTTRC_AVDT_CCB_DBG0(dbg)
+#define BTTRC_AVDT_CCB_DBG1(dbg, p1_t,p1_v)
+#define BTTRC_AVDT_CCB_DBG2(dbg, p1_t,p1_v,p2_t,p2_v)
+#define BTTRC_AVDT_CCB_DBG3(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v)
+#define BTTRC_AVDT_CCB_DBG4(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v)
+#define BTTRC_AVDT_CCB_DBG5(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v)
+#define BTTRC_AVDT_CCB_DBG6(dbg, p1_t,p1_v,p2_t,p2_v,p3_t,p3_v,p4_t,p4_v,p5_t,p5_v,p6_t,p6_v)
+
+/***************************************************************************************/
+
+#endif /*BTTRC_INCLUDED*/
+
+
+#if (BT_USE_TRACES == TRUE)
+
+#define BT_TRACE_0(l,t,m)                           LogMsg_0((TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t)),(m))
+#define BT_TRACE_1(l,t,m,p1)                        LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1))
+#define BT_TRACE_2(l,t,m,p1,p2)                     LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2))
+#define BT_TRACE_3(l,t,m,p1,p2,p3)                  LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3))
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)               LogMsg_4(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4))
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)            LogMsg_5(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5))
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)         LogMsg_6(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | (t),(m),(UINT32)(p1),   \
+                                                        (UINT32)(p2),(UINT32)(p3),(UINT32)(p4), \
+                                                        (UINT32)(p5),(UINT32)(p6))
+
+#define BT_ERROR_TRACE_0(l,m)                     LogMsg_0(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m))
+#define BT_ERROR_TRACE_1(l,m,p1)                  LogMsg_1(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1))
+#define BT_ERROR_TRACE_2(l,m,p1,p2)               LogMsg_2(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1),(UINT32)(p2))
+#define BT_ERROR_TRACE_3(l,m,p1,p2,p3)            LogMsg_3(TRACE_CTRL_GENERAL | (l) | TRACE_ORG_STACK | TRACE_TYPE_ERROR,(m),(UINT32)(p1),(UINT32)(p2),(UINT32)(p3))
+
+/* Define tracing for the HCI unit
+*/
+#define HCI_TRACE_ERROR0(m)                     {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m);}
+#define HCI_TRACE_ERROR1(m,p1)                  {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1);}
+#define HCI_TRACE_ERROR2(m,p1,p2)               {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCI_TRACE_ERROR3(m,p1,p2,p3)            {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCI_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_WARNING0(m)                   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m);}
+#define HCI_TRACE_WARNING1(m,p1)                {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1);}
+#define HCI_TRACE_WARNING2(m,p1,p2)             {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCI_TRACE_WARNING3(m,p1,p2,p3)          {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCI_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (btu_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_EVENT0(m)                     {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m);}
+#define HCI_TRACE_EVENT1(m,p1)                  {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m, p1);}
+#define HCI_TRACE_EVENT2(m,p1,p2)               {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCI_TRACE_EVENT3(m,p1,p2,p3)            {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCI_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCI_TRACE_DEBUG0(m)                     {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m);}
+#define HCI_TRACE_DEBUG1(m,p1)                  {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1);}
+#define HCI_TRACE_DEBUG2(m,p1,p2)               {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCI_TRACE_DEBUG3(m,p1,p2,p3)            {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCI_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (btu_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for BTM
+*/
+#define BTM_TRACE_ERROR0(m)                     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m);}
+#define BTM_TRACE_ERROR1(m,p1)                  {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1);}
+#define BTM_TRACE_ERROR2(m,p1,p2)               {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BTM_TRACE_ERROR3(m,p1,p2,p3)            {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BTM_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BTM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_WARNING0(m)                   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m);}
+#define BTM_TRACE_WARNING1(m,p1)                {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1);}
+#define BTM_TRACE_WARNING2(m,p1,p2)             {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BTM_TRACE_WARNING3(m,p1,p2,p3)          {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BTM_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BTM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_API0(m)                       {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_API, m);}
+#define BTM_TRACE_API1(m,p1)                    {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_API, m, p1);}
+#define BTM_TRACE_API2(m,p1,p2)                 {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2);}
+#define BTM_TRACE_API3(m,p1,p2,p3)              {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BTM_TRACE_API4(m,p1,p2,p3,p4)           {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BTM_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_EVENT0(m)                     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m);}
+#define BTM_TRACE_EVENT1(m,p1)                  {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m, p1);}
+#define BTM_TRACE_EVENT2(m,p1,p2)               {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BTM_TRACE_EVENT3(m,p1,p2,p3)            {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BTM_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BTM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BTM_TRACE_DEBUG0(m)                     {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m);}
+#define BTM_TRACE_DEBUG1(m,p1)                  {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1);}
+#define BTM_TRACE_DEBUG2(m,p1,p2)               {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BTM_TRACE_DEBUG3(m,p1,p2,p3)            {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BTM_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BTM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BTM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BTM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the L2CAP unit
+*/
+#define L2CAP_TRACE_ERROR0(m)                     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m);}
+#define L2CAP_TRACE_ERROR1(m,p1)                  {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1);}
+#define L2CAP_TRACE_ERROR2(m,p1,p2)               {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define L2CAP_TRACE_ERROR3(m,p1,p2,p3)            {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define L2CAP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_WARNING0(m)                   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m);}
+#define L2CAP_TRACE_WARNING1(m,p1)                {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1);}
+#define L2CAP_TRACE_WARNING2(m,p1,p2)             {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define L2CAP_TRACE_WARNING3(m,p1,p2,p3)          {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define L2CAP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_API0(m)                       {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m);}
+#define L2CAP_TRACE_API1(m,p1)                    {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1);}
+#define L2CAP_TRACE_API2(m,p1,p2)                 {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2);}
+#define L2CAP_TRACE_API3(m,p1,p2,p3)              {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define L2CAP_TRACE_API4(m,p1,p2,p3,p4)           {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_EVENT0(m)                     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m);}
+#define L2CAP_TRACE_EVENT1(m,p1)                  {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m, p1);}
+#define L2CAP_TRACE_EVENT2(m,p1,p2)               {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define L2CAP_TRACE_EVENT3(m,p1,p2,p3)            {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define L2CAP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define L2CAP_TRACE_DEBUG0(m)                     {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m);}
+#define L2CAP_TRACE_DEBUG1(m,p1)                  {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1);}
+#define L2CAP_TRACE_DEBUG2(m,p1,p2)               {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define L2CAP_TRACE_DEBUG3(m,p1,p2,p3)            {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define L2CAP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define L2CAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define L2CAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_L2CAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m)                     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m);}
+#define LLCP_TRACE_ERROR1(m,p1)                  {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1);}
+#define LLCP_TRACE_ERROR2(m,p1,p2)               {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LLCP_TRACE_ERROR3(m,p1,p2,p3)            {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LLCP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_WARNING0(m)                   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m);}
+#define LLCP_TRACE_WARNING1(m,p1)                {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1);}
+#define LLCP_TRACE_WARNING2(m,p1,p2)             {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LLCP_TRACE_WARNING3(m,p1,p2,p3)          {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LLCP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_API0(m)                       {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_API, m);}
+#define LLCP_TRACE_API1(m,p1)                    {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1);}
+#define LLCP_TRACE_API2(m,p1,p2)                 {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2);}
+#define LLCP_TRACE_API3(m,p1,p2,p3)              {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define LLCP_TRACE_API4(m,p1,p2,p3,p4)           {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_EVENT0(m)                     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m);}
+#define LLCP_TRACE_EVENT1(m,p1)                  {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m, p1);}
+#define LLCP_TRACE_EVENT2(m,p1,p2)               {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LLCP_TRACE_EVENT3(m,p1,p2,p3)            {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LLCP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LLCP_TRACE_DEBUG0(m)                     {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m);}
+#define LLCP_TRACE_DEBUG1(m,p1)                  {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1);}
+#define LLCP_TRACE_DEBUG2(m,p1,p2)               {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LLCP_TRACE_DEBUG3(m,p1,p2,p3)            {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LLCP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define LLCP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LLCP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (llcp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_LLCP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the SDP unit
+*/
+#define SDP_TRACE_ERROR0(m)                     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m);}
+#define SDP_TRACE_ERROR1(m,p1)                  {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1);}
+#define SDP_TRACE_ERROR2(m,p1,p2)               {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SDP_TRACE_ERROR3(m,p1,p2,p3)            {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SDP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_WARNING0(m)                   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m);}
+#define SDP_TRACE_WARNING1(m,p1)                {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1);}
+#define SDP_TRACE_WARNING2(m,p1,p2)             {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SDP_TRACE_WARNING3(m,p1,p2,p3)          {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SDP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_API0(m)                       {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_API, m);}
+#define SDP_TRACE_API1(m,p1)                    {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1);}
+#define SDP_TRACE_API2(m,p1,p2)                 {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2);}
+#define SDP_TRACE_API3(m,p1,p2,p3)              {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SDP_TRACE_API4(m,p1,p2,p3,p4)           {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SDP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_EVENT0(m)                     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m);}
+#define SDP_TRACE_EVENT1(m,p1)                  {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m, p1);}
+#define SDP_TRACE_EVENT2(m,p1,p2)               {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SDP_TRACE_EVENT3(m,p1,p2,p3)            {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SDP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SDP_TRACE_DEBUG0(m)                     {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m);}
+#define SDP_TRACE_DEBUG1(m,p1)                  {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1);}
+#define SDP_TRACE_DEBUG2(m,p1,p2)               {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SDP_TRACE_DEBUG3(m,p1,p2,p3)            {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SDP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SDP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the RFCOMM unit
+*/
+#define RFCOMM_TRACE_ERROR0(m)                     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m);}
+#define RFCOMM_TRACE_ERROR1(m,p1)                  {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1);}
+#define RFCOMM_TRACE_ERROR2(m,p1,p2)               {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define RFCOMM_TRACE_ERROR3(m,p1,p2,p3)            {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define RFCOMM_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_WARNING0(m)                   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m);}
+#define RFCOMM_TRACE_WARNING1(m,p1)                {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1);}
+#define RFCOMM_TRACE_WARNING2(m,p1,p2)             {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define RFCOMM_TRACE_WARNING3(m,p1,p2,p3)          {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define RFCOMM_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_API0(m)                       {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m);}
+#define RFCOMM_TRACE_API1(m,p1)                    {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1);}
+#define RFCOMM_TRACE_API2(m,p1,p2)                 {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2);}
+#define RFCOMM_TRACE_API3(m,p1,p2,p3)              {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3);}
+#define RFCOMM_TRACE_API4(m,p1,p2,p3,p4)           {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_EVENT0(m)                     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m);}
+#define RFCOMM_TRACE_EVENT1(m,p1)                  {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m, p1);}
+#define RFCOMM_TRACE_EVENT2(m,p1,p2)               {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define RFCOMM_TRACE_EVENT3(m,p1,p2,p3)            {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define RFCOMM_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define RFCOMM_TRACE_DEBUG0(m)                     {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m);}
+#define RFCOMM_TRACE_DEBUG1(m,p1)                  {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1);}
+#define RFCOMM_TRACE_DEBUG2(m,p1,p2)               {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define RFCOMM_TRACE_DEBUG3(m,p1,p2,p3)            {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define RFCOMM_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define RFCOMM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define RFCOMM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_RFCOMM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for Serial Port Profile
+*/
+#define SPP_TRACE_ERROR0(m)                     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m);}
+#define SPP_TRACE_ERROR1(m,p1)                  {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1);}
+#define SPP_TRACE_ERROR2(m,p1,p2)               {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SPP_TRACE_ERROR3(m,p1,p2,p3)            {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SPP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_WARNING0(m)                   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m);}
+#define SPP_TRACE_WARNING1(m,p1)                {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1);}
+#define SPP_TRACE_WARNING2(m,p1,p2)             {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SPP_TRACE_WARNING3(m,p1,p2,p3)          {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SPP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (spp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_EVENT0(m)                     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m);}
+#define SPP_TRACE_EVENT1(m,p1)                  {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m, p1);}
+#define SPP_TRACE_EVENT2(m,p1,p2)               {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SPP_TRACE_EVENT3(m,p1,p2,p3)            {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SPP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_API0(m)                       {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_API, m);}
+#define SPP_TRACE_API1(m,p1)                    {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_API, m, p1);}
+#define SPP_TRACE_API2(m,p1,p2)                 {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2);}
+#define SPP_TRACE_API3(m,p1,p2,p3)              {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SPP_TRACE_API4(m,p1,p2,p3,p4)           {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SPP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SPP_TRACE_DEBUG0(m)                     {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m);}
+#define SPP_TRACE_DEBUG1(m,p1)                  {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1);}
+#define SPP_TRACE_DEBUG2(m,p1,p2)               {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SPP_TRACE_DEBUG3(m,p1,p2,p3)            {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SPP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (spp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Generic Access Profile traces */
+#define GAP_TRACE_ERROR0(m)                     {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m);}
+#define GAP_TRACE_ERROR1(m,p1)                  {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m, p1);}
+#define GAP_TRACE_ERROR2(m,p1,p2)               {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GAP_TRACE_ERROR3(m,p1,p2,p3)            {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GAP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_EVENT0(m)                     {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m);}
+#define GAP_TRACE_EVENT1(m,p1)                  {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m, p1);}
+#define GAP_TRACE_EVENT2(m,p1,p2)               {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GAP_TRACE_EVENT3(m,p1,p2,p3)            {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GAP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_API0(m)                       {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_API, m);}
+#define GAP_TRACE_API1(m,p1)                    {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_API, m, p1);}
+#define GAP_TRACE_API2(m,p1,p2)                 {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2);}
+#define GAP_TRACE_API3(m,p1,p2,p3)              {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GAP_TRACE_API4(m,p1,p2,p3,p4)           {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GAP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define GAP_TRACE_WARNING0(m)                   {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m);}
+#define GAP_TRACE_WARNING1(m,p1)                {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m, p1);}
+#define GAP_TRACE_WARNING2(m,p1,p2)             {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GAP_TRACE_WARNING3(m,p1,p2,p3)          {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GAP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_GAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for OBX
+*/
+#define OBX_TRACE_ERROR0(m)                      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m);}
+#define OBX_TRACE_ERROR1(m,p1)                   {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1);}
+#define OBX_TRACE_ERROR2(m,p1,p2)                {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2);}
+#define OBX_TRACE_ERROR3(m,p1,p2,p3)             {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define OBX_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define OBX_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_WARNING0(m)                    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m);}
+#define OBX_TRACE_WARNING1(m,p1)                 {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1);}
+#define OBX_TRACE_WARNING2(m,p1,p2)              {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2);}
+#define OBX_TRACE_WARNING3(m,p1,p2,p3)           {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define OBX_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define OBX_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (obx_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_EVENT0(m)                      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m);}
+#define OBX_TRACE_EVENT1(m,p1)                   {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m, p1);}
+#define OBX_TRACE_EVENT2(m,p1,p2)                {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2);}
+#define OBX_TRACE_EVENT3(m,p1,p2,p3)             {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define OBX_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define OBX_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_DEBUG0(m)                      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m);}
+#define OBX_TRACE_DEBUG1(m,p1)                   {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1);}
+#define OBX_TRACE_DEBUG2(m,p1,p2)                {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define OBX_TRACE_DEBUG3(m,p1,p2,p3)             {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define OBX_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define OBX_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (obx_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define OBX_TRACE_API0(m)                        {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_OBEX, TRACE_TYPE_API, m);}
+#define OBX_TRACE_API1(m,p1)                     {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_OBEX, TRACE_TYPE_API, m, p1);}
+#define OBX_TRACE_API2(m,p1,p2)                  {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2);}
+#define OBX_TRACE_API3(m,p1,p2,p3)               {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3);}
+#define OBX_TRACE_API4(m,p1,p2,p3,p4)            {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define OBX_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define OBX_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (obx_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_OBEX, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for OBEX application profiles
+*/
+#define GOEP_TRACE_ERROR0(m)                     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m);}
+#define GOEP_TRACE_ERROR1(m,p1)                  {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1);}
+#define GOEP_TRACE_ERROR2(m,p1,p2)               {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GOEP_TRACE_ERROR3(m,p1,p2,p3)            {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GOEP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_WARNING0(m)                   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m);}
+#define GOEP_TRACE_WARNING1(m,p1)                {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1);}
+#define GOEP_TRACE_WARNING2(m,p1,p2)             {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GOEP_TRACE_WARNING3(m,p1,p2,p3)          {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GOEP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (goep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_EVENT0(m)                     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m);}
+#define GOEP_TRACE_EVENT1(m,p1)                  {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m, p1);}
+#define GOEP_TRACE_EVENT2(m,p1,p2)               {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GOEP_TRACE_EVENT3(m,p1,p2,p3)            {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GOEP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_DEBUG0(m)                     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m);}
+#define GOEP_TRACE_DEBUG1(m,p1)                  {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1);}
+#define GOEP_TRACE_DEBUG2(m,p1,p2)               {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define GOEP_TRACE_DEBUG3(m,p1,p2,p3)            {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define GOEP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (goep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define GOEP_TRACE_API0(m)                       {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_GOEP, TRACE_TYPE_API, m);}
+#define GOEP_TRACE_API1(m,p1)                    {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_GOEP, TRACE_TYPE_API, m, p1);}
+#define GOEP_TRACE_API2(m,p1,p2)                 {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2);}
+#define GOEP_TRACE_API3(m,p1,p2,p3)              {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GOEP_TRACE_API4(m,p1,p2,p3,p4)           {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GOEP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GOEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (goep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_GOEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the BPP profile
+*/
+#define BPP_TRACE_ERROR0(m)                      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m);}
+#define BPP_TRACE_ERROR1(m,p1)                   {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1);}
+#define BPP_TRACE_ERROR2(m,p1,p2)                {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BPP_TRACE_ERROR3(m,p1,p2,p3)             {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BPP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_WARNING0(m)                    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m);}
+#define BPP_TRACE_WARNING1(m,p1)                 {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1);}
+#define BPP_TRACE_WARNING2(m,p1,p2)              {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BPP_TRACE_WARNING3(m,p1,p2,p3)           {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BPP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_EVENT0(m)                      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m);}
+#define BPP_TRACE_EVENT1(m,p1)                   {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m, p1);}
+#define BPP_TRACE_EVENT2(m,p1,p2)                {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BPP_TRACE_EVENT3(m,p1,p2,p3)             {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BPP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_DEBUG0(m)                      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m);}
+#define BPP_TRACE_DEBUG1(m,p1)                   {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1);}
+#define BPP_TRACE_DEBUG2(m,p1,p2)                {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BPP_TRACE_DEBUG3(m,p1,p2,p3)             {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BPP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define BPP_TRACE_API0(m)                        {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BPP, TRACE_TYPE_API, m);}
+#define BPP_TRACE_API1(m,p1)                     {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BPP, TRACE_TYPE_API, m, p1);}
+#define BPP_TRACE_API2(m,p1,p2)                  {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2);}
+#define BPP_TRACE_API3(m,p1,p2,p3)               {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BPP_TRACE_API4(m,p1,p2,p3,p4)            {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BPP_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (bpp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BPP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the BIP profile
+*/
+#define BIP_TRACE_ERROR0(m)                      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m);}
+#define BIP_TRACE_ERROR1(m,p1)                   {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1);}
+#define BIP_TRACE_ERROR2(m,p1,p2)                {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BIP_TRACE_ERROR3(m,p1,p2,p3)             {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BIP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BIP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_WARNING0(m)                    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m);}
+#define BIP_TRACE_WARNING1(m,p1)                 {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1);}
+#define BIP_TRACE_WARNING2(m,p1,p2)              {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BIP_TRACE_WARNING3(m,p1,p2,p3)           {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BIP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BIP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (bip_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_EVENT0(m)                      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m);}
+#define BIP_TRACE_EVENT1(m,p1)                   {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m, p1);}
+#define BIP_TRACE_EVENT2(m,p1,p2)                {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BIP_TRACE_EVENT3(m,p1,p2,p3)             {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BIP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BIP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_DEBUG0(m)                      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m);}
+#define BIP_TRACE_DEBUG1(m,p1)                   {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1);}
+#define BIP_TRACE_DEBUG2(m,p1,p2)                {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BIP_TRACE_DEBUG3(m,p1,p2,p3)             {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BIP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BIP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (bip_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define BIP_TRACE_API0(m)                        {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BIP, TRACE_TYPE_API, m);}
+#define BIP_TRACE_API1(m,p1)                     {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BIP, TRACE_TYPE_API, m, p1);}
+#define BIP_TRACE_API2(m,p1,p2)                  {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2);}
+#define BIP_TRACE_API3(m,p1,p2,p3)               {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BIP_TRACE_API4(m,p1,p2,p3,p4)            {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BIP_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BIP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (bip_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BIP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for TCS
+*/
+#define TCS_TRACE_ERROR0(m)                     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m);}
+#define TCS_TRACE_ERROR1(m,p1)                  {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1);}
+#define TCS_TRACE_ERROR2(m,p1,p2)               {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2);}
+#define TCS_TRACE_ERROR3(m,p1,p2,p3)            {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define TCS_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define TCS_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_WARNING0(m)                   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m);}
+#define TCS_TRACE_WARNING1(m,p1)                {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1);}
+#define TCS_TRACE_WARNING2(m,p1,p2)             {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2);}
+#define TCS_TRACE_WARNING3(m,p1,p2,p3)          {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define TCS_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define TCS_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_EVENT0(m)                     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m);}
+#define TCS_TRACE_EVENT1(m,p1)                  {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m, p1);}
+#define TCS_TRACE_EVENT2(m,p1,p2)               {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2);}
+#define TCS_TRACE_EVENT3(m,p1,p2,p3)            {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define TCS_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define TCS_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_DEBUG0(m)                     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m);}
+#define TCS_TRACE_DEBUG1(m,p1)                  {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1);}
+#define TCS_TRACE_DEBUG2(m,p1,p2)               {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define TCS_TRACE_DEBUG3(m,p1,p2,p3)            {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define TCS_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define TCS_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define TCS_TRACE_API0(m)                       {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_TCS, TRACE_TYPE_API, m);}
+#define TCS_TRACE_API1(m,p1)                    {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_TCS, TRACE_TYPE_API, m, p1);}
+#define TCS_TRACE_API2(m,p1,p2)                 {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2);}
+#define TCS_TRACE_API3(m,p1,p2,p3)              {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3);}
+#define TCS_TRACE_API4(m,p1,p2,p3,p4)           {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define TCS_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define TCS_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (tcs_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_TCS, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for ICP
+*/
+#define ICP_TRACE_ERROR0(m)                     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m);}
+#define ICP_TRACE_ERROR1(m,p1)                  {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1);}
+#define ICP_TRACE_ERROR2(m,p1,p2)               {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define ICP_TRACE_ERROR3(m,p1,p2,p3)            {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define ICP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define ICP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_WARNING0(m)                   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m);}
+#define ICP_TRACE_WARNING1(m,p1)                {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1);}
+#define ICP_TRACE_WARNING2(m,p1,p2)             {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define ICP_TRACE_WARNING3(m,p1,p2,p3)          {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define ICP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define ICP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (icp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_EVENT0(m)                     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m);}
+#define ICP_TRACE_EVENT1(m,p1)                  {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m, p1);}
+#define ICP_TRACE_EVENT2(m,p1,p2)               {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define ICP_TRACE_EVENT3(m,p1,p2,p3)            {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define ICP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define ICP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_DEBUG0(m)                     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m);}
+#define ICP_TRACE_DEBUG1(m,p1)                  {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1);}
+#define ICP_TRACE_DEBUG2(m,p1,p2)               {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define ICP_TRACE_DEBUG3(m,p1,p2,p3)            {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define ICP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define ICP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (icp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define ICP_TRACE_API0(m)                       {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_ICP, TRACE_TYPE_API, m);}
+#define ICP_TRACE_API1(m,p1)                    {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_ICP, TRACE_TYPE_API, m, p1);}
+#define ICP_TRACE_API2(m,p1,p2)                 {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2);}
+#define ICP_TRACE_API3(m,p1,p2,p3)              {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define ICP_TRACE_API4(m,p1,p2,p3,p4)           {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define ICP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define ICP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (icp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_ICP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* CTP */
+#define CTP_TRACE_ERROR0(m)                     {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m);}
+#define CTP_TRACE_ERROR1(m,p1)                  {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1);}
+#define CTP_TRACE_ERROR2(m,p1,p2)               {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CTP_TRACE_ERROR3(m,p1,p2,p3)            {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CTP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_WARNING0(m)                   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m);}
+#define CTP_TRACE_WARNING1(m,p1)                {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1);}
+#define CTP_TRACE_WARNING2(m,p1,p2)             {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CTP_TRACE_WARNING3(m,p1,p2,p3)          {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CTP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_EVENT0(m)                     {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m);}
+#define CTP_TRACE_EVENT1(m,p1)                  {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m, p1);}
+#define CTP_TRACE_EVENT2(m,p1,p2)               {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CTP_TRACE_EVENT3(m,p1,p2,p3)            {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CTP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CTP_TRACE_DEBUG0(m)                     {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m);}
+#define CTP_TRACE_DEBUG1(m,p1)                  {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1);}
+#define CTP_TRACE_DEBUG2(m,p1,p2)               {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CTP_TRACE_DEBUG3(m,p1,p2,p3)            {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CTP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ctp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* define traces for HID Host */
+#define HIDH_TRACE_ERROR0(m)                     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m);}
+#define HIDH_TRACE_ERROR1(m,p1)                  {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m, p1);}
+#define HIDH_TRACE_ERROR2(m,p1,p2)               {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HIDH_TRACE_ERROR3(m,p1,p2,p3)            {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HIDH_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_WARNING0(m)                   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m);}
+#define HIDH_TRACE_WARNING1(m,p1)                {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1);}
+#define HIDH_TRACE_WARNING2(m,p1,p2)             {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HIDH_TRACE_WARNING3(m,p1,p2,p3)          {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HIDH_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_API0(m)                       {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_API, m);}
+#define HIDH_TRACE_API1(m,p1)                    {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_API, m, p1);}
+#define HIDH_TRACE_API2(m,p1,p2)                 {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2);}
+#define HIDH_TRACE_API3(m,p1,p2,p3)              {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HIDH_TRACE_API4(m,p1,p2,p3,p4)           {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_EVENT0(m)                     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m);}
+#define HIDH_TRACE_EVENT1(m,p1)                  {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m, p1);}
+#define HIDH_TRACE_EVENT2(m,p1,p2)               {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HIDH_TRACE_EVENT3(m,p1,p2,p3)            {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HIDH_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDH_TRACE_DEBUG0(m)                     {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m);}
+#define HIDH_TRACE_DEBUG1(m,p1)                  {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1);}
+#define HIDH_TRACE_DEBUG2(m,p1,p2)               {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HIDH_TRACE_DEBUG3(m,p1,p2,p3)            {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HIDH_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HIDH_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HIDH_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hh_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for HID Device */
+#define HIDD_TRACE_ERROR0(m)                     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m);}
+#define HIDD_TRACE_ERROR1(m,p1)                  {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m, p1);}
+#define HIDD_TRACE_ERROR2(m,p1,p2)               {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HIDD_TRACE_ERROR3(m,p1,p2,p3)            {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HIDD_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_WARNING0(m)                   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m);}
+#define HIDD_TRACE_WARNING1(m,p1)                {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1);}
+#define HIDD_TRACE_WARNING2(m,p1,p2)             {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HIDD_TRACE_WARNING3(m,p1,p2,p3)          {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HIDD_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hd_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_API0(m)                       {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_API, m);}
+#define HIDD_TRACE_API1(m,p1)                    {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_API, m, p1);}
+#define HIDD_TRACE_API2(m,p1,p2)                 {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2);}
+#define HIDD_TRACE_API3(m,p1,p2,p3)              {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HIDD_TRACE_API4(m,p1,p2,p3,p4)           {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_EVENT0(m)                     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m);}
+#define HIDD_TRACE_EVENT1(m,p1)                  {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m, p1);}
+#define HIDD_TRACE_EVENT2(m,p1,p2)               {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HIDD_TRACE_EVENT3(m,p1,p2,p3)            {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HIDD_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HIDD_TRACE_DEBUG0(m)                     {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m);}
+#define HIDD_TRACE_DEBUG1(m,p1)                  {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1);}
+#define HIDD_TRACE_DEBUG2(m,p1,p2)               {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HIDD_TRACE_DEBUG3(m,p1,p2,p3)            {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HIDD_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HIDD_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HIDD_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hd_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for headset profile */
+#define HSP2_TRACE_ERROR0(pcb,m)                     {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m);}
+#define HSP2_TRACE_ERROR1(pcb,m,p1)                  {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m, p1);}
+#define HSP2_TRACE_ERROR2(pcb,m,p1,p2)               {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HSP2_TRACE_ERROR3(pcb,m,p1,p2,p3)            {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HSP2_TRACE_ERROR4(pcb,m,p1,p2,p3,p4)         {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_ERROR5(pcb,m,p1,p2,p3,p4,p5)      {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_ERROR6(pcb,m,p1,p2,p3,p4,p5,p6)   {if (pcb->trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_WARNING0(pcb,m)                   {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m);}
+#define HSP2_TRACE_WARNING1(pcb,m,p1)                {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1);}
+#define HSP2_TRACE_WARNING2(pcb,m,p1,p2)             {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HSP2_TRACE_WARNING3(pcb,m,p1,p2,p3)          {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HSP2_TRACE_WARNING4(pcb,m,p1,p2,p3,p4)       {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_WARNING5(pcb,m,p1,p2,p3,p4,p5)    {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_WARNING6(pcb,m,p1,p2,p3,p4,p5,p6) {if (pcb->trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_API0(pcb,m)                       {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_API, m);}
+#define HSP2_TRACE_API1(pcb,m,p1)                    {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_API, m, p1);}
+#define HSP2_TRACE_API2(pcb,m,p1,p2)                 {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2);}
+#define HSP2_TRACE_API3(pcb,m,p1,p2,p3)              {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HSP2_TRACE_API4(pcb,m,p1,p2,p3,p4)           {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_API5(pcb,m,p1,p2,p3,p4,p5)        {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_API6(pcb,m,p1,p2,p3,p4,p5,p6)     {if (pcb->trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_EVENT0(pcb,m)                     {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m);}
+#define HSP2_TRACE_EVENT1(pcb,m,p1)                  {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m, p1);}
+#define HSP2_TRACE_EVENT2(pcb,m,p1,p2)               {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HSP2_TRACE_EVENT3(pcb,m,p1,p2,p3)            {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HSP2_TRACE_EVENT4(pcb,m,p1,p2,p3,p4)         {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_EVENT5(pcb,m,p1,p2,p3,p4,p5)      {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_EVENT6(pcb,m,p1,p2,p3,p4,p5,p6)   {if (pcb->trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HSP2_TRACE_DEBUG0(pcb,m)                     {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m);}
+#define HSP2_TRACE_DEBUG1(pcb,m,p1)                  {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1);}
+#define HSP2_TRACE_DEBUG2(pcb,m,p1,p2)               {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HSP2_TRACE_DEBUG3(pcb,m,p1,p2,p3)            {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HSP2_TRACE_DEBUG4(pcb,m,p1,p2,p3,p4)         {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HSP2_TRACE_DEBUG5(pcb,m,p1,p2,p3,p4,p5)      {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HSP2_TRACE_DEBUG6(pcb,m,p1,p2,p3,p4,p5,p6)   {if (pcb->trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HSP2, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m)                     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m);}
+#define NFC_TRACE_ERROR1(m,p1)                  {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1);}
+#define NFC_TRACE_ERROR2(m,p1,p2)               {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NFC_TRACE_ERROR3(m,p1,p2,p3)            {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NFC_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NFC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_WARNING0(m)                   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m);}
+#define NFC_TRACE_WARNING1(m,p1)                {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1);}
+#define NFC_TRACE_WARNING2(m,p1,p2)             {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NFC_TRACE_WARNING3(m,p1,p2,p3)          {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NFC_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NFC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_API0(m)                       {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_API, m);}
+#define NFC_TRACE_API1(m,p1)                    {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1);}
+#define NFC_TRACE_API2(m,p1,p2)                 {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2);}
+#define NFC_TRACE_API3(m,p1,p2,p3)              {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NFC_TRACE_API4(m,p1,p2,p3,p4)           {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NFC_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_EVENT0(m)                     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m);}
+#define NFC_TRACE_EVENT1(m,p1)                  {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m, p1);}
+#define NFC_TRACE_EVENT2(m,p1,p2)               {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NFC_TRACE_EVENT3(m,p1,p2,p3)            {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NFC_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NFC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFC_TRACE_DEBUG0(m)                     {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m);}
+#define NFC_TRACE_DEBUG1(m,p1)                  {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1);}
+#define NFC_TRACE_DEBUG2(m,p1,p2)               {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NFC_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NFC_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NFC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NFC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NFC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_ERROR0(m)                     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m);}
+#define NCI_TRACE_ERROR1(m,p1)                  {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1);}
+#define NCI_TRACE_ERROR2(m,p1,p2)               {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)            {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_WARNING0(m)                   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m);}
+#define NCI_TRACE_WARNING1(m,p1)                {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1);}
+#define NCI_TRACE_WARNING2(m,p1,p2)             {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)          {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_API0(m)                       {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_API, m);}
+#define NCI_TRACE_API1(m,p1)                    {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1);}
+#define NCI_TRACE_API2(m,p1,p2)                 {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2);}
+#define NCI_TRACE_API3(m,p1,p2,p3)              {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)           {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_EVENT0(m)                     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m);}
+#define NCI_TRACE_EVENT1(m,p1)                  {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m, p1);}
+#define NCI_TRACE_EVENT2(m,p1,p2)               {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)            {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NCI_TRACE_DEBUG0(m)                     {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m);}
+#define NCI_TRACE_DEBUG1(m,p1)                  {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1);}
+#define NCI_TRACE_DEBUG2(m,p1,p2)               {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)            {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ncit_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NCI, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_ERROR0(m)                     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m);}
+#define RW_TRACE_ERROR1(m,p1)                  {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1);}
+#define RW_TRACE_ERROR2(m,p1,p2)               {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2);}
+#define RW_TRACE_ERROR3(m,p1,p2,p3)            {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define RW_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define RW_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_WARNING0(m)                   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m);}
+#define RW_TRACE_WARNING1(m,p1)                {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1);}
+#define RW_TRACE_WARNING2(m,p1,p2)             {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2);}
+#define RW_TRACE_WARNING3(m,p1,p2,p3)          {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define RW_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define RW_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (rw_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_API0(m)                       {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_API, m);}
+#define RW_TRACE_API1(m,p1)                    {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1);}
+#define RW_TRACE_API2(m,p1,p2)                 {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2);}
+#define RW_TRACE_API3(m,p1,p2,p3)              {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3);}
+#define RW_TRACE_API4(m,p1,p2,p3,p4)           {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define RW_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_EVENT0(m)                     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m);}
+#define RW_TRACE_EVENT1(m,p1)                  {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m, p1);}
+#define RW_TRACE_EVENT2(m,p1,p2)               {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2);}
+#define RW_TRACE_EVENT3(m,p1,p2,p3)            {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define RW_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define RW_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define RW_TRACE_DEBUG0(m)                     {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m);}
+#define RW_TRACE_DEBUG1(m,p1)                  {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1);}
+#define RW_TRACE_DEBUG2(m,p1,p2)               {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define RW_TRACE_DEBUG3(m,p1,p2,p3)            {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define RW_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define RW_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define RW_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (rw_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_RW, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_ERROR0(m)                     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m);}
+#define CE_TRACE_ERROR1(m,p1)                  {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1);}
+#define CE_TRACE_ERROR2(m,p1,p2)               {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CE_TRACE_ERROR3(m,p1,p2,p3)            {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CE_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CE_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_WARNING0(m)                   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m);}
+#define CE_TRACE_WARNING1(m,p1)                {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1);}
+#define CE_TRACE_WARNING2(m,p1,p2)             {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CE_TRACE_WARNING3(m,p1,p2,p3)          {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CE_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CE_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ce_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_API0(m)                       {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_API, m);}
+#define CE_TRACE_API1(m,p1)                    {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1);}
+#define CE_TRACE_API2(m,p1,p2)                 {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2);}
+#define CE_TRACE_API3(m,p1,p2,p3)              {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3);}
+#define CE_TRACE_API4(m,p1,p2,p3,p4)           {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define CE_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_EVENT0(m)                     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m);}
+#define CE_TRACE_EVENT1(m,p1)                  {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m, p1);}
+#define CE_TRACE_EVENT2(m,p1,p2)               {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CE_TRACE_EVENT3(m,p1,p2,p3)            {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CE_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CE_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CE_TRACE_DEBUG0(m)                     {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m);}
+#define CE_TRACE_DEBUG1(m,p1)                  {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1);}
+#define CE_TRACE_DEBUG2(m,p1,p2)               {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CE_TRACE_DEBUG3(m,p1,p2,p3)            {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CE_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CE_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CE_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ce_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CE, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_ERROR0(m)                     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m);}
+#define NDEF_TRACE_ERROR1(m,p1)                  {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1);}
+#define NDEF_TRACE_ERROR2(m,p1,p2)               {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NDEF_TRACE_ERROR3(m,p1,p2,p3)            {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NDEF_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_WARNING0(m)                   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m);}
+#define NDEF_TRACE_WARNING1(m,p1)                {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1);}
+#define NDEF_TRACE_WARNING2(m,p1,p2)             {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NDEF_TRACE_WARNING3(m,p1,p2,p3)          {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NDEF_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_API0(m)                       {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_API, m);}
+#define NDEF_TRACE_API1(m,p1)                    {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1);}
+#define NDEF_TRACE_API2(m,p1,p2)                 {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2);}
+#define NDEF_TRACE_API3(m,p1,p2,p3)              {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NDEF_TRACE_API4(m,p1,p2,p3,p4)           {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_EVENT0(m)                     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m);}
+#define NDEF_TRACE_EVENT1(m,p1)                  {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m, p1);}
+#define NDEF_TRACE_EVENT2(m,p1,p2)               {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NDEF_TRACE_EVENT3(m,p1,p2,p3)            {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NDEF_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NDEF_TRACE_DEBUG0(m)                     {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m);}
+#define NDEF_TRACE_DEBUG1(m,p1)                  {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1);}
+#define NDEF_TRACE_DEBUG2(m,p1,p2)               {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NDEF_TRACE_DEBUG3(m,p1,p2,p3)            {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NDEF_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NDEF_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NDEF_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (ndef_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NDEF, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m)                     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m);}
+#define NFA_TRACE_ERROR1(m,p1)                  {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1);}
+#define NFA_TRACE_ERROR2(m,p1,p2)               {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2);}
+#define NFA_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define NFA_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define NFA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_WARNING0(m)                   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m);}
+#define NFA_TRACE_WARNING1(m,p1)                {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1);}
+#define NFA_TRACE_WARNING2(m,p1,p2)             {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2);}
+#define NFA_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define NFA_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define NFA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_API0(m)                       {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_API, m);}
+#define NFA_TRACE_API1(m,p1)                    {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1);}
+#define NFA_TRACE_API2(m,p1,p2)                 {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2);}
+#define NFA_TRACE_API3(m,p1,p2,p3)              {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3);}
+#define NFA_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define NFA_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_EVENT0(m)                     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m);}
+#define NFA_TRACE_EVENT1(m,p1)                  {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m, p1);}
+#define NFA_TRACE_EVENT2(m,p1,p2)               {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2);}
+#define NFA_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define NFA_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define NFA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define NFA_TRACE_DEBUG0(m)                     {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m);}
+#define NFA_TRACE_DEBUG1(m,p1)                  {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1);}
+#define NFA_TRACE_DEBUG2(m,p1,p2)               {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define NFA_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define NFA_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define NFA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define NFA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_sys_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_NFA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m)                     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m);}
+#define P2P_TRACE_ERROR1(m,p1)                  {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1);}
+#define P2P_TRACE_ERROR2(m,p1,p2)               {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2);}
+#define P2P_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define P2P_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define P2P_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_WARNING0(m)                   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m);}
+#define P2P_TRACE_WARNING1(m,p1)                {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1);}
+#define P2P_TRACE_WARNING2(m,p1,p2)             {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2);}
+#define P2P_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define P2P_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define P2P_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_API0(m)                       {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_API, m);}
+#define P2P_TRACE_API1(m,p1)                    {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1);}
+#define P2P_TRACE_API2(m,p1,p2)                 {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2);}
+#define P2P_TRACE_API3(m,p1,p2,p3)              {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3);}
+#define P2P_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define P2P_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_EVENT0(m)                     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m);}
+#define P2P_TRACE_EVENT1(m,p1)                  {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m, p1);}
+#define P2P_TRACE_EVENT2(m,p1,p2)               {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2);}
+#define P2P_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define P2P_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define P2P_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define P2P_TRACE_DEBUG0(m)                     {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m);}
+#define P2P_TRACE_DEBUG1(m,p1)                  {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1);}
+#define P2P_TRACE_DEBUG2(m,p1,p2)               {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define P2P_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define P2P_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define P2P_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define P2P_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_p2p_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_P2P, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA CHO unit
+*/
+#define CHO_TRACE_ERROR0(m)                     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m);}
+#define CHO_TRACE_ERROR1(m,p1)                  {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1);}
+#define CHO_TRACE_ERROR2(m,p1,p2)               {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2);}
+#define CHO_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define CHO_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define CHO_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_WARNING0(m)                   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m);}
+#define CHO_TRACE_WARNING1(m,p1)                {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1);}
+#define CHO_TRACE_WARNING2(m,p1,p2)             {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2);}
+#define CHO_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define CHO_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define CHO_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_API0(m)                       {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_API, m);}
+#define CHO_TRACE_API1(m,p1)                    {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1);}
+#define CHO_TRACE_API2(m,p1,p2)                 {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2);}
+#define CHO_TRACE_API3(m,p1,p2,p3)              {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3);}
+#define CHO_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define CHO_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_EVENT0(m)                     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m);}
+#define CHO_TRACE_EVENT1(m,p1)                  {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m, p1);}
+#define CHO_TRACE_EVENT2(m,p1,p2)               {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2);}
+#define CHO_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define CHO_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define CHO_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define CHO_TRACE_DEBUG0(m)                     {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m);}
+#define CHO_TRACE_DEBUG1(m,p1)                  {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1);}
+#define CHO_TRACE_DEBUG2(m,p1,p2)               {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define CHO_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define CHO_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define CHO_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define CHO_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_cho_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_CHO, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the NFA SNEP unit
+*/
+#define SNEP_TRACE_ERROR0(m)                     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m);}
+#define SNEP_TRACE_ERROR1(m,p1)                  {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1);}
+#define SNEP_TRACE_ERROR2(m,p1,p2)               {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SNEP_TRACE_ERROR3(m,p1,p2,p3)            {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SNEP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_WARNING0(m)                   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m);}
+#define SNEP_TRACE_WARNING1(m,p1)                {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1);}
+#define SNEP_TRACE_WARNING2(m,p1,p2)             {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SNEP_TRACE_WARNING3(m,p1,p2,p3)          {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SNEP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_API0(m)                       {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_API, m);}
+#define SNEP_TRACE_API1(m,p1)                    {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1);}
+#define SNEP_TRACE_API2(m,p1,p2)                 {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2);}
+#define SNEP_TRACE_API3(m,p1,p2,p3)              {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SNEP_TRACE_API4(m,p1,p2,p3,p4)           {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_EVENT0(m)                     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m);}
+#define SNEP_TRACE_EVENT1(m,p1)                  {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m, p1);}
+#define SNEP_TRACE_EVENT2(m,p1,p2)               {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SNEP_TRACE_EVENT3(m,p1,p2,p3)            {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SNEP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SNEP_TRACE_DEBUG0(m)                     {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m);}
+#define SNEP_TRACE_DEBUG1(m,p1)                  {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1);}
+#define SNEP_TRACE_DEBUG2(m,p1,p2)               {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SNEP_TRACE_DEBUG3(m,p1,p2,p3)            {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (nfa_snep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define MMI_TRACE_0(m)
+#define MMI_TRACE_1(m,p1)
+#define MMI_TRACE_2(m,p1,p2)
+#define MMI_TRACE_3(m,p1,p2,p3)
+#define MMI_TRACE_4(m,p1,p2,p3,p4)
+#define MMI_TRACE_5(m,p1,p2,p3,p4,p5)
+#define MMI_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_DEBUG_0(m)                           BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m)
+#define MMI_DEBUG_1(m,p1)                        BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1)
+#define MMI_DEBUG_2(m,p1,p2)                     BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2)
+#define MMI_DEBUG_3(m,p1,p2,p3)                  BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3)
+#define MMI_DEBUG_4(m,p1,p2,p3,p4)               BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4)
+#define MMI_DEBUG_5(m,p1,p2,p3,p4,p5)            BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5)
+#define MMI_DEBUG_6(m,p1,p2,p3,p4,p5,p6)         BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_WARNING_0(m)                         BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m)
+#define MMI_WARNING_1(m,p1)                      BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1)
+#define MMI_WARNING_2(m,p1,p2)                   BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2)
+#define MMI_WARNING_3(m,p1,p2,p3)                BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3)
+#define MMI_WARNING_4(m,p1,p2,p3,p4)             BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4)
+#define MMI_WARNING_5(m,p1,p2,p3,p4,p5)          BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5)
+#define MMI_WARNING_6(m,p1,p2,p3,p4,p5,p6)       BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6)
+
+#define MMI_ERROR_0(m)                           BT_TRACE_0(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m)
+#define MMI_ERROR_1(m,p1)                        BT_TRACE_1(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1)
+#define MMI_ERROR_2(m,p1,p2)                     BT_TRACE_2(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2)
+#define MMI_ERROR_3(m,p1,p2,p3)                  BT_TRACE_3(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3)
+#define MMI_ERROR_4(m,p1,p2,p3,p4)               BT_TRACE_4(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4)
+#define MMI_ERROR_5(m,p1,p2,p3,p4,p5)            BT_TRACE_5(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5)
+#define MMI_ERROR_6(m,p1,p2,p3,p4,p5,p6)         BT_TRACE_6(TRACE_LAYER_HID, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6)
+
+#define TAK_TRACE_0(m)                            MMI_Echo(m)
+
+/* hid mouse module traces */
+
+#define MSKB_TRACE_0(m)                         MMI_Echo(m)
+#define MSKB_TRACE_1(m,p1)                      MMI_Echo(m,p1)
+#define MSKB_TRACE_2(m,p1,p2)                   MMI_Echo(m,p1,p2)
+#define MSKB_TRACE_3(m,p1,p2,p3)                MMI_Echo(m,p1,p2,p3)
+#define MSKB_TRACE_4(m,p1,p2,p3,p4)             MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_TRACE_5(m,p1,p2,p3,p4,p5)          MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_TRACE_6(m,p1,p2,p3,p4,p5,p6)       MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_DEBUG_0(m)                         MMI_Echo(m)
+#define MSKB_DEBUG_1(m,p1)                      MMI_Echo(m,p1)
+#define MSKB_DEBUG_2(m,p1,p2)                   MMI_Echo(m,p1,p2)
+#define MSKB_DEBUG_3(m,p1,p2,p3)                MMI_Echo(m,p1,p2,p3)
+#define MSKB_DEBUG_4(m,p1,p2,p3,p4)             MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_DEBUG_5(m,p1,p2,p3,p4,p5)          MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_DEBUG_6(m,p1,p2,p3,p4,p5,p6)       MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_ERROR_0(m)                         MMI_Echo(m)
+#define MSKB_ERROR_1(m,p1)                      MMI_Echo(m,p1)
+#define MSKB_ERROR_2(m,p1,p2)                   MMI_Echo(m,p1,p2)
+#define MSKB_ERROR_3(m,p1,p2,p3)                MMI_Echo(m,p1,p2,p3)
+#define MSKB_ERROR_4(m,p1,p2,p3,p4)             MMI_Echo(m,p1,p2,p3,p4)
+#define MSKB_ERROR_5(m,p1,p2,p3,p4,p5)          MMI_Echo(m,p1,p2,p3,p4,p5)
+#define MSKB_ERROR_6(m,p1,p2,p3,p4,p5,p6)       MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for DUN */
+
+#define DUN_TRACE_ERROR0(m)                     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m);}
+#define DUN_TRACE_ERROR1(m,p1)                  {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m, p1);}
+#define DUN_TRACE_ERROR2(m,p1,p2)               {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2);}
+#define DUN_TRACE_ERROR3(m,p1,p2,p3)            {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define DUN_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define DUN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_WARNING0(m)                   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m);}
+#define DUN_TRACE_WARNING1(m,p1)                {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1);}
+#define DUN_TRACE_WARNING2(m,p1,p2)             {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2);}
+#define DUN_TRACE_WARNING3(m,p1,p2,p3)          {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define DUN_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define DUN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (dun_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_API0(m)                       {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_API, m);}
+#define DUN_TRACE_API1(m,p1)                    {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_API, m, p1);}
+#define DUN_TRACE_API2(m,p1,p2)                 {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2);}
+#define DUN_TRACE_API3(m,p1,p2,p3)              {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3);}
+#define DUN_TRACE_API4(m,p1,p2,p3,p4)           {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define DUN_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_EVENT0(m)                     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m);}
+#define DUN_TRACE_EVENT1(m,p1)                  {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m, p1);}
+#define DUN_TRACE_EVENT2(m,p1,p2)               {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2);}
+#define DUN_TRACE_EVENT3(m,p1,p2,p3)            {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define DUN_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define DUN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define DUN_TRACE_DEBUG0(m)                     {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m);}
+#define DUN_TRACE_DEBUG1(m,p1)                  {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1);}
+#define DUN_TRACE_DEBUG2(m,p1,p2)               {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define DUN_TRACE_DEBUG3(m,p1,p2,p3)            {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define DUN_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define DUN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define DUN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (dun_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_DUN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for hardcopy cable replacement profile */
+
+#define HCRP_TRACE_ERROR0(m)                     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m);}
+#define HCRP_TRACE_ERROR1(m,p1)                  {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m, p1);}
+#define HCRP_TRACE_ERROR2(m,p1,p2)               {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCRP_TRACE_ERROR3(m,p1,p2,p3)            {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCRP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_WARNING0(m)                   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m);}
+#define HCRP_TRACE_WARNING1(m,p1)                {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1);}
+#define HCRP_TRACE_WARNING2(m,p1,p2)             {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCRP_TRACE_WARNING3(m,p1,p2,p3)          {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCRP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_API0(m)                       {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_API, m);}
+#define HCRP_TRACE_API1(m,p1)                    {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_API, m, p1);}
+#define HCRP_TRACE_API2(m,p1,p2)                 {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2);}
+#define HCRP_TRACE_API3(m,p1,p2,p3)              {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HCRP_TRACE_API4(m,p1,p2,p3,p4)           {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_EVENT0(m)                     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m);}
+#define HCRP_TRACE_EVENT1(m,p1)                  {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m, p1);}
+#define HCRP_TRACE_EVENT2(m,p1,p2)               {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCRP_TRACE_EVENT3(m,p1,p2,p3)            {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCRP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRP_TRACE_DEBUG0(m)                     {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m);}
+#define HCRP_TRACE_DEBUG1(m,p1)                  {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1);}
+#define HCRP_TRACE_DEBUG2(m,p1,p2)               {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCRP_TRACE_DEBUG3(m,p1,p2,p3)            {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCRP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCRP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCRP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hcrp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for multi-client server hardcopy cable replacement profile */
+
+#define HCRPM_TRACE_ERROR0(m)                     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m);}
+#define HCRPM_TRACE_ERROR1(m,p1)                  {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m, p1);}
+#define HCRPM_TRACE_ERROR2(m,p1,p2)               {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define HCRPM_TRACE_ERROR3(m,p1,p2,p3)            {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define HCRPM_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_WARNING0(m)                   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m);}
+#define HCRPM_TRACE_WARNING1(m,p1)                {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1);}
+#define HCRPM_TRACE_WARNING2(m,p1,p2)             {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define HCRPM_TRACE_WARNING3(m,p1,p2,p3)          {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define HCRPM_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_API0(m)                       {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_API, m);}
+#define HCRPM_TRACE_API1(m,p1)                    {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_API, m, p1);}
+#define HCRPM_TRACE_API2(m,p1,p2)                 {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2);}
+#define HCRPM_TRACE_API3(m,p1,p2,p3)              {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define HCRPM_TRACE_API4(m,p1,p2,p3,p4)           {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_EVENT0(m)                     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m);}
+#define HCRPM_TRACE_EVENT1(m,p1)                  {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m, p1);}
+#define HCRPM_TRACE_EVENT2(m,p1,p2)               {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define HCRPM_TRACE_EVENT3(m,p1,p2,p3)            {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define HCRPM_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define HCRPM_TRACE_DEBUG0(m)                     {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m);}
+#define HCRPM_TRACE_DEBUG1(m,p1)                  {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1);}
+#define HCRPM_TRACE_DEBUG2(m,p1,p2)               {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define HCRPM_TRACE_DEBUG3(m,p1,p2,p3)            {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define HCRPM_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define HCRPM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define HCRPM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (hcrpm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_HCRP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for RPC */
+
+#define RPC_TRACE_ERROR0(m)                      {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, (m));}
+#define RPC_TRACE_ERROR1(m,p1)                   {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_ERROR2(m,p1,p2)                {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_ERROR3(m,p1,p2,p3)             {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (rpc_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_WARNING0(m)                    {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, (m));}
+#define RPC_TRACE_WARNING1(m,p1)                 {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_WARNING2(m,p1,p2)              {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_WARNING3(m,p1,p2,p3)           {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (rpc_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_API0(m)                        {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, (m));}
+#define RPC_TRACE_API1(m,p1)                     {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_API2(m,p1,p2)                  {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_API3(m,p1,p2,p3)               {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_API4(m,p1,p2,p3,p4)            {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (rpc_trace_level >= BT_TRACE_LEVEL_API) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_EVENT0(m)                      {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, (m));}
+#define RPC_TRACE_EVENT1(m,p1)                   {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_EVENT2(m,p1,p2)                {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_EVENT3(m,p1,p2,p3)             {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (rpc_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define RPC_TRACE_DEBUG0(m)                      {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, (m));}
+#define RPC_TRACE_DEBUG1(m,p1)                   {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1));}
+#define RPC_TRACE_DEBUG2(m,p1,p2)                {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define RPC_TRACE_DEBUG3(m,p1,p2,p3)             {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define RPC_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define RPC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define RPC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (rpc_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_RPC | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+/* define traces for BNEP */
+
+#define BNEP_TRACE_ERROR0(m)                     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m);}
+#define BNEP_TRACE_ERROR1(m,p1)                  {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m, p1);}
+#define BNEP_TRACE_ERROR2(m,p1,p2)               {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define BNEP_TRACE_ERROR3(m,p1,p2,p3)            {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define BNEP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_WARNING0(m)                   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m);}
+#define BNEP_TRACE_WARNING1(m,p1)                {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1);}
+#define BNEP_TRACE_WARNING2(m,p1,p2)             {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define BNEP_TRACE_WARNING3(m,p1,p2,p3)          {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define BNEP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_API0(m)                       {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_API, m);}
+#define BNEP_TRACE_API1(m,p1)                    {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_API, m, p1);}
+#define BNEP_TRACE_API2(m,p1,p2)                 {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2);}
+#define BNEP_TRACE_API3(m,p1,p2,p3)              {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define BNEP_TRACE_API4(m,p1,p2,p3,p4)           {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_EVENT0(m)                     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m);}
+#define BNEP_TRACE_EVENT1(m,p1)                  {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m, p1);}
+#define BNEP_TRACE_EVENT2(m,p1,p2)               {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define BNEP_TRACE_EVENT3(m,p1,p2,p3)            {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define BNEP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define BNEP_TRACE_DEBUG0(m)                     {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m);}
+#define BNEP_TRACE_DEBUG1(m,p1)                  {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1);}
+#define BNEP_TRACE_DEBUG2(m,p1,p2)               {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define BNEP_TRACE_DEBUG3(m,p1,p2,p3)            {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define BNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define BNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define BNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (bnep_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_BNEP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for PAN */
+
+#define PAN_TRACE_ERROR0(m)                     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m);}
+#define PAN_TRACE_ERROR1(m,p1)                  {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m, p1);}
+#define PAN_TRACE_ERROR2(m,p1,p2)               {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2);}
+#define PAN_TRACE_ERROR3(m,p1,p2,p3)            {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define PAN_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define PAN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_WARNING0(m)                   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m);}
+#define PAN_TRACE_WARNING1(m,p1)                {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1);}
+#define PAN_TRACE_WARNING2(m,p1,p2)             {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2);}
+#define PAN_TRACE_WARNING3(m,p1,p2,p3)          {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define PAN_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define PAN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (pan_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_API0(m)                       {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_API, m);}
+#define PAN_TRACE_API1(m,p1)                    {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_API, m, p1);}
+#define PAN_TRACE_API2(m,p1,p2)                 {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2);}
+#define PAN_TRACE_API3(m,p1,p2,p3)              {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3);}
+#define PAN_TRACE_API4(m,p1,p2,p3,p4)           {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define PAN_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_EVENT0(m)                     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m);}
+#define PAN_TRACE_EVENT1(m,p1)                  {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m, p1);}
+#define PAN_TRACE_EVENT2(m,p1,p2)               {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2);}
+#define PAN_TRACE_EVENT3(m,p1,p2,p3)            {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define PAN_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define PAN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define PAN_TRACE_DEBUG0(m)                     {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m);}
+#define PAN_TRACE_DEBUG1(m,p1)                  {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1);}
+#define PAN_TRACE_DEBUG2(m,p1,p2)               {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define PAN_TRACE_DEBUG3(m,p1,p2,p3)            {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define PAN_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define PAN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define PAN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (pan_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_PAN, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* define traces for SIM */
+
+#define SAP_TRACE_ERROR0(m)                     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m);}
+#define SAP_TRACE_ERROR1(m,p1)                  {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m, p1);}
+#define SAP_TRACE_ERROR2(m,p1,p2)               {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SAP_TRACE_ERROR3(m,p1,p2,p3)            {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SAP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_WARNING0(m)                   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m);}
+#define SAP_TRACE_WARNING1(m,p1)                {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1);}
+#define SAP_TRACE_WARNING2(m,p1,p2)             {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SAP_TRACE_WARNING3(m,p1,p2,p3)          {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SAP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sap_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_API0(m)                       {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_API, m);}
+#define SAP_TRACE_API1(m,p1)                    {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_API, m, p1);}
+#define SAP_TRACE_API2(m,p1,p2)                 {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2);}
+#define SAP_TRACE_API3(m,p1,p2,p3)              {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SAP_TRACE_API4(m,p1,p2,p3,p4)           {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SAP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_EVENT0(m)                     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m);}
+#define SAP_TRACE_EVENT1(m,p1)                  {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m, p1);}
+#define SAP_TRACE_EVENT2(m,p1,p2)               {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SAP_TRACE_EVENT3(m,p1,p2,p3)            {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SAP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SAP_TRACE_DEBUG0(m)                     {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m);}
+#define SAP_TRACE_DEBUG1(m,p1)                  {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1);}
+#define SAP_TRACE_DEBUG2(m,p1,p2)               {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SAP_TRACE_DEBUG3(m,p1,p2,p3)            {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SAP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (sap_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SAP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for OPP profile
+*/
+#define OPP_TRACE_ERROR0(m)                      {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m);}
+#define OPP_TRACE_ERROR1(m,p1)                   {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1);}
+#define OPP_TRACE_ERROR2(m,p1,p2)                {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define OPP_TRACE_ERROR3(m,p1,p2,p3)             {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define OPP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define OPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_WARNING0(m)                    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m);}
+#define OPP_TRACE_WARNING1(m,p1)                 {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1);}
+#define OPP_TRACE_WARNING2(m,p1,p2)              {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define OPP_TRACE_WARNING3(m,p1,p2,p3)           {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define OPP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define OPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (opp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_EVENT0(m)                      {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m);}
+#define OPP_TRACE_EVENT1(m,p1)                   {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m, p1);}
+#define OPP_TRACE_EVENT2(m,p1,p2)                {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define OPP_TRACE_EVENT3(m,p1,p2,p3)             {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define OPP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define OPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define OPP_TRACE_DEBUG0(m)                      {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m);}
+#define OPP_TRACE_DEBUG1(m,p1)                   {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1);}
+#define OPP_TRACE_DEBUG2(m,p1,p2)                {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define OPP_TRACE_DEBUG3(m,p1,p2,p3)             {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define OPP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define OPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define OPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (opp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_OPP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for FTP profile
+*/
+#define FTP_TRACE_ERROR0(m)                      {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m);}
+#define FTP_TRACE_ERROR1(m,p1)                   {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1);}
+#define FTP_TRACE_ERROR2(m,p1,p2)                {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define FTP_TRACE_ERROR3(m,p1,p2,p3)             {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define FTP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define FTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_WARNING0(m)                    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m);}
+#define FTP_TRACE_WARNING1(m,p1)                 {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1);}
+#define FTP_TRACE_WARNING2(m,p1,p2)              {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define FTP_TRACE_WARNING3(m,p1,p2,p3)           {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define FTP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define FTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_EVENT0(m)                      {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m);}
+#define FTP_TRACE_EVENT1(m,p1)                   {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m, p1);}
+#define FTP_TRACE_EVENT2(m,p1,p2)                {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define FTP_TRACE_EVENT3(m,p1,p2,p3)             {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define FTP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define FTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define FTP_TRACE_DEBUG0(m)                      {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m);}
+#define FTP_TRACE_DEBUG1(m,p1)                   {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1);}
+#define FTP_TRACE_DEBUG2(m,p1,p2)                {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define FTP_TRACE_DEBUG3(m,p1,p2,p3)             {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define FTP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define FTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define FTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (ftp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_FTP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the A2DP profile
+*/
+#define A2D_TRACE_ERROR0(m)                      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m);}
+#define A2D_TRACE_ERROR1(m,p1)                   {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1);}
+#define A2D_TRACE_ERROR2(m,p1,p2)                {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2);}
+#define A2D_TRACE_ERROR3(m,p1,p2,p3)             {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define A2D_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define A2D_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_WARNING0(m)                    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m);}
+#define A2D_TRACE_WARNING1(m,p1)                 {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1);}
+#define A2D_TRACE_WARNING2(m,p1,p2)              {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2);}
+#define A2D_TRACE_WARNING3(m,p1,p2,p3)           {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define A2D_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define A2D_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_EVENT0(m)                      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m);}
+#define A2D_TRACE_EVENT1(m,p1)                   {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m, p1);}
+#define A2D_TRACE_EVENT2(m,p1,p2)                {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2);}
+#define A2D_TRACE_EVENT3(m,p1,p2,p3)             {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define A2D_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define A2D_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_DEBUG0(m)                      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m);}
+#define A2D_TRACE_DEBUG1(m,p1)                   {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1);}
+#define A2D_TRACE_DEBUG2(m,p1,p2)                {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define A2D_TRACE_DEBUG3(m,p1,p2,p3)             {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define A2D_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define A2D_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define A2D_TRACE_API0(m)                        {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_A2D, TRACE_TYPE_API,m);}
+#define A2D_TRACE_API1(m,p1)                     {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_A2D, TRACE_TYPE_API,m, p1);}
+#define A2D_TRACE_API2(m,p1,p2)                  {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2);}
+#define A2D_TRACE_API3(m,p1,p2,p3)               {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3);}
+#define A2D_TRACE_API4(m,p1,p2,p3,p4)            {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define A2D_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define A2D_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (a2d_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_A2D, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the VDP profile
+*/
+#define VDP_TRACE_ERROR0(m)                      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m);}
+#define VDP_TRACE_ERROR1(m,p1)                   {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1);}
+#define VDP_TRACE_ERROR2(m,p1,p2)                {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2);}
+#define VDP_TRACE_ERROR3(m,p1,p2,p3)             {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define VDP_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define VDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_WARNING0(m)                    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m);}
+#define VDP_TRACE_WARNING1(m,p1)                 {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1);}
+#define VDP_TRACE_WARNING2(m,p1,p2)              {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2);}
+#define VDP_TRACE_WARNING3(m,p1,p2,p3)           {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define VDP_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define VDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_EVENT0(m)                      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m);}
+#define VDP_TRACE_EVENT1(m,p1)                   {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m, p1);}
+#define VDP_TRACE_EVENT2(m,p1,p2)                {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2);}
+#define VDP_TRACE_EVENT3(m,p1,p2,p3)             {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define VDP_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define VDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_DEBUG0(m)                      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m);}
+#define VDP_TRACE_DEBUG1(m,p1)                   {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1);}
+#define VDP_TRACE_DEBUG2(m,p1,p2)                {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define VDP_TRACE_DEBUG3(m,p1,p2,p3)             {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define VDP_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define VDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define VDP_TRACE_API0(m)                        {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API,m);}
+#define VDP_TRACE_API1(m,p1)                     {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API,m, p1);}
+#define VDP_TRACE_API2(m,p1,p2)                  {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2);}
+#define VDP_TRACE_API3(m,p1,p2,p3)               {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3);}
+#define VDP_TRACE_API4(m,p1,p2,p3,p4)            {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define VDP_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define VDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (vdp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the LM unit
+*/
+#define LMP_TRACE_ERROR0(m)                     {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m);}
+#define LMP_TRACE_ERROR1(m,p1)                  {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1);}
+#define LMP_TRACE_ERROR2(m,p1,p2)               {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LMP_TRACE_ERROR3(m,p1,p2,p3)            {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LMP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (lmp_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_WARNING0(m)                   {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m);}
+#define LMP_TRACE_WARNING1(m,p1)                {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1);}
+#define LMP_TRACE_WARNING2(m,p1,p2)             {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LMP_TRACE_WARNING3(m,p1,p2,p3)          {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LMP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (lmp_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_EVENT0(m)                     {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m);}
+#define LMP_TRACE_EVENT1(m,p1)                  {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m, p1);}
+#define LMP_TRACE_EVENT2(m,p1,p2)               {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LMP_TRACE_EVENT3(m,p1,p2,p3)            {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LMP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (lmp_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LMP_TRACE_DEBUG0(m)                     {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m);}
+#define LMP_TRACE_DEBUG1(m,p1)                  {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1);}
+#define LMP_TRACE_DEBUG2(m,p1,p2)               {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LMP_TRACE_DEBUG3(m,p1,p2,p3)            {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LMP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define LMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (lmp_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_LM, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the LC unit
+*/
+#define LC_TRACE_ERROR0(m)                     {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m);}
+#define LC_TRACE_ERROR1(m,p1)                  {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1);}
+#define LC_TRACE_ERROR2(m,p1,p2)               {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2);}
+#define LC_TRACE_ERROR3(m,p1,p2,p3)            {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define LC_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define LC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_ERROR]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_WARNING0(m)                   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m);}
+#define LC_TRACE_WARNING1(m,p1)                {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1);}
+#define LC_TRACE_WARNING2(m,p1,p2)             {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2);}
+#define LC_TRACE_WARNING3(m,p1,p2,p3)          {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define LC_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define LC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_WARNING]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_EVENT0(m)                     {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m);}
+#define LC_TRACE_EVENT1(m,p1)                  {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m, p1);}
+#define LC_TRACE_EVENT2(m,p1,p2)               {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2);}
+#define LC_TRACE_EVENT3(m,p1,p2,p3)            {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define LC_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_4(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define LC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_EVENT]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define LC_TRACE_DEBUG0(m)                     {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_0(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m);}
+#define LC_TRACE_DEBUG1(m,p1)                  {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_1(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1);}
+#define LC_TRACE_DEBUG2(m,p1,p2)               {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_2(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define LC_TRACE_DEBUG3(m,p1,p2,p3)            {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_3(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define LC_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_5(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define LC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (lc_trace_level & trace_map[BT_TRACE_LEVEL_DEBUG]) BT_TRACE_6(TRACE_LAYER_LC, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the Serial Dongle Application SDA
+*/
+#define SDA_TRACE_ERROR0(m)                     {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(m);}
+#define SDA_TRACE_ERROR1(m,p1)                  {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_ERROR2(m,p1,p2)               {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_ERROR3(m,p1,p2,p3)            {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_WARNING0(m)                   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(m);}
+#define SDA_TRACE_WARNING1(m,p1)                {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_WARNING2(m,p1,p2)             {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_WARNING3(m,p1,p2,p3)          {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_EVENT0(m)                     {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(m);}
+#define SDA_TRACE_EVENT1(m,p1)                  {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(m, p1);}
+#define SDA_TRACE_EVENT2(m,p1,p2)               {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_EVENT3(m,p1,p2,p3)            {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+#define SDA_TRACE_DEBUG0(m)                     {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(m);}
+#define SDA_TRACE_DEBUG1(m,p1)                  {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(m,p1);}
+#define SDA_TRACE_DEBUG2(m,p1,p2)               {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(m,p1,p2);}
+#define SDA_TRACE_DEBUG3(m,p1,p2,p3)            {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(m,p1,p2,p3);}
+#define SDA_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(m,p1,p2,p3,p4);}
+#define SDA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(m,p1,p2,p3,p4,p5);}
+#define SDA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (sda_config_cb.sda_trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(m,p1,p2,p3,p4,p5,p6);}
+
+/* AVDTP
+*/
+#define AVDT_TRACE_ERROR0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m);}
+#define AVDT_TRACE_ERROR1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1);}
+#define AVDT_TRACE_ERROR2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AVDT_TRACE_ERROR3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AVDT_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_WARNING0(m)                   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m);}
+#define AVDT_TRACE_WARNING1(m,p1)                {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1);}
+#define AVDT_TRACE_WARNING2(m,p1,p2)             {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AVDT_TRACE_WARNING3(m,p1,p2,p3)          {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AVDT_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_EVENT0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m);}
+#define AVDT_TRACE_EVENT1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m, p1);}
+#define AVDT_TRACE_EVENT2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AVDT_TRACE_EVENT3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AVDT_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_DEBUG0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m);}
+#define AVDT_TRACE_DEBUG1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1);}
+#define AVDT_TRACE_DEBUG2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AVDT_TRACE_DEBUG3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AVDT_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVDT_TRACE_API0(m)                     {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API, m);}
+#define AVDT_TRACE_API1(m,p1)                  {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1);}
+#define AVDT_TRACE_API2(m,p1,p2)               {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2);}
+#define AVDT_TRACE_API3(m,p1,p2,p3)            {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AVDT_TRACE_API4(m,p1,p2,p3,p4)         {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AVDT_TRACE_API5(m,p1,p2,p3,p4,p5)      {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AVDT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)   {if (avdt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the AVCTP protocol
+*/
+#define AVCT_TRACE_ERROR0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m);}
+#define AVCT_TRACE_ERROR1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1);}
+#define AVCT_TRACE_ERROR2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AVCT_TRACE_ERROR3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AVCT_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_WARNING0(m)                   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m);}
+#define AVCT_TRACE_WARNING1(m,p1)                {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1);}
+#define AVCT_TRACE_WARNING2(m,p1,p2)             {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AVCT_TRACE_WARNING3(m,p1,p2,p3)          {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AVCT_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (avct_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_EVENT0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m);}
+#define AVCT_TRACE_EVENT1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m, p1);}
+#define AVCT_TRACE_EVENT2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AVCT_TRACE_EVENT3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AVCT_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_DEBUG0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m);}
+#define AVCT_TRACE_DEBUG1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1);}
+#define AVCT_TRACE_DEBUG2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AVCT_TRACE_DEBUG3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AVCT_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define AVCT_TRACE_API0(m)                     {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API, m);}
+#define AVCT_TRACE_API1(m,p1)                  {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1);}
+#define AVCT_TRACE_API2(m,p1,p2)               {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2);}
+#define AVCT_TRACE_API3(m,p1,p2,p3)            {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AVCT_TRACE_API4(m,p1,p2,p3,p4)         {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AVCT_TRACE_API5(m,p1,p2,p3,p4,p5)      {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AVCT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)   {if (avct_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+
+/* Define tracing for the AVRCP profile
+*/
+#define AVRC_TRACE_ERROR0(m)                      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m);}
+#define AVRC_TRACE_ERROR1(m,p1)                   {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1);}
+#define AVRC_TRACE_ERROR2(m,p1,p2)                {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2);}
+#define AVRC_TRACE_ERROR3(m,p1,p2,p3)             {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3);}
+#define AVRC_TRACE_ERROR4(m,p1,p2,p3,p4)          {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_WARNING0(m)                    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m);}
+#define AVRC_TRACE_WARNING1(m,p1)                 {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1);}
+#define AVRC_TRACE_WARNING2(m,p1,p2)              {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2);}
+#define AVRC_TRACE_WARNING3(m,p1,p2,p3)           {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3);}
+#define AVRC_TRACE_WARNING4(m,p1,p2,p3,p4)        {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)     {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)  {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_WARNING,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_EVENT0(m)                      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m);}
+#define AVRC_TRACE_EVENT1(m,p1)                   {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m, p1);}
+#define AVRC_TRACE_EVENT2(m,p1,p2)                {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2);}
+#define AVRC_TRACE_EVENT3(m,p1,p2,p3)             {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3);}
+#define AVRC_TRACE_EVENT4(m,p1,p2,p3,p4)          {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)       {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_EVENT,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_DEBUG0(m)                      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m);}
+#define AVRC_TRACE_DEBUG1(m,p1)                   {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1);}
+#define AVRC_TRACE_DEBUG2(m,p1,p2)                {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2);}
+#define AVRC_TRACE_DEBUG3(m,p1,p2,p3)             {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3);}
+#define AVRC_TRACE_DEBUG4(m,p1,p2,p3,p4)          {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)       {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)    {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_DEBUG,m,p1,p2,p3,p4,p5,p6);}
+
+#define AVRC_TRACE_API0(m)                        {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AVP, TRACE_TYPE_API,m);}
+#define AVRC_TRACE_API1(m,p1)                     {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AVP, TRACE_TYPE_API,m, p1);}
+#define AVRC_TRACE_API2(m,p1,p2)                  {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2);}
+#define AVRC_TRACE_API3(m,p1,p2,p3)               {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3);}
+#define AVRC_TRACE_API4(m,p1,p2,p3,p4)            {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4);}
+#define AVRC_TRACE_API5(m,p1,p2,p3,p4,p5)         {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5);}
+#define AVRC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)      {if (avrc_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AVP, TRACE_TYPE_API,m,p1,p2,p3,p4,p5,p6);}
+
+/* MCAP
+*/
+#define MCA_TRACE_ERROR0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m);}
+#define MCA_TRACE_ERROR1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1);}
+#define MCA_TRACE_ERROR2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2);}
+#define MCA_TRACE_ERROR3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define MCA_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define MCA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_WARNING0(m)                   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m);}
+#define MCA_TRACE_WARNING1(m,p1)                {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1);}
+#define MCA_TRACE_WARNING2(m,p1,p2)             {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2);}
+#define MCA_TRACE_WARNING3(m,p1,p2,p3)          {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define MCA_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define MCA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (mca_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_EVENT0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m);}
+#define MCA_TRACE_EVENT1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m, p1);}
+#define MCA_TRACE_EVENT2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2);}
+#define MCA_TRACE_EVENT3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define MCA_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define MCA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_DEBUG0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m);}
+#define MCA_TRACE_DEBUG1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1);}
+#define MCA_TRACE_DEBUG2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define MCA_TRACE_DEBUG3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define MCA_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define MCA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+#define MCA_TRACE_API0(m)                     {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_MCA, TRACE_TYPE_API, m);}
+#define MCA_TRACE_API1(m,p1)                  {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1);}
+#define MCA_TRACE_API2(m,p1,p2)               {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2);}
+#define MCA_TRACE_API3(m,p1,p2,p3)            {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3);}
+#define MCA_TRACE_API4(m,p1,p2,p3,p4)         {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define MCA_TRACE_API5(m,p1,p2,p3,p4,p5)      {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define MCA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)   {if (mca_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_MCA, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the AMP unit
+*/
+#define AMP_TRACE_ERROR0(m)                     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m);}
+#define AMP_TRACE_ERROR1(m,p1)                  {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1);}
+#define AMP_TRACE_ERROR2(m,p1,p2)               {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define AMP_TRACE_ERROR3(m,p1,p2,p3)            {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define AMP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define AMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_WARNING0(m)                   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m);}
+#define AMP_TRACE_WARNING1(m,p1)                {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1);}
+#define AMP_TRACE_WARNING2(m,p1,p2)             {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define AMP_TRACE_WARNING3(m,p1,p2,p3)          {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define AMP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define AMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (amp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_API0(m)                       {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_API, m);}
+#define AMP_TRACE_API1(m,p1)                    {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1);}
+#define AMP_TRACE_API2(m,p1,p2)                 {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2);}
+#define AMP_TRACE_API3(m,p1,p2,p3)              {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define AMP_TRACE_API4(m,p1,p2,p3,p4)           {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define AMP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_EVENT0(m)                     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m);}
+#define AMP_TRACE_EVENT1(m,p1)                  {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m, p1);}
+#define AMP_TRACE_EVENT2(m,p1,p2)               {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define AMP_TRACE_EVENT3(m,p1,p2,p3)            {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define AMP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define AMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define AMP_TRACE_DEBUG0(m)                     {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m);}
+#define AMP_TRACE_DEBUG1(m,p1)                  {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1);}
+#define AMP_TRACE_DEBUG2(m,p1,p2)               {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define AMP_TRACE_DEBUG3(m,p1,p2,p3)            {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define AMP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define AMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define AMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (amp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_AMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the ATT/GATT unit
+*/
+#define GATT_TRACE_ERROR0(m)                     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m);}
+#define GATT_TRACE_ERROR1(m,p1)                  {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1);}
+#define GATT_TRACE_ERROR2(m,p1,p2)               {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2);}
+#define GATT_TRACE_ERROR3(m,p1,p2,p3)            {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define GATT_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define GATT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_WARNING0(m)                   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m);}
+#define GATT_TRACE_WARNING1(m,p1)                {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1);}
+#define GATT_TRACE_WARNING2(m,p1,p2)             {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2);}
+#define GATT_TRACE_WARNING3(m,p1,p2,p3)          {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define GATT_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define GATT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_API0(m)                       {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_API, m);}
+#define GATT_TRACE_API1(m,p1)                    {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1);}
+#define GATT_TRACE_API2(m,p1,p2)                 {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2);}
+#define GATT_TRACE_API3(m,p1,p2,p3)              {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3);}
+#define GATT_TRACE_API4(m,p1,p2,p3,p4)           {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define GATT_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_EVENT0(m)                     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m);}
+#define GATT_TRACE_EVENT1(m,p1)                  {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m, p1);}
+#define GATT_TRACE_EVENT2(m,p1,p2)               {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2);}
+#define GATT_TRACE_EVENT3(m,p1,p2,p3)            {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define GATT_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define GATT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define GATT_TRACE_DEBUG0(m)                     {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m);}
+#define GATT_TRACE_DEBUG1(m,p1)                  {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1);}
+#define GATT_TRACE_DEBUG2(m,p1,p2)               {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define GATT_TRACE_DEBUG3(m,p1,p2,p3)            {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define GATT_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define GATT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define GATT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_ATT, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* Define tracing for the SMP unit
+*/
+#define SMP_TRACE_ERROR0(m)                     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m);}
+#define SMP_TRACE_ERROR1(m,p1)                  {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1);}
+#define SMP_TRACE_ERROR2(m,p1,p2)               {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2);}
+#define SMP_TRACE_ERROR3(m,p1,p2,p3)            {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3);}
+#define SMP_TRACE_ERROR4(m,p1,p2,p3,p4)         {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4);}
+#define SMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)      {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_ERROR, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_WARNING0(m)                   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m);}
+#define SMP_TRACE_WARNING1(m,p1)                {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1);}
+#define SMP_TRACE_WARNING2(m,p1,p2)             {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2);}
+#define SMP_TRACE_WARNING3(m,p1,p2,p3)          {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3);}
+#define SMP_TRACE_WARNING4(m,p1,p2,p3,p4)       {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4);}
+#define SMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)    {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_WARNING, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_API0(m)                       {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_API, m);}
+#define SMP_TRACE_API1(m,p1)                    {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1);}
+#define SMP_TRACE_API2(m,p1,p2)                 {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2);}
+#define SMP_TRACE_API3(m,p1,p2,p3)              {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3);}
+#define SMP_TRACE_API4(m,p1,p2,p3,p4)           {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4);}
+#define SMP_TRACE_API5(m,p1,p2,p3,p4,p5)        {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_API, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_EVENT0(m)                     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m);}
+#define SMP_TRACE_EVENT1(m,p1)                  {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m, p1);}
+#define SMP_TRACE_EVENT2(m,p1,p2)               {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2);}
+#define SMP_TRACE_EVENT3(m,p1,p2,p3)            {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3);}
+#define SMP_TRACE_EVENT4(m,p1,p2,p3,p4)         {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4);}
+#define SMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)      {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_EVENT, m,p1,p2,p3,p4,p5,p6);}
+
+#define SMP_TRACE_DEBUG0(m)                     {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_0(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m);}
+#define SMP_TRACE_DEBUG1(m,p1)                  {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_1(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1);}
+#define SMP_TRACE_DEBUG2(m,p1,p2)               {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_2(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2);}
+#define SMP_TRACE_DEBUG3(m,p1,p2,p3)            {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_3(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3);}
+#define SMP_TRACE_DEBUG4(m,p1,p2,p3,p4)         {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_4(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4);}
+#define SMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)      {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_5(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5);}
+#define SMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)   {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) BT_TRACE_6(TRACE_LAYER_SMP, TRACE_TYPE_DEBUG, m,p1,p2,p3,p4,p5,p6);}
+
+/* END OF USE TRACES */
+#else
+
+#define BT_TRACE_0(l,t,m)
+#define BT_TRACE_1(l,t,m,p1)
+#define BT_TRACE_2(l,t,m,p1,p2)
+#define BT_TRACE_3(l,t,m,p1,p2,p3)
+#define BT_TRACE_4(l,t,m,p1,p2,p3,p4)
+#define BT_TRACE_5(l,t,m,p1,p2,p3,p4,p5)
+#define BT_TRACE_6(l,t,m,p1,p2,p3,p4,p5,p6)
+
+#define BT_ERROR_TRACE_0(l,m)
+#define BT_ERROR_TRACE_1(l,m,p1)
+#define BT_ERROR_TRACE_2(l,m,p1,p2)
+#define BT_ERROR_TRACE_3(l,m,p1,p2,p3)
+
+/* Define tracing for the HCI unit
+*/
+#define HCI_TRACE_ERROR0(m)
+#define HCI_TRACE_ERROR1(m,p1)
+#define HCI_TRACE_ERROR2(m,p1,p2)
+#define HCI_TRACE_ERROR3(m,p1,p2,p3)
+#define HCI_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_WARNING0(m)
+#define HCI_TRACE_WARNING1(m,p1)
+#define HCI_TRACE_WARNING2(m,p1,p2)
+#define HCI_TRACE_WARNING3(m,p1,p2,p3)
+#define HCI_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_EVENT0(m)
+#define HCI_TRACE_EVENT1(m,p1)
+#define HCI_TRACE_EVENT2(m,p1,p2)
+#define HCI_TRACE_EVENT3(m,p1,p2,p3)
+#define HCI_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCI_TRACE_DEBUG0(m)
+#define HCI_TRACE_DEBUG1(m,p1)
+#define HCI_TRACE_DEBUG2(m,p1,p2)
+#define HCI_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCI_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for BTM
+*/
+#define BTM_TRACE_ERROR0(m)
+#define BTM_TRACE_ERROR1(m,p1)
+#define BTM_TRACE_ERROR2(m,p1,p2)
+#define BTM_TRACE_ERROR3(m,p1,p2,p3)
+#define BTM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BTM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_WARNING0(m)
+#define BTM_TRACE_WARNING1(m,p1)
+#define BTM_TRACE_WARNING2(m,p1,p2)
+#define BTM_TRACE_WARNING3(m,p1,p2,p3)
+#define BTM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BTM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_API0(m)
+#define BTM_TRACE_API1(m,p1)
+#define BTM_TRACE_API2(m,p1,p2)
+#define BTM_TRACE_API3(m,p1,p2,p3)
+#define BTM_TRACE_API4(m,p1,p2,p3,p4)
+#define BTM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_EVENT0(m)
+#define BTM_TRACE_EVENT1(m,p1)
+#define BTM_TRACE_EVENT2(m,p1,p2)
+#define BTM_TRACE_EVENT3(m,p1,p2,p3)
+#define BTM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BTM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BTM_TRACE_DEBUG0(m)
+#define BTM_TRACE_DEBUG1(m,p1)
+#define BTM_TRACE_DEBUG2(m,p1,p2)
+#define BTM_TRACE_DEBUG3(m,p1,p2,p3)
+#define BTM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BTM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BTM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the L2CAP unit
+*/
+#define L2CAP_TRACE_ERROR0(m)
+#define L2CAP_TRACE_ERROR1(m,p1)
+#define L2CAP_TRACE_ERROR2(m,p1,p2)
+#define L2CAP_TRACE_ERROR3(m,p1,p2,p3)
+#define L2CAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_WARNING0(m)
+#define L2CAP_TRACE_WARNING1(m,p1)
+#define L2CAP_TRACE_WARNING2(m,p1,p2)
+#define L2CAP_TRACE_WARNING3(m,p1,p2,p3)
+#define L2CAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_API0(m)
+#define L2CAP_TRACE_API1(m,p1)
+#define L2CAP_TRACE_API2(m,p1,p2)
+#define L2CAP_TRACE_API3(m,p1,p2,p3)
+#define L2CAP_TRACE_API4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_EVENT0(m)
+#define L2CAP_TRACE_EVENT1(m,p1)
+#define L2CAP_TRACE_EVENT2(m,p1,p2)
+#define L2CAP_TRACE_EVENT3(m,p1,p2,p3)
+#define L2CAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define L2CAP_TRACE_DEBUG0(m)
+#define L2CAP_TRACE_DEBUG1(m,p1)
+#define L2CAP_TRACE_DEBUG2(m,p1,p2)
+#define L2CAP_TRACE_DEBUG3(m,p1,p2,p3)
+#define L2CAP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define L2CAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define L2CAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the LLCP unit
+*/
+#define LLCP_TRACE_ERROR0(m)
+#define LLCP_TRACE_ERROR1(m,p1)
+#define LLCP_TRACE_ERROR2(m,p1,p2)
+#define LLCP_TRACE_ERROR3(m,p1,p2,p3)
+#define LLCP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_WARNING0(m)
+#define LLCP_TRACE_WARNING1(m,p1)
+#define LLCP_TRACE_WARNING2(m,p1,p2)
+#define LLCP_TRACE_WARNING3(m,p1,p2,p3)
+#define LLCP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_API0(m)
+#define LLCP_TRACE_API1(m,p1)
+#define LLCP_TRACE_API2(m,p1,p2)
+#define LLCP_TRACE_API3(m,p1,p2,p3)
+#define LLCP_TRACE_API4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_EVENT0(m)
+#define LLCP_TRACE_EVENT1(m,p1)
+#define LLCP_TRACE_EVENT2(m,p1,p2)
+#define LLCP_TRACE_EVENT3(m,p1,p2,p3)
+#define LLCP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LLCP_TRACE_DEBUG0(m)
+#define LLCP_TRACE_DEBUG1(m,p1)
+#define LLCP_TRACE_DEBUG2(m,p1,p2)
+#define LLCP_TRACE_DEBUG3(m,p1,p2,p3)
+#define LLCP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LLCP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LLCP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the SDP unit
+*/
+#define SDP_TRACE_ERROR0(m)
+#define SDP_TRACE_ERROR1(m,p1)
+#define SDP_TRACE_ERROR2(m,p1,p2)
+#define SDP_TRACE_ERROR3(m,p1,p2,p3)
+#define SDP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_WARNING0(m)
+#define SDP_TRACE_WARNING1(m,p1)
+#define SDP_TRACE_WARNING2(m,p1,p2)
+#define SDP_TRACE_WARNING3(m,p1,p2,p3)
+#define SDP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_API0(m)
+#define SDP_TRACE_API1(m,p1)
+#define SDP_TRACE_API2(m,p1,p2)
+#define SDP_TRACE_API3(m,p1,p2,p3)
+#define SDP_TRACE_API4(m,p1,p2,p3,p4)
+#define SDP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_EVENT0(m)
+#define SDP_TRACE_EVENT1(m,p1)
+#define SDP_TRACE_EVENT2(m,p1,p2)
+#define SDP_TRACE_EVENT3(m,p1,p2,p3)
+#define SDP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDP_TRACE_DEBUG0(m)
+#define SDP_TRACE_DEBUG1(m,p1)
+#define SDP_TRACE_DEBUG2(m,p1,p2)
+#define SDP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SDP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the RFCOMM unit
+*/
+#define RFCOMM_TRACE_ERROR0(m)
+#define RFCOMM_TRACE_ERROR1(m,p1)
+#define RFCOMM_TRACE_ERROR2(m,p1,p2)
+#define RFCOMM_TRACE_ERROR3(m,p1,p2,p3)
+#define RFCOMM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_WARNING0(m)
+#define RFCOMM_TRACE_WARNING1(m,p1)
+#define RFCOMM_TRACE_WARNING2(m,p1,p2)
+#define RFCOMM_TRACE_WARNING3(m,p1,p2,p3)
+#define RFCOMM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_API0(m)
+#define RFCOMM_TRACE_API1(m,p1)
+#define RFCOMM_TRACE_API2(m,p1,p2)
+#define RFCOMM_TRACE_API3(m,p1,p2,p3)
+#define RFCOMM_TRACE_API4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_EVENT0(m)
+#define RFCOMM_TRACE_EVENT1(m,p1)
+#define RFCOMM_TRACE_EVENT2(m,p1,p2)
+#define RFCOMM_TRACE_EVENT3(m,p1,p2,p3)
+#define RFCOMM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RFCOMM_TRACE_DEBUG0(m)
+#define RFCOMM_TRACE_DEBUG1(m,p1)
+#define RFCOMM_TRACE_DEBUG2(m,p1,p2)
+#define RFCOMM_TRACE_DEBUG3(m,p1,p2,p3)
+#define RFCOMM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RFCOMM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RFCOMM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for Serial Port Profile
+*/
+#define SPP_TRACE_ERROR0(m)
+#define SPP_TRACE_ERROR1(m,p1)
+#define SPP_TRACE_ERROR2(m,p1,p2)
+#define SPP_TRACE_ERROR3(m,p1,p2,p3)
+#define SPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_WARNING0(m)
+#define SPP_TRACE_WARNING1(m,p1)
+#define SPP_TRACE_WARNING2(m,p1,p2)
+#define SPP_TRACE_WARNING3(m,p1,p2,p3)
+#define SPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_EVENT0(m)
+#define SPP_TRACE_EVENT1(m,p1)
+#define SPP_TRACE_EVENT2(m,p1,p2)
+#define SPP_TRACE_EVENT3(m,p1,p2,p3)
+#define SPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_API0(m)
+#define SPP_TRACE_API1(m,p1)
+#define SPP_TRACE_API2(m,p1,p2)
+#define SPP_TRACE_API3(m,p1,p2,p3)
+#define SPP_TRACE_API4(m,p1,p2,p3,p4)
+#define SPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SPP_TRACE_DEBUG0(m)
+#define SPP_TRACE_DEBUG1(m,p1)
+#define SPP_TRACE_DEBUG2(m,p1,p2)
+#define SPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Generic Access Profile traces */
+#define GAP_TRACE_ERROR0(m)
+#define GAP_TRACE_ERROR1(m,p1)
+#define GAP_TRACE_ERROR2(m,p1,p2)
+#define GAP_TRACE_ERROR3(m,p1,p2,p3)
+#define GAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_EVENT0(m)
+#define GAP_TRACE_EVENT1(m,p1)
+#define GAP_TRACE_EVENT2(m,p1,p2)
+#define GAP_TRACE_EVENT3(m,p1,p2,p3)
+#define GAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_API0(m)
+#define GAP_TRACE_API1(m,p1)
+#define GAP_TRACE_API2(m,p1,p2)
+#define GAP_TRACE_API3(m,p1,p2,p3)
+#define GAP_TRACE_API4(m,p1,p2,p3,p4)
+#define GAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define GAP_TRACE_WARNING0(m)
+#define GAP_TRACE_WARNING1(m,p1)
+#define GAP_TRACE_WARNING2(m,p1,p2)
+#define GAP_TRACE_WARNING3(m,p1,p2,p3)
+#define GAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for OBX
+*/
+#define OBX_TRACE_ERROR0(m)
+#define OBX_TRACE_ERROR1(m,p1)
+#define OBX_TRACE_ERROR2(m,p1,p2)
+#define OBX_TRACE_ERROR3(m,p1,p2,p3)
+#define OBX_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define OBX_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_WARNING0(m)
+#define OBX_TRACE_WARNING1(m,p1)
+#define OBX_TRACE_WARNING2(m,p1,p2)
+#define OBX_TRACE_WARNING3(m,p1,p2,p3)
+#define OBX_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define OBX_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_EVENT0(m)
+#define OBX_TRACE_EVENT1(m,p1)
+#define OBX_TRACE_EVENT2(m,p1,p2)
+#define OBX_TRACE_EVENT3(m,p1,p2,p3)
+#define OBX_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define OBX_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_DEBUG0(m)
+#define OBX_TRACE_DEBUG1(m,p1)
+#define OBX_TRACE_DEBUG2(m,p1,p2)
+#define OBX_TRACE_DEBUG3(m,p1,p2,p3)
+#define OBX_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define OBX_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define OBX_TRACE_API0(m)
+#define OBX_TRACE_API1(m,p1)
+#define OBX_TRACE_API2(m,p1,p2)
+#define OBX_TRACE_API3(m,p1,p2,p3)
+#define OBX_TRACE_API4(m,p1,p2,p3,p4)
+#define OBX_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define OBX_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for GOEP application profiles
+*/
+#define GOEP_TRACE_ERROR0(m)
+#define GOEP_TRACE_ERROR1(m,p1)
+#define GOEP_TRACE_ERROR2(m,p1,p2)
+#define GOEP_TRACE_ERROR3(m,p1,p2,p3)
+#define GOEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_WARNING0(m)
+#define GOEP_TRACE_WARNING1(m,p1)
+#define GOEP_TRACE_WARNING2(m,p1,p2)
+#define GOEP_TRACE_WARNING3(m,p1,p2,p3)
+#define GOEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_EVENT0(m)
+#define GOEP_TRACE_EVENT1(m,p1)
+#define GOEP_TRACE_EVENT2(m,p1,p2)
+#define GOEP_TRACE_EVENT3(m,p1,p2,p3)
+#define GOEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_DEBUG0(m)
+#define GOEP_TRACE_DEBUG1(m,p1)
+#define GOEP_TRACE_DEBUG2(m,p1,p2)
+#define GOEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define GOEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define GOEP_TRACE_API0(m)
+#define GOEP_TRACE_API1(m,p1)
+#define GOEP_TRACE_API2(m,p1,p2)
+#define GOEP_TRACE_API3(m,p1,p2,p3)
+#define GOEP_TRACE_API4(m,p1,p2,p3,p4)
+#define GOEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GOEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the BPP profile
+*/
+#define BPP_TRACE_ERROR0(m)
+#define BPP_TRACE_ERROR1(m,p1)
+#define BPP_TRACE_ERROR2(m,p1,p2)
+#define BPP_TRACE_ERROR3(m,p1,p2,p3)
+#define BPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_WARNING0(m)
+#define BPP_TRACE_WARNING1(m,p1)
+#define BPP_TRACE_WARNING2(m,p1,p2)
+#define BPP_TRACE_WARNING3(m,p1,p2,p3)
+#define BPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_EVENT0(m)
+#define BPP_TRACE_EVENT1(m,p1)
+#define BPP_TRACE_EVENT2(m,p1,p2)
+#define BPP_TRACE_EVENT3(m,p1,p2,p3)
+#define BPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_DEBUG0(m)
+#define BPP_TRACE_DEBUG1(m,p1)
+#define BPP_TRACE_DEBUG2(m,p1,p2)
+#define BPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define BPP_TRACE_API0(m)
+#define BPP_TRACE_API1(m,p1)
+#define BPP_TRACE_API2(m,p1,p2)
+#define BPP_TRACE_API3(m,p1,p2,p3)
+#define BPP_TRACE_API4(m,p1,p2,p3,p4)
+#define BPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the BIP profile
+*/
+#define BIP_TRACE_ERROR0(m)
+#define BIP_TRACE_ERROR1(m,p1)
+#define BIP_TRACE_ERROR2(m,p1,p2)
+#define BIP_TRACE_ERROR3(m,p1,p2,p3)
+#define BIP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BIP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_WARNING0(m)
+#define BIP_TRACE_WARNING1(m,p1)
+#define BIP_TRACE_WARNING2(m,p1,p2)
+#define BIP_TRACE_WARNING3(m,p1,p2,p3)
+#define BIP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BIP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_EVENT0(m)
+#define BIP_TRACE_EVENT1(m,p1)
+#define BIP_TRACE_EVENT2(m,p1,p2)
+#define BIP_TRACE_EVENT3(m,p1,p2,p3)
+#define BIP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BIP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_DEBUG0(m)
+#define BIP_TRACE_DEBUG1(m,p1)
+#define BIP_TRACE_DEBUG2(m,p1,p2)
+#define BIP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BIP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BIP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define BIP_TRACE_API0(m)
+#define BIP_TRACE_API1(m,p1)
+#define BIP_TRACE_API2(m,p1,p2)
+#define BIP_TRACE_API3(m,p1,p2,p3)
+#define BIP_TRACE_API4(m,p1,p2,p3,p4)
+#define BIP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BIP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for TCS
+*/
+#define TCS_TRACE_ERROR0(m)
+#define TCS_TRACE_ERROR1(m,p1)
+#define TCS_TRACE_ERROR2(m,p1,p2)
+#define TCS_TRACE_ERROR3(m,p1,p2,p3)
+#define TCS_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define TCS_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_WARNING0(m)
+#define TCS_TRACE_WARNING1(m,p1)
+#define TCS_TRACE_WARNING2(m,p1,p2)
+#define TCS_TRACE_WARNING3(m,p1,p2,p3)
+#define TCS_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define TCS_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_EVENT0(m)
+#define TCS_TRACE_EVENT1(m,p1)
+#define TCS_TRACE_EVENT2(m,p1,p2)
+#define TCS_TRACE_EVENT3(m,p1,p2,p3)
+#define TCS_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define TCS_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_DEBUG0(m)
+#define TCS_TRACE_DEBUG1(m,p1)
+#define TCS_TRACE_DEBUG2(m,p1,p2)
+#define TCS_TRACE_DEBUG3(m,p1,p2,p3)
+#define TCS_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define TCS_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define TCS_TRACE_API0(m)
+#define TCS_TRACE_API1(m,p1)
+#define TCS_TRACE_API2(m,p1,p2)
+#define TCS_TRACE_API3(m,p1,p2,p3)
+#define TCS_TRACE_API4(m,p1,p2,p3,p4)
+#define TCS_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define TCS_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for ICP
+*/
+#define ICP_TRACE_ERROR0(m)
+#define ICP_TRACE_ERROR1(m,p1)
+#define ICP_TRACE_ERROR2(m,p1,p2)
+#define ICP_TRACE_ERROR3(m,p1,p2,p3)
+#define ICP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define ICP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_WARNING0(m)
+#define ICP_TRACE_WARNING1(m,p1)
+#define ICP_TRACE_WARNING2(m,p1,p2)
+#define ICP_TRACE_WARNING3(m,p1,p2,p3)
+#define ICP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define ICP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_EVENT0(m)
+#define ICP_TRACE_EVENT1(m,p1)
+#define ICP_TRACE_EVENT2(m,p1,p2)
+#define ICP_TRACE_EVENT3(m,p1,p2,p3)
+#define ICP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define ICP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_DEBUG0(m)
+#define ICP_TRACE_DEBUG1(m,p1)
+#define ICP_TRACE_DEBUG2(m,p1,p2)
+#define ICP_TRACE_DEBUG3(m,p1,p2,p3)
+#define ICP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define ICP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define ICP_TRACE_API0(m)
+#define ICP_TRACE_API1(m,p1)
+#define ICP_TRACE_API2(m,p1,p2)
+#define ICP_TRACE_API3(m,p1,p2,p3)
+#define ICP_TRACE_API4(m,p1,p2,p3,p4)
+#define ICP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define ICP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for CTP
+*/
+#define CTP_TRACE_ERROR0(m)
+#define CTP_TRACE_ERROR1(m,p1)
+#define CTP_TRACE_ERROR2(m,p1,p2)
+#define CTP_TRACE_ERROR3(m,p1,p2,p3)
+#define CTP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_WARNING0(m)
+#define CTP_TRACE_WARNING1(m,p1)
+#define CTP_TRACE_WARNING2(m,p1,p2)
+#define CTP_TRACE_WARNING3(m,p1,p2,p3)
+#define CTP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_EVENT0(m)
+#define CTP_TRACE_EVENT1(m,p1)
+#define CTP_TRACE_EVENT2(m,p1,p2)
+#define CTP_TRACE_EVENT3(m,p1,p2,p3)
+#define CTP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_DEBUG0(m)
+#define CTP_TRACE_DEBUG1(m,p1)
+#define CTP_TRACE_DEBUG2(m,p1,p2)
+#define CTP_TRACE_DEBUG3(m,p1,p2,p3)
+#define CTP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define CTP_TRACE_API0(m)
+#define CTP_TRACE_API1(m,p1)
+#define CTP_TRACE_API2(m,p1,p2)
+#define CTP_TRACE_API3(m,p1,p2,p3)
+#define CTP_TRACE_API4(m,p1,p2,p3,p4)
+#define CTP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CTP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for headset profile */
+
+#define HSP2_TRACE_ERROR0(pcb,m)
+#define HSP2_TRACE_ERROR1(pcb,m,p1)
+#define HSP2_TRACE_ERROR2(pcb,m,p1,p2)
+#define HSP2_TRACE_ERROR3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_ERROR4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_ERROR5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_ERROR6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_WARNING0(pcb,m)
+#define HSP2_TRACE_WARNING1(pcb,m,p1)
+#define HSP2_TRACE_WARNING2(pcb,m,p1,p2)
+#define HSP2_TRACE_WARNING3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_WARNING4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_WARNING5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_WARNING6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_API0(pcb,m)
+#define HSP2_TRACE_API1(pcb,m,p1)
+#define HSP2_TRACE_API2(pcb,m,p1,p2)
+#define HSP2_TRACE_API3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_API4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_API5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_API6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_EVENT0(pcb,m)
+#define HSP2_TRACE_EVENT1(pcb,m,p1)
+#define HSP2_TRACE_EVENT2(pcb,m,p1,p2)
+#define HSP2_TRACE_EVENT3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_EVENT4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_EVENT5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_EVENT6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+#define HSP2_TRACE_DEBUG0(pcb,m)
+#define HSP2_TRACE_DEBUG1(pcb,m,p1)
+#define HSP2_TRACE_DEBUG2(pcb,m,p1,p2)
+#define HSP2_TRACE_DEBUG3(pcb,m,p1,p2,p3)
+#define HSP2_TRACE_DEBUG4(pcb,m,p1,p2,p3,p4)
+#define HSP2_TRACE_DEBUG5(pcb,m,p1,p2,p3,p4,p5)
+#define HSP2_TRACE_DEBUG6(pcb,m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFC unit
+*/
+#define NFC_TRACE_ERROR0(m)
+#define NFC_TRACE_ERROR1(m,p1)
+#define NFC_TRACE_ERROR2(m,p1,p2)
+#define NFC_TRACE_ERROR3(m,p1,p2,p3)
+#define NFC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NFC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_WARNING0(m)
+#define NFC_TRACE_WARNING1(m,p1)
+#define NFC_TRACE_WARNING2(m,p1,p2)
+#define NFC_TRACE_WARNING3(m,p1,p2,p3)
+#define NFC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NFC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_API0(m)
+#define NFC_TRACE_API1(m,p1)
+#define NFC_TRACE_API2(m,p1,p2)
+#define NFC_TRACE_API3(m,p1,p2,p3)
+#define NFC_TRACE_API4(m,p1,p2,p3,p4)
+#define NFC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_EVENT0(m)
+#define NFC_TRACE_EVENT1(m,p1)
+#define NFC_TRACE_EVENT2(m,p1,p2)
+#define NFC_TRACE_EVENT3(m,p1,p2,p3)
+#define NFC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NFC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFC_TRACE_DEBUG0(m)
+#define NFC_TRACE_DEBUG1(m,p1)
+#define NFC_TRACE_DEBUG2(m,p1,p2)
+#define NFC_TRACE_DEBUG3(m,p1,p2,p3)
+#define NFC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NFC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NFC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_ERROR0(m)
+#define NCI_TRACE_ERROR1(m,p1)
+#define NCI_TRACE_ERROR2(m,p1,p2)
+#define NCI_TRACE_ERROR3(m,p1,p2,p3)
+#define NCI_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NCI_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_WARNING0(m)
+#define NCI_TRACE_WARNING1(m,p1)
+#define NCI_TRACE_WARNING2(m,p1,p2)
+#define NCI_TRACE_WARNING3(m,p1,p2,p3)
+#define NCI_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NCI_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_API0(m)
+#define NCI_TRACE_API1(m,p1)
+#define NCI_TRACE_API2(m,p1,p2)
+#define NCI_TRACE_API3(m,p1,p2,p3)
+#define NCI_TRACE_API4(m,p1,p2,p3,p4)
+#define NCI_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_EVENT0(m)
+#define NCI_TRACE_EVENT1(m,p1)
+#define NCI_TRACE_EVENT2(m,p1,p2)
+#define NCI_TRACE_EVENT3(m,p1,p2,p3)
+#define NCI_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NCI_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NCI_TRACE_DEBUG0(m)
+#define NCI_TRACE_DEBUG1(m,p1)
+#define NCI_TRACE_DEBUG2(m,p1,p2)
+#define NCI_TRACE_DEBUG3(m,p1,p2,p3)
+#define NCI_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NCI_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NCI_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_ERROR0(m)
+#define RW_TRACE_ERROR1(m,p1)
+#define RW_TRACE_ERROR2(m,p1,p2)
+#define RW_TRACE_ERROR3(m,p1,p2,p3)
+#define RW_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RW_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_WARNING0(m)
+#define RW_TRACE_WARNING1(m,p1)
+#define RW_TRACE_WARNING2(m,p1,p2)
+#define RW_TRACE_WARNING3(m,p1,p2,p3)
+#define RW_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RW_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) }
+
+#define RW_TRACE_API0(m)
+#define RW_TRACE_API1(m,p1)
+#define RW_TRACE_API2(m,p1,p2)
+#define RW_TRACE_API3(m,p1,p2,p3)
+#define RW_TRACE_API4(m,p1,p2,p3,p4)
+#define RW_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_EVENT0(m)
+#define RW_TRACE_EVENT1(m,p1)
+#define RW_TRACE_EVENT2(m,p1,p2)
+#define RW_TRACE_EVENT3(m,p1,p2,p3)
+#define RW_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RW_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RW_TRACE_DEBUG0(m)
+#define RW_TRACE_DEBUG1(m,p1)
+#define RW_TRACE_DEBUG2(m,p1,p2)
+#define RW_TRACE_DEBUG3(m,p1,p2,p3)
+#define RW_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RW_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RW_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_ERROR0(m)
+#define CE_TRACE_ERROR1(m,p1)
+#define CE_TRACE_ERROR2(m,p1,p2)
+#define CE_TRACE_ERROR3(m,p1,p2,p3)
+#define CE_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CE_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_WARNING0(m)
+#define CE_TRACE_WARNING1(m,p1)
+#define CE_TRACE_WARNING2(m,p1,p2)
+#define CE_TRACE_WARNING3(m,p1,p2,p3)
+#define CE_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CE_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_API0(m)
+#define CE_TRACE_API1(m,p1)
+#define CE_TRACE_API2(m,p1,p2)
+#define CE_TRACE_API3(m,p1,p2,p3)
+#define CE_TRACE_API4(m,p1,p2,p3,p4)
+#define CE_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_EVENT0(m)
+#define CE_TRACE_EVENT1(m,p1)
+#define CE_TRACE_EVENT2(m,p1,p2)
+#define CE_TRACE_EVENT3(m,p1,p2,p3)
+#define CE_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CE_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CE_TRACE_DEBUG0(m)
+#define CE_TRACE_DEBUG1(m,p1)
+#define CE_TRACE_DEBUG2(m,p1,p2)
+#define CE_TRACE_DEBUG3(m,p1,p2,p3)
+#define CE_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CE_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CE_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_ERROR0(m)
+#define NDEF_TRACE_ERROR1(m,p1)
+#define NDEF_TRACE_ERROR2(m,p1,p2)
+#define NDEF_TRACE_ERROR3(m,p1,p2,p3)
+#define NDEF_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_WARNING0(m)
+#define NDEF_TRACE_WARNING1(m,p1)
+#define NDEF_TRACE_WARNING2(m,p1,p2)
+#define NDEF_TRACE_WARNING3(m,p1,p2,p3)
+#define NDEF_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_API0(m)
+#define NDEF_TRACE_API1(m,p1)
+#define NDEF_TRACE_API2(m,p1,p2)
+#define NDEF_TRACE_API3(m,p1,p2,p3)
+#define NDEF_TRACE_API4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_EVENT0(m)
+#define NDEF_TRACE_EVENT1(m,p1)
+#define NDEF_TRACE_EVENT2(m,p1,p2)
+#define NDEF_TRACE_EVENT3(m,p1,p2,p3)
+#define NDEF_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NDEF_TRACE_DEBUG0(m)
+#define NDEF_TRACE_DEBUG1(m,p1)
+#define NDEF_TRACE_DEBUG2(m,p1,p2)
+#define NDEF_TRACE_DEBUG3(m,p1,p2,p3)
+#define NDEF_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NDEF_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NDEF_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA unit
+*/
+#define NFA_TRACE_ERROR0(m)
+#define NFA_TRACE_ERROR1(m,p1)
+#define NFA_TRACE_ERROR2(m,p1,p2)
+#define NFA_TRACE_ERROR3(m,p1,p2,p3)
+#define NFA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define NFA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_WARNING0(m)
+#define NFA_TRACE_WARNING1(m,p1)
+#define NFA_TRACE_WARNING2(m,p1,p2)
+#define NFA_TRACE_WARNING3(m,p1,p2,p3)
+#define NFA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define NFA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_API0(m)
+#define NFA_TRACE_API1(m,p1)
+#define NFA_TRACE_API2(m,p1,p2)
+#define NFA_TRACE_API3(m,p1,p2,p3)
+#define NFA_TRACE_API4(m,p1,p2,p3,p4)
+#define NFA_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_EVENT0(m)
+#define NFA_TRACE_EVENT1(m,p1)
+#define NFA_TRACE_EVENT2(m,p1,p2)
+#define NFA_TRACE_EVENT3(m,p1,p2,p3)
+#define NFA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define NFA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define NFA_TRACE_DEBUG0(m)
+#define NFA_TRACE_DEBUG1(m,p1)
+#define NFA_TRACE_DEBUG2(m,p1,p2)
+#define NFA_TRACE_DEBUG3(m,p1,p2,p3)
+#define NFA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define NFA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define NFA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA P2P unit
+*/
+#define P2P_TRACE_ERROR0(m)
+#define P2P_TRACE_ERROR1(m,p1)
+#define P2P_TRACE_ERROR2(m,p1,p2)
+#define P2P_TRACE_ERROR3(m,p1,p2,p3)
+#define P2P_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define P2P_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_WARNING0(m)
+#define P2P_TRACE_WARNING1(m,p1)
+#define P2P_TRACE_WARNING2(m,p1,p2)
+#define P2P_TRACE_WARNING3(m,p1,p2,p3)
+#define P2P_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define P2P_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_API0(m)
+#define P2P_TRACE_API1(m,p1)
+#define P2P_TRACE_API2(m,p1,p2)
+#define P2P_TRACE_API3(m,p1,p2,p3)
+#define P2P_TRACE_API4(m,p1,p2,p3,p4)
+#define P2P_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_EVENT0(m)
+#define P2P_TRACE_EVENT1(m,p1)
+#define P2P_TRACE_EVENT2(m,p1,p2)
+#define P2P_TRACE_EVENT3(m,p1,p2,p3)
+#define P2P_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define P2P_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define P2P_TRACE_DEBUG0(m)
+#define P2P_TRACE_DEBUG1(m,p1)
+#define P2P_TRACE_DEBUG2(m,p1,p2)
+#define P2P_TRACE_DEBUG3(m,p1,p2,p3)
+#define P2P_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define P2P_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define P2P_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA CHO unit
+*/
+#define CHO_TRACE_ERROR0(m)
+#define CHO_TRACE_ERROR1(m,p1)
+#define CHO_TRACE_ERROR2(m,p1,p2)
+#define CHO_TRACE_ERROR3(m,p1,p2,p3)
+#define CHO_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define CHO_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_WARNING0(m)
+#define CHO_TRACE_WARNING1(m,p1)
+#define CHO_TRACE_WARNING2(m,p1,p2)
+#define CHO_TRACE_WARNING3(m,p1,p2,p3)
+#define CHO_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define CHO_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_API0(m)
+#define CHO_TRACE_API1(m,p1)
+#define CHO_TRACE_API2(m,p1,p2)
+#define CHO_TRACE_API3(m,p1,p2,p3)
+#define CHO_TRACE_API4(m,p1,p2,p3,p4)
+#define CHO_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_EVENT0(m)
+#define CHO_TRACE_EVENT1(m,p1)
+#define CHO_TRACE_EVENT2(m,p1,p2)
+#define CHO_TRACE_EVENT3(m,p1,p2,p3)
+#define CHO_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define CHO_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define CHO_TRACE_DEBUG0(m)
+#define CHO_TRACE_DEBUG1(m,p1)
+#define CHO_TRACE_DEBUG2(m,p1,p2)
+#define CHO_TRACE_DEBUG3(m,p1,p2,p3)
+#define CHO_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define CHO_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define CHO_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the NFA SNEP unit
+*/
+#define SNEP_TRACE_ERROR0(m)
+#define SNEP_TRACE_ERROR1(m,p1)
+#define SNEP_TRACE_ERROR2(m,p1,p2)
+#define SNEP_TRACE_ERROR3(m,p1,p2,p3)
+#define SNEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_WARNING0(m)
+#define SNEP_TRACE_WARNING1(m,p1)
+#define SNEP_TRACE_WARNING2(m,p1,p2)
+#define SNEP_TRACE_WARNING3(m,p1,p2,p3)
+#define SNEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_API0(m)
+#define SNEP_TRACE_API1(m,p1)
+#define SNEP_TRACE_API2(m,p1,p2)
+#define SNEP_TRACE_API3(m,p1,p2,p3)
+#define SNEP_TRACE_API4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_EVENT0(m)
+#define SNEP_TRACE_EVENT1(m,p1)
+#define SNEP_TRACE_EVENT2(m,p1,p2)
+#define SNEP_TRACE_EVENT3(m,p1,p2,p3)
+#define SNEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SNEP_TRACE_DEBUG0(m)
+#define SNEP_TRACE_DEBUG1(m,p1)
+#define SNEP_TRACE_DEBUG2(m,p1,p2)
+#define SNEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* define traces for HID Host */
+#define HIDH_TRACE_ERROR0(m)
+#define HIDH_TRACE_ERROR1(m,p1)
+#define HIDH_TRACE_ERROR2(m,p1,p2)
+#define HIDH_TRACE_ERROR3(m,p1,p2,p3)
+#define HIDH_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_WARNING0(m)
+#define HIDH_TRACE_WARNING1(m,p1)
+#define HIDH_TRACE_WARNING2(m,p1,p2)
+#define HIDH_TRACE_WARNING3(m,p1,p2,p3)
+#define HIDH_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_API0(m)
+#define HIDH_TRACE_API1(m,p1)
+#define HIDH_TRACE_API2(m,p1,p2)
+#define HIDH_TRACE_API3(m,p1,p2,p3)
+#define HIDH_TRACE_API4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_EVENT0(m)
+#define HIDH_TRACE_EVENT1(m,p1)
+#define HIDH_TRACE_EVENT2(m,p1,p2)
+#define HIDH_TRACE_EVENT3(m,p1,p2,p3)
+#define HIDH_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDH_TRACE_DEBUG0(m)
+#define HIDH_TRACE_DEBUG1(m,p1)
+#define HIDH_TRACE_DEBUG2(m,p1,p2)
+#define HIDH_TRACE_DEBUG3(m,p1,p2,p3)
+#define HIDH_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HIDH_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HIDH_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for HID Device */
+#define HIDD_TRACE_ERROR0(m)
+#define HIDD_TRACE_ERROR1(m,p1)
+#define HIDD_TRACE_ERROR2(m,p1,p2)
+#define HIDD_TRACE_ERROR3(m,p1,p2,p3)
+#define HIDD_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_WARNING0(m)
+#define HIDD_TRACE_WARNING1(m,p1)
+#define HIDD_TRACE_WARNING2(m,p1,p2)
+#define HIDD_TRACE_WARNING3(m,p1,p2,p3)
+#define HIDD_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_API0(m)
+#define HIDD_TRACE_API1(m,p1)
+#define HIDD_TRACE_API2(m,p1,p2)
+#define HIDD_TRACE_API3(m,p1,p2,p3)
+#define HIDD_TRACE_API4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_EVENT0(m)
+#define HIDD_TRACE_EVENT1(m,p1)
+#define HIDD_TRACE_EVENT2(m,p1,p2)
+#define HIDD_TRACE_EVENT3(m,p1,p2,p3)
+#define HIDD_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HIDD_TRACE_DEBUG0(m)
+#define HIDD_TRACE_DEBUG1(m,p1)
+#define HIDD_TRACE_DEBUG2(m,p1,p2)
+#define HIDD_TRACE_DEBUG3(m,p1,p2,p3)
+#define HIDD_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HIDD_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HIDD_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for DUN */
+
+#define DUN_TRACE_ERROR0(m)
+#define DUN_TRACE_ERROR1(m,p1)
+#define DUN_TRACE_ERROR2(m,p1,p2)
+#define DUN_TRACE_ERROR3(m,p1,p2,p3)
+#define DUN_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define DUN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_WARNING0(m)
+#define DUN_TRACE_WARNING1(m,p1)
+#define DUN_TRACE_WARNING2(m,p1,p2)
+#define DUN_TRACE_WARNING3(m,p1,p2,p3)
+#define DUN_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DUN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_API0(m)
+#define DUN_TRACE_API1(m,p1)
+#define DUN_TRACE_API2(m,p1,p2)
+#define DUN_TRACE_API3(m,p1,p2,p3)
+#define DUN_TRACE_API4(m,p1,p2,p3,p4)
+#define DUN_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_EVENT0(m)
+#define DUN_TRACE_EVENT1(m,p1)
+#define DUN_TRACE_EVENT2(m,p1,p2)
+#define DUN_TRACE_EVENT3(m,p1,p2,p3)
+#define DUN_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define DUN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define DUN_TRACE_DEBUG0(m)
+#define DUN_TRACE_DEBUG1(m,p1)
+#define DUN_TRACE_DEBUG2(m,p1,p2)
+#define DUN_TRACE_DEBUG3(m,p1,p2,p3)
+#define DUN_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define DUN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define DUN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for HCRP */
+
+#define HCRP_TRACE_ERROR0(m)
+#define HCRP_TRACE_ERROR1(m,p1)
+#define HCRP_TRACE_ERROR2(m,p1,p2)
+#define HCRP_TRACE_ERROR3(m,p1,p2,p3)
+#define HCRP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_WARNING0(m)
+#define HCRP_TRACE_WARNING1(m,p1)
+#define HCRP_TRACE_WARNING2(m,p1,p2)
+#define HCRP_TRACE_WARNING3(m,p1,p2,p3)
+#define HCRP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_API0(m)
+#define HCRP_TRACE_API1(m,p1)
+#define HCRP_TRACE_API2(m,p1,p2)
+#define HCRP_TRACE_API3(m,p1,p2,p3)
+#define HCRP_TRACE_API4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_EVENT0(m)
+#define HCRP_TRACE_EVENT1(m,p1)
+#define HCRP_TRACE_EVENT2(m,p1,p2)
+#define HCRP_TRACE_EVENT3(m,p1,p2,p3)
+#define HCRP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRP_TRACE_DEBUG0(m)
+#define HCRP_TRACE_DEBUG1(m,p1)
+#define HCRP_TRACE_DEBUG2(m,p1,p2)
+#define HCRP_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCRP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCRP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCRP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* define traces for HCRP */
+
+#define HCRPM_TRACE_ERROR0(m)
+#define HCRPM_TRACE_ERROR1(m,p1)
+#define HCRPM_TRACE_ERROR2(m,p1,p2)
+#define HCRPM_TRACE_ERROR3(m,p1,p2,p3)
+#define HCRPM_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_WARNING0(m)
+#define HCRPM_TRACE_WARNING1(m,p1)
+#define HCRPM_TRACE_WARNING2(m,p1,p2)
+#define HCRPM_TRACE_WARNING3(m,p1,p2,p3)
+#define HCRPM_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_API0(m)
+#define HCRPM_TRACE_API1(m,p1)
+#define HCRPM_TRACE_API2(m,p1,p2)
+#define HCRPM_TRACE_API3(m,p1,p2,p3)
+#define HCRPM_TRACE_API4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_EVENT0(m)
+#define HCRPM_TRACE_EVENT1(m,p1)
+#define HCRPM_TRACE_EVENT2(m,p1,p2)
+#define HCRPM_TRACE_EVENT3(m,p1,p2,p3)
+#define HCRPM_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define HCRPM_TRACE_DEBUG0(m)
+#define HCRPM_TRACE_DEBUG1(m,p1)
+#define HCRPM_TRACE_DEBUG2(m,p1,p2)
+#define HCRPM_TRACE_DEBUG3(m,p1,p2,p3)
+#define HCRPM_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define HCRPM_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define HCRPM_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for RPC */
+
+#define RPC_TRACE_ERROR0(m)
+#define RPC_TRACE_ERROR1(m,p1)
+#define RPC_TRACE_ERROR2(m,p1,p2)
+#define RPC_TRACE_ERROR3(m,p1,p2,p3)
+#define RPC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define RPC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_WARNING0(m)
+#define RPC_TRACE_WARNING1(m,p1)
+#define RPC_TRACE_WARNING2(m,p1,p2)
+#define RPC_TRACE_WARNING3(m,p1,p2,p3)
+#define RPC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define RPC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_API0(m)
+#define RPC_TRACE_API1(m,p1)
+#define RPC_TRACE_API2(m,p1,p2)
+#define RPC_TRACE_API3(m,p1,p2,p3)
+#define RPC_TRACE_API4(m,p1,p2,p3,p4)
+#define RPC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_EVENT0(m)
+#define RPC_TRACE_EVENT1(m,p1)
+#define RPC_TRACE_EVENT2(m,p1,p2)
+#define RPC_TRACE_EVENT3(m,p1,p2,p3)
+#define RPC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define RPC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define RPC_TRACE_DEBUG0(m)
+#define RPC_TRACE_DEBUG1(m,p1)
+#define RPC_TRACE_DEBUG2(m,p1,p2)
+#define RPC_TRACE_DEBUG3(m,p1,p2,p3)
+#define RPC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define RPC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define RPC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for BNEP */
+
+#define BNEP_TRACE_ERROR0(m)
+#define BNEP_TRACE_ERROR1(m,p1)
+#define BNEP_TRACE_ERROR2(m,p1,p2)
+#define BNEP_TRACE_ERROR3(m,p1,p2,p3)
+#define BNEP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_WARNING0(m)
+#define BNEP_TRACE_WARNING1(m,p1)
+#define BNEP_TRACE_WARNING2(m,p1,p2)
+#define BNEP_TRACE_WARNING3(m,p1,p2,p3)
+#define BNEP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_API0(m)
+#define BNEP_TRACE_API1(m,p1)
+#define BNEP_TRACE_API2(m,p1,p2)
+#define BNEP_TRACE_API3(m,p1,p2,p3)
+#define BNEP_TRACE_API4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_EVENT0(m)
+#define BNEP_TRACE_EVENT1(m,p1)
+#define BNEP_TRACE_EVENT2(m,p1,p2)
+#define BNEP_TRACE_EVENT3(m,p1,p2,p3)
+#define BNEP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define BNEP_TRACE_DEBUG0(m)
+#define BNEP_TRACE_DEBUG1(m,p1)
+#define BNEP_TRACE_DEBUG2(m,p1,p2)
+#define BNEP_TRACE_DEBUG3(m,p1,p2,p3)
+#define BNEP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define BNEP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define BNEP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* hid module traces */
+
+#define MSKB_TRACE_0(m)
+#define MSKB_TRACE_1(m,p1)
+#define MSKB_TRACE_2(m,p1,p2)
+#define MSKB_TRACE_3(m,p1,p2,p3)
+#define MSKB_TRACE_4(m,p1,p2,p3,p4)
+#define MSKB_TRACE_5(m,p1,p2,p3,p4,p5)
+#define MSKB_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_DEBUG_0(m)
+#define MSKB_DEBUG_1(m,p1)
+#define MSKB_DEBUG_2(m,p1,p2)
+#define MSKB_DEBUG_3(m,p1,p2,p3)
+#define MSKB_DEBUG_4(m,p1,p2,p3,p4)
+#define MSKB_DEBUG_5(m,p1,p2,p3,p4,p5)
+#define MSKB_DEBUG_6(m,p1,p2,p3,p4,p5,p6)
+
+#define MSKB_ERROR_0(m)
+#define MSKB_ERROR_1(m,p1)
+#define MSKB_ERROR_2(m,p1,p2)
+#define MSKB_ERROR_3(m,p1,p2,p3)
+#define MSKB_ERROR_4(m,p1,p2,p3,p4)
+#define MSKB_ERROR_5(m,p1,p2,p3,p4,p5)
+#define MSKB_ERROR_6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for PAN */
+
+#define PAN_TRACE_ERROR0(m)
+#define PAN_TRACE_ERROR1(m,p1)
+#define PAN_TRACE_ERROR2(m,p1,p2)
+#define PAN_TRACE_ERROR3(m,p1,p2,p3)
+#define PAN_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define PAN_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_WARNING0(m)
+#define PAN_TRACE_WARNING1(m,p1)
+#define PAN_TRACE_WARNING2(m,p1,p2)
+#define PAN_TRACE_WARNING3(m,p1,p2,p3)
+#define PAN_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define PAN_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_API0(m)
+#define PAN_TRACE_API1(m,p1)
+#define PAN_TRACE_API2(m,p1,p2)
+#define PAN_TRACE_API3(m,p1,p2,p3)
+#define PAN_TRACE_API4(m,p1,p2,p3,p4)
+#define PAN_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_EVENT0(m)
+#define PAN_TRACE_EVENT1(m,p1)
+#define PAN_TRACE_EVENT2(m,p1,p2)
+#define PAN_TRACE_EVENT3(m,p1,p2,p3)
+#define PAN_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define PAN_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define PAN_TRACE_DEBUG0(m)
+#define PAN_TRACE_DEBUG1(m,p1)
+#define PAN_TRACE_DEBUG2(m,p1,p2)
+#define PAN_TRACE_DEBUG3(m,p1,p2,p3)
+#define PAN_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define PAN_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define PAN_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* define traces for SIM */
+
+#define SAP_TRACE_ERROR0(m)
+#define SAP_TRACE_ERROR1(m,p1)
+#define SAP_TRACE_ERROR2(m,p1,p2)
+#define SAP_TRACE_ERROR3(m,p1,p2,p3)
+#define SAP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SAP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_WARNING0(m)
+#define SAP_TRACE_WARNING1(m,p1)
+#define SAP_TRACE_WARNING2(m,p1,p2)
+#define SAP_TRACE_WARNING3(m,p1,p2,p3)
+#define SAP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SAP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_API0(m)
+#define SAP_TRACE_API1(m,p1)
+#define SAP_TRACE_API2(m,p1,p2)
+#define SAP_TRACE_API3(m,p1,p2,p3)
+#define SAP_TRACE_API4(m,p1,p2,p3,p4)
+#define SAP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_EVENT0(m)
+#define SAP_TRACE_EVENT1(m,p1)
+#define SAP_TRACE_EVENT2(m,p1,p2)
+#define SAP_TRACE_EVENT3(m,p1,p2,p3)
+#define SAP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SAP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SAP_TRACE_DEBUG0(m)
+#define SAP_TRACE_DEBUG1(m,p1)
+#define SAP_TRACE_DEBUG2(m,p1,p2)
+#define SAP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SAP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SAP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the OPP profile
+*/
+#define OPP_TRACE_ERROR0(m)
+#define OPP_TRACE_ERROR1(m,p1)
+#define OPP_TRACE_ERROR2(m,p1,p2)
+#define OPP_TRACE_ERROR3(m,p1,p2,p3)
+#define OPP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define OPP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_WARNING0(m)
+#define OPP_TRACE_WARNING1(m,p1)
+#define OPP_TRACE_WARNING2(m,p1,p2)
+#define OPP_TRACE_WARNING3(m,p1,p2,p3)
+#define OPP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define OPP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_EVENT0(m)
+#define OPP_TRACE_EVENT1(m,p1)
+#define OPP_TRACE_EVENT2(m,p1,p2)
+#define OPP_TRACE_EVENT3(m,p1,p2,p3)
+#define OPP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define OPP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_DEBUG0(m)
+#define OPP_TRACE_DEBUG1(m,p1)
+#define OPP_TRACE_DEBUG2(m,p1,p2)
+#define OPP_TRACE_DEBUG3(m,p1,p2,p3)
+#define OPP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define OPP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define OPP_TRACE_API0(m)
+#define OPP_TRACE_API1(m,p1)
+#define OPP_TRACE_API2(m,p1,p2)
+#define OPP_TRACE_API3(m,p1,p2,p3)
+#define OPP_TRACE_API4(m,p1,p2,p3,p4)
+#define OPP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define OPP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the FTP profile
+*/
+#define FTP_TRACE_ERROR0(m)
+#define FTP_TRACE_ERROR1(m,p1)
+#define FTP_TRACE_ERROR2(m,p1,p2)
+#define FTP_TRACE_ERROR3(m,p1,p2,p3)
+#define FTP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define FTP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_WARNING0(m)
+#define FTP_TRACE_WARNING1(m,p1)
+#define FTP_TRACE_WARNING2(m,p1,p2)
+#define FTP_TRACE_WARNING3(m,p1,p2,p3)
+#define FTP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define FTP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_EVENT0(m)
+#define FTP_TRACE_EVENT1(m,p1)
+#define FTP_TRACE_EVENT2(m,p1,p2)
+#define FTP_TRACE_EVENT3(m,p1,p2,p3)
+#define FTP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define FTP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_DEBUG0(m)
+#define FTP_TRACE_DEBUG1(m,p1)
+#define FTP_TRACE_DEBUG2(m,p1,p2)
+#define FTP_TRACE_DEBUG3(m,p1,p2,p3)
+#define FTP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define FTP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define FTP_TRACE_API0(m)
+#define FTP_TRACE_API1(m,p1)
+#define FTP_TRACE_API2(m,p1,p2)
+#define FTP_TRACE_API3(m,p1,p2,p3)
+#define FTP_TRACE_API4(m,p1,p2,p3,p4)
+#define FTP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define FTP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the A2DP profile
+*/
+#define A2D_TRACE_ERROR0(m)
+#define A2D_TRACE_ERROR1(m,p1)
+#define A2D_TRACE_ERROR2(m,p1,p2)
+#define A2D_TRACE_ERROR3(m,p1,p2,p3)
+#define A2D_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define A2D_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_WARNING0(m)
+#define A2D_TRACE_WARNING1(m,p1)
+#define A2D_TRACE_WARNING2(m,p1,p2)
+#define A2D_TRACE_WARNING3(m,p1,p2,p3)
+#define A2D_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define A2D_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_EVENT0(m)
+#define A2D_TRACE_EVENT1(m,p1)
+#define A2D_TRACE_EVENT2(m,p1,p2)
+#define A2D_TRACE_EVENT3(m,p1,p2,p3)
+#define A2D_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define A2D_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_DEBUG0(m)
+#define A2D_TRACE_DEBUG1(m,p1)
+#define A2D_TRACE_DEBUG2(m,p1,p2)
+#define A2D_TRACE_DEBUG3(m,p1,p2,p3)
+#define A2D_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define A2D_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define A2D_TRACE_API0(m)
+#define A2D_TRACE_API1(m,p1)
+#define A2D_TRACE_API2(m,p1,p2)
+#define A2D_TRACE_API3(m,p1,p2,p3)
+#define A2D_TRACE_API4(m,p1,p2,p3,p4)
+#define A2D_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define A2D_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the VDP profile
+*/
+#define VDP_TRACE_ERROR0(m)
+#define VDP_TRACE_ERROR1(m,p1)
+#define VDP_TRACE_ERROR2(m,p1,p2)
+#define VDP_TRACE_ERROR3(m,p1,p2,p3)
+#define VDP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define VDP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_WARNING0(m)
+#define VDP_TRACE_WARNING1(m,p1)
+#define VDP_TRACE_WARNING2(m,p1,p2)
+#define VDP_TRACE_WARNING3(m,p1,p2,p3)
+#define VDP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define VDP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_EVENT0(m)
+#define VDP_TRACE_EVENT1(m,p1)
+#define VDP_TRACE_EVENT2(m,p1,p2)
+#define VDP_TRACE_EVENT3(m,p1,p2,p3)
+#define VDP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define VDP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_DEBUG0(m)
+#define VDP_TRACE_DEBUG1(m,p1)
+#define VDP_TRACE_DEBUG2(m,p1,p2)
+#define VDP_TRACE_DEBUG3(m,p1,p2,p3)
+#define VDP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define VDP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define VDP_TRACE_API0(m)
+#define VDP_TRACE_API1(m,p1)
+#define VDP_TRACE_API2(m,p1,p2)
+#define VDP_TRACE_API3(m,p1,p2,p3)
+#define VDP_TRACE_API4(m,p1,p2,p3,p4)
+#define VDP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define VDP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the LM unit
+*/
+#define LMP_TRACE_ERROR0(m)
+#define LMP_TRACE_ERROR1(m,p1)
+#define LMP_TRACE_ERROR2(m,p1,p2)
+#define LMP_TRACE_ERROR3(m,p1,p2,p3)
+#define LMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_WARNING0(m)
+#define LMP_TRACE_WARNING1(m,p1)
+#define LMP_TRACE_WARNING2(m,p1,p2)
+#define LMP_TRACE_WARNING3(m,p1,p2,p3)
+#define LMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_EVENT0(m)
+#define LMP_TRACE_EVENT1(m,p1)
+#define LMP_TRACE_EVENT2(m,p1,p2)
+#define LMP_TRACE_EVENT3(m,p1,p2,p3)
+#define LMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LMP_TRACE_DEBUG0(m)
+#define LMP_TRACE_DEBUG1(m,p1)
+#define LMP_TRACE_DEBUG2(m,p1,p2)
+#define LMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define LMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the LC unit
+*/
+#define LC_TRACE_ERROR0(m)
+#define LC_TRACE_ERROR1(m,p1)
+#define LC_TRACE_ERROR2(m,p1,p2)
+#define LC_TRACE_ERROR3(m,p1,p2,p3)
+#define LC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define LC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_WARNING0(m)
+#define LC_TRACE_WARNING1(m,p1)
+#define LC_TRACE_WARNING2(m,p1,p2)
+#define LC_TRACE_WARNING3(m,p1,p2,p3)
+#define LC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define LC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_EVENT0(m)
+#define LC_TRACE_EVENT1(m,p1)
+#define LC_TRACE_EVENT2(m,p1,p2)
+#define LC_TRACE_EVENT3(m,p1,p2,p3)
+#define LC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define LC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define LC_TRACE_DEBUG0(m)
+#define LC_TRACE_DEBUG1(m,p1)
+#define LC_TRACE_DEBUG2(m,p1,p2)
+#define LC_TRACE_DEBUG3(m,p1,p2,p3)
+#define LC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define LC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define LC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_ERROR0(m)
+#define SDA_TRACE_ERROR1(m,p1)
+#define SDA_TRACE_ERROR2(m,p1,p2)
+#define SDA_TRACE_ERROR3(m,p1,p2,p3)
+#define SDA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SDA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_WARNING0(m)
+#define SDA_TRACE_WARNING1(m,p1)
+#define SDA_TRACE_WARNING2(m,p1,p2)
+#define SDA_TRACE_WARNING3(m,p1,p2,p3)
+#define SDA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SDA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_EVENT0(m)
+#define SDA_TRACE_EVENT1(m,p1)
+#define SDA_TRACE_EVENT2(m,p1,p2)
+#define SDA_TRACE_EVENT3(m,p1,p2,p3)
+#define SDA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SDA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SDA_TRACE_DEBUG0(m)
+#define SDA_TRACE_DEBUG1(m,p1)
+#define SDA_TRACE_DEBUG2(m,p1,p2)
+#define SDA_TRACE_DEBUG3(m,p1,p2,p3)
+#define SDA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SDA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SDA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* AVDTP
+*/
+#define AVDT_TRACE_ERROR0(m)
+#define AVDT_TRACE_ERROR1(m,p1)
+#define AVDT_TRACE_ERROR2(m,p1,p2)
+#define AVDT_TRACE_ERROR3(m,p1,p2,p3)
+#define AVDT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_WARNING0(m)
+#define AVDT_TRACE_WARNING1(m,p1)
+#define AVDT_TRACE_WARNING2(m,p1,p2)
+#define AVDT_TRACE_WARNING3(m,p1,p2,p3)
+#define AVDT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_EVENT0(m)
+#define AVDT_TRACE_EVENT1(m,p1)
+#define AVDT_TRACE_EVENT2(m,p1,p2)
+#define AVDT_TRACE_EVENT3(m,p1,p2,p3)
+#define AVDT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_DEBUG0(m)
+#define AVDT_TRACE_DEBUG1(m,p1)
+#define AVDT_TRACE_DEBUG2(m,p1,p2)
+#define AVDT_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVDT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVDT_TRACE_API0(m)
+#define AVDT_TRACE_API1(m,p1)
+#define AVDT_TRACE_API2(m,p1,p2)
+#define AVDT_TRACE_API3(m,p1,p2,p3)
+#define AVDT_TRACE_API4(m,p1,p2,p3,p4)
+#define AVDT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVDT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the AVCTP protocol
+*/
+#define AVCT_TRACE_ERROR0(m)
+#define AVCT_TRACE_ERROR1(m,p1)
+#define AVCT_TRACE_ERROR2(m,p1,p2)
+#define AVCT_TRACE_ERROR3(m,p1,p2,p3)
+#define AVCT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_WARNING0(m)
+#define AVCT_TRACE_WARNING1(m,p1)
+#define AVCT_TRACE_WARNING2(m,p1,p2)
+#define AVCT_TRACE_WARNING3(m,p1,p2,p3)
+#define AVCT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_EVENT0(m)
+#define AVCT_TRACE_EVENT1(m,p1)
+#define AVCT_TRACE_EVENT2(m,p1,p2)
+#define AVCT_TRACE_EVENT3(m,p1,p2,p3)
+#define AVCT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_DEBUG0(m)
+#define AVCT_TRACE_DEBUG1(m,p1)
+#define AVCT_TRACE_DEBUG2(m,p1,p2)
+#define AVCT_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVCT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVCT_TRACE_API0(m)
+#define AVCT_TRACE_API1(m,p1)
+#define AVCT_TRACE_API2(m,p1,p2)
+#define AVCT_TRACE_API3(m,p1,p2,p3)
+#define AVCT_TRACE_API4(m,p1,p2,p3,p4)
+#define AVCT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVCT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+
+/* Define tracing for the AVRCP profile
+*/
+#define AVRC_TRACE_ERROR0(m)
+#define AVRC_TRACE_ERROR1(m,p1)
+#define AVRC_TRACE_ERROR2(m,p1,p2)
+#define AVRC_TRACE_ERROR3(m,p1,p2,p3)
+#define AVRC_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_WARNING0(m)
+#define AVRC_TRACE_WARNING1(m,p1)
+#define AVRC_TRACE_WARNING2(m,p1,p2)
+#define AVRC_TRACE_WARNING3(m,p1,p2,p3)
+#define AVRC_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_EVENT0(m)
+#define AVRC_TRACE_EVENT1(m,p1)
+#define AVRC_TRACE_EVENT2(m,p1,p2)
+#define AVRC_TRACE_EVENT3(m,p1,p2,p3)
+#define AVRC_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_DEBUG0(m)
+#define AVRC_TRACE_DEBUG1(m,p1)
+#define AVRC_TRACE_DEBUG2(m,p1,p2)
+#define AVRC_TRACE_DEBUG3(m,p1,p2,p3)
+#define AVRC_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define AVRC_TRACE_API0(m)
+#define AVRC_TRACE_API1(m,p1)
+#define AVRC_TRACE_API2(m,p1,p2)
+#define AVRC_TRACE_API3(m,p1,p2,p3)
+#define AVRC_TRACE_API4(m,p1,p2,p3,p4)
+#define AVRC_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AVRC_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* MCAP
+*/
+#define MCA_TRACE_ERROR0(m)
+#define MCA_TRACE_ERROR1(m,p1)
+#define MCA_TRACE_ERROR2(m,p1,p2)
+#define MCA_TRACE_ERROR3(m,p1,p2,p3)
+#define MCA_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define MCA_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_WARNING0(m)
+#define MCA_TRACE_WARNING1(m,p1)
+#define MCA_TRACE_WARNING2(m,p1,p2)
+#define MCA_TRACE_WARNING3(m,p1,p2,p3)
+#define MCA_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define MCA_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_EVENT0(m)
+#define MCA_TRACE_EVENT1(m,p1)
+#define MCA_TRACE_EVENT2(m,p1,p2)
+#define MCA_TRACE_EVENT3(m,p1,p2,p3)
+#define MCA_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define MCA_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_DEBUG0(m)
+#define MCA_TRACE_DEBUG1(m,p1)
+#define MCA_TRACE_DEBUG2(m,p1,p2)
+#define MCA_TRACE_DEBUG3(m,p1,p2,p3)
+#define MCA_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define MCA_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#define MCA_TRACE_API0(m)
+#define MCA_TRACE_API1(m,p1)
+#define MCA_TRACE_API2(m,p1,p2)
+#define MCA_TRACE_API3(m,p1,p2,p3)
+#define MCA_TRACE_API4(m,p1,p2,p3,p4)
+#define MCA_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define MCA_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the AMP unit
+*/
+#define AMP_TRACE_ERROR0(m)
+#define AMP_TRACE_ERROR1(m,p1)
+#define AMP_TRACE_ERROR2(m,p1,p2)
+#define AMP_TRACE_ERROR3(m,p1,p2,p3)
+#define AMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define AMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_WARNING0(m)
+#define AMP_TRACE_WARNING1(m,p1)
+#define AMP_TRACE_WARNING2(m,p1,p2)
+#define AMP_TRACE_WARNING3(m,p1,p2,p3)
+#define AMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define AMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_API0(m)
+#define AMP_TRACE_API1(m,p1)
+#define AMP_TRACE_API2(m,p1,p2)
+#define AMP_TRACE_API3(m,p1,p2,p3)
+#define AMP_TRACE_API4(m,p1,p2,p3,p4)
+#define AMP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_EVENT0(m)
+#define AMP_TRACE_EVENT1(m,p1)
+#define AMP_TRACE_EVENT2(m,p1,p2)
+#define AMP_TRACE_EVENT3(m,p1,p2,p3)
+#define AMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define AMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define AMP_TRACE_DEBUG0(m)
+#define AMP_TRACE_DEBUG1(m,p1)
+#define AMP_TRACE_DEBUG2(m,p1,p2)
+#define AMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define AMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define AMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define AMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the GATT
+*/
+#define GATT_TRACE_ERROR0(m)
+#define GATT_TRACE_ERROR1(m,p1)
+#define GATT_TRACE_ERROR2(m,p1,p2)
+#define GATT_TRACE_ERROR3(m,p1,p2,p3)
+#define GATT_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define GATT_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_WARNING0(m)
+#define GATT_TRACE_WARNING1(m,p1)
+#define GATT_TRACE_WARNING2(m,p1,p2)
+#define GATT_TRACE_WARNING3(m,p1,p2,p3)
+#define GATT_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define GATT_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_API0(m)
+#define GATT_TRACE_API1(m,p1)
+#define GATT_TRACE_API2(m,p1,p2)
+#define GATT_TRACE_API3(m,p1,p2,p3)
+#define GATT_TRACE_API4(m,p1,p2,p3,p4)
+#define GATT_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_EVENT0(m)
+#define GATT_TRACE_EVENT1(m,p1)
+#define GATT_TRACE_EVENT2(m,p1,p2)
+#define GATT_TRACE_EVENT3(m,p1,p2,p3)
+#define GATT_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define GATT_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define GATT_TRACE_DEBUG0(m)
+#define GATT_TRACE_DEBUG1(m,p1)
+#define GATT_TRACE_DEBUG2(m,p1,p2)
+#define GATT_TRACE_DEBUG3(m,p1,p2,p3)
+#define GATT_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define GATT_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define GATT_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+/* Define tracing for the SMP unit
+*/
+#define SMP_TRACE_ERROR0(m)
+#define SMP_TRACE_ERROR1(m,p1)
+#define SMP_TRACE_ERROR2(m,p1,p2)
+#define SMP_TRACE_ERROR3(m,p1,p2,p3)
+#define SMP_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define SMP_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_WARNING0(m)
+#define SMP_TRACE_WARNING1(m,p1)
+#define SMP_TRACE_WARNING2(m,p1,p2)
+#define SMP_TRACE_WARNING3(m,p1,p2,p3)
+#define SMP_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define SMP_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_API0(m)
+#define SMP_TRACE_API1(m,p1)
+#define SMP_TRACE_API2(m,p1,p2)
+#define SMP_TRACE_API3(m,p1,p2,p3)
+#define SMP_TRACE_API4(m,p1,p2,p3,p4)
+#define SMP_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_EVENT0(m)
+#define SMP_TRACE_EVENT1(m,p1)
+#define SMP_TRACE_EVENT2(m,p1,p2)
+#define SMP_TRACE_EVENT3(m,p1,p2,p3)
+#define SMP_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define SMP_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define SMP_TRACE_DEBUG0(m)
+#define SMP_TRACE_DEBUG1(m,p1)
+#define SMP_TRACE_DEBUG2(m,p1,p2)
+#define SMP_TRACE_DEBUG3(m,p1,p2,p3)
+#define SMP_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define SMP_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define SMP_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
+
+/* define traces for application */
+#define APPL_TRACE_ERROR0(m)                    {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, (m));}
+#define APPL_TRACE_ERROR1(m,p1)                 {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_ERROR2(m,p1,p2)              {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_ERROR3(m,p1,p2,p3)           {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_ERROR4(m,p1,p2,p3,p4)        {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)     {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)  {if (appl_trace_level >= BT_TRACE_LEVEL_ERROR) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_ERROR, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_WARNING0(m)                  {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, (m));}
+#define APPL_TRACE_WARNING1(m,p1)               {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_WARNING2(m,p1,p2)            {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_WARNING3(m,p1,p2,p3)         {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_WARNING4(m,p1,p2,p3,p4)      {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)   {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6) {if (appl_trace_level >= BT_TRACE_LEVEL_WARNING) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_WARNING, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_API0(m)                      {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, (m));}
+#define APPL_TRACE_API1(m,p1)                   {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_API2(m,p1,p2)                {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_API3(m,p1,p2,p3)             {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_API4(m,p1,p2,p3,p4)          {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_API5(m,p1,p2,p3,p4,p5)       {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_API6(m,p1,p2,p3,p4,p5,p6)    {if (appl_trace_level >= BT_TRACE_LEVEL_API) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_API, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_EVENT0(m)                    {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, (m));}
+#define APPL_TRACE_EVENT1(m,p1)                 {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_EVENT2(m,p1,p2)              {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_EVENT3(m,p1,p2,p3)           {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_EVENT4(m,p1,p2,p3,p4)        {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_EVENT5(m,p1,p2,p3,p4,p5)     {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)  {if (appl_trace_level >= BT_TRACE_LEVEL_EVENT) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_EVENT, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+
+#define APPL_TRACE_DEBUG0(m)                    {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_0(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, (m));}
+#define APPL_TRACE_DEBUG1(m,p1)                 {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_1(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1));}
+#define APPL_TRACE_DEBUG2(m,p1,p2)              {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_2(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2));}
+#define APPL_TRACE_DEBUG3(m,p1,p2,p3)           {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_3(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3));}
+#define APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)        {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_4(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4));}
+#define APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)     {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_5(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5));}
+#define APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)  {if (appl_trace_level >= BT_TRACE_LEVEL_DEBUG) LogMsg_6(TRACE_CTRL_GENERAL | TRACE_LAYER_NONE | TRACE_ORG_APPL | TRACE_TYPE_DEBUG, \
+                                                        (m), (UINT32)(p1), (UINT32)(p2), (UINT32)(p3), (UINT32)(p4), (UINT32)(p5), (UINT32)(p6));}
+#else
+/* define traces for Application */
+
+#define APPL_TRACE_ERROR0(m)
+#define APPL_TRACE_ERROR1(m,p1)
+#define APPL_TRACE_ERROR2(m,p1,p2)
+#define APPL_TRACE_ERROR3(m,p1,p2,p3)
+#define APPL_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_WARNING0(m)
+#define APPL_TRACE_WARNING1(m,p1)
+#define APPL_TRACE_WARNING2(m,p1,p2)
+#define APPL_TRACE_WARNING3(m,p1,p2,p3)
+#define APPL_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_API0(m)
+#define APPL_TRACE_API1(m,p1)
+#define APPL_TRACE_API2(m,p1,p2)
+#define APPL_TRACE_API3(m,p1,p2,p3)
+#define APPL_TRACE_API4(m,p1,p2,p3,p4)
+#define APPL_TRACE_API5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_API6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_EVENT0(m)
+#define APPL_TRACE_EVENT1(m,p1)
+#define APPL_TRACE_EVENT2(m,p1,p2)
+#define APPL_TRACE_EVENT3(m,p1,p2,p3)
+#define APPL_TRACE_EVENT4(m,p1,p2,p3,p4)
+#define APPL_TRACE_EVENT5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_EVENT6(m,p1,p2,p3,p4,p5,p6)
+
+#define APPL_TRACE_DEBUG0(m)
+#define APPL_TRACE_DEBUG1(m,p1)
+#define APPL_TRACE_DEBUG2(m,p1,p2)
+#define APPL_TRACE_DEBUG3(m,p1,p2,p3)
+#define APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#if ((MMI_INCLUDED == TRUE) && (!defined(HID_MSKB_INCLUDED) || (HID_MSKB_INCLUDED == FALSE)))
+/* UI for sample applications */
+#define SAP_TRACE_0(m)                            MMI_Echo(m)
+#define SAP_TRACE_1(m,p1)                         MMI_Echo(m,p1)
+#define SAP_TRACE_2(m,p1,p2)                      MMI_Echo(m,p1,p2)
+#define SAP_TRACE_3(m,p1,p2,p3)                   MMI_Echo(m,p1,p2,p3)
+#define SAP_TRACE_4(m,p1,p2,p3,p4)                MMI_Echo(m,p1,p2,p3,p4)
+#define SAP_TRACE_5(m,p1,p2,p3,p4,p5)             MMI_Echo(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_6(m,p1,p2,p3,p4,p5,p6)          MMI_Echo(m,p1,p2,p3,p4,p5,p6)
+#else
+#define SAP_TRACE_0(m)
+#define SAP_TRACE_1(m,p1)
+#define SAP_TRACE_2(m,p1,p2)
+#define SAP_TRACE_3(m,p1,p2,p3)
+#define SAP_TRACE_4(m,p1,p2,p3,p4)
+#define SAP_TRACE_5(m,p1,p2,p3,p4,p5)
+#define SAP_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#endif  /* End of MMI_INCLUDED */
+#if defined(DRV_DEBUG_MSG) && (DRV_DEBUG_MSG == TRUE)
+/* Driver Trace macros
+*/
+#define DRV_TRACE_WARNING0(m)                      APPL_TRACE_WARNING0(m)
+#define DRV_TRACE_WARNING1(m,p1)                   APPL_TRACE_WARNING1(m,p1)
+#define DRV_TRACE_WARNING2(m,p1,p2)                APPL_TRACE_WARNING2(m,p1,p2)
+#define DRV_TRACE_WARNING3(m,p1,p2,p3)             APPL_TRACE_WARNING3(m,p1,p2,p3)
+#define DRV_TRACE_WARNING4(m,p1,p2,p3,p4)          APPL_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DRV_TRACE_WARNING5(m,p1,p2,p3,p4,p5)       APPL_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)    APPL_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+#else
+/* Driver Trace macros
+*/
+#define DRV_TRACE_WARNING0(m)
+#define DRV_TRACE_WARNING1(m,p1)
+#define DRV_TRACE_WARNING2(m,p1,p2)
+#define DRV_TRACE_WARNING3(m,p1,p2,p3)
+#define DRV_TRACE_WARNING4(m,p1,p2,p3,p4)
+#define DRV_TRACE_WARNING5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_WARNING6(m,p1,p2,p3,p4,p5,p6)
+#endif
+
+#define DRV_TRACE_ERROR0(m)                      APPL_TRACE_ERROR0(m)
+#define DRV_TRACE_ERROR1(m,p1)                   APPL_TRACE_ERROR1(m,p1)
+#define DRV_TRACE_ERROR2(m,p1,p2)                APPL_TRACE_ERROR2(m,p1,p2)
+#define DRV_TRACE_ERROR3(m,p1,p2,p3)             APPL_TRACE_ERROR3(m,p1,p2,p3)
+#define DRV_TRACE_ERROR4(m,p1,p2,p3,p4)          APPL_TRACE_ERROR4(m,p1,p2,p3,p4)
+#define DRV_TRACE_ERROR5(m,p1,p2,p3,p4,p5)       APPL_TRACE_ERROR5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)    APPL_TRACE_ERROR6(m,p1,p2,p3,p4,p5,p6)
+
+/* Driver Trace macros
+*/
+#define DRV_TRACE_DEBUG0(m)                    APPL_TRACE_DEBUG0(m)
+#define DRV_TRACE_DEBUG1(m,p1)                 APPL_TRACE_DEBUG1(m,p1)
+#define DRV_TRACE_DEBUG2(m,p1,p2)              APPL_TRACE_DEBUG2(m,p1,p2)
+#define DRV_TRACE_DEBUG3(m,p1,p2,p3)           APPL_TRACE_DEBUG3(m,p1,p2,p3)
+#define DRV_TRACE_DEBUG4(m,p1,p2,p3,p4)        APPL_TRACE_DEBUG4(m,p1,p2,p3,p4)
+#define DRV_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)     APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5)
+#define DRV_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)  APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6)
+
+
+#endif /* BT_TRACE_H */
+
+
diff --git a/src/include/bt_types.h b/src/include/bt_types.h
new file mode 100644
index 0000000..2b0e809
--- /dev/null
+++ b/src/include/bt_types.h
@@ -0,0 +1,702 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 BT_TYPES_H
+#define BT_TYPES_H
+
+#include "data_types.h"
+
+#ifdef _WIN32
+#ifdef BLUESTACK_TESTER
+    #include "bte_stack_entry.h"
+#endif
+#endif
+
+/* READ WELL !!
+**
+** This section defines global events. These are events that cross layers.
+** Any event that passes between layers MUST be one of these events. Tasks
+** can use their own events internally, but a FUNDAMENTAL design issue is
+** that global events MUST be one of these events defined below.
+**
+** The convention used is the the event name contains the layer that the
+** event is going to.
+*/
+#define BT_EVT_MASK                 0xFF00
+#define BT_SUB_EVT_MASK             0x00FF
+                                                /* To Bluetooth Upper Layers        */
+                                                /************************************/
+#define BT_EVT_TO_BTU_L2C_EVT       0x0900      /* L2CAP event */
+#define BT_EVT_TO_BTU_HCI_EVT       0x1000      /* HCI Event                        */
+#define BT_EVT_TO_BTU_HCI_BR_EDR_EVT (0x0000 | BT_EVT_TO_BTU_HCI_EVT)      /* event from BR/EDR controller */
+#define BT_EVT_TO_BTU_HCI_AMP1_EVT   (0x0001 | BT_EVT_TO_BTU_HCI_EVT)      /* event from local AMP 1 controller */
+#define BT_EVT_TO_BTU_HCI_AMP2_EVT   (0x0002 | BT_EVT_TO_BTU_HCI_EVT)      /* event from local AMP 2 controller */
+#define BT_EVT_TO_BTU_HCI_AMP3_EVT   (0x0003 | BT_EVT_TO_BTU_HCI_EVT)      /* event from local AMP 3 controller */
+
+#define BT_EVT_TO_BTU_HCI_ACL       0x1100      /* ACL Data from HCI                */
+#define BT_EVT_TO_BTU_HCI_SCO       0x1200      /* SCO Data from HCI                */
+#define BT_EVT_TO_BTU_HCIT_ERR      0x1300      /* HCI Transport Error              */
+
+#define BT_EVT_TO_BTU_SP_EVT        0x1400      /* Serial Port Event                */
+#define BT_EVT_TO_BTU_SP_DATA       0x1500      /* Serial Port Data                 */
+
+#define BT_EVT_TO_BTU_HCI_CMD       0x1600      /* HCI command from upper layer     */
+
+
+#define BT_EVT_TO_BTU_L2C_SEG_XMIT  0x1900      /* L2CAP segment(s) transmitted     */
+
+#define BT_EVT_PROXY_INCOMING_MSG   0x1A00      /* BlueStackTester event: incoming message from target */
+
+#define BT_EVT_BTSIM                0x1B00      /* Insight BTSIM event */
+#define BT_EVT_BTISE                0x1C00      /* Insight Script Engine event */
+
+                                                /* To LM                            */
+                                                /************************************/
+#define BT_EVT_TO_LM_HCI_CMD        0x2000      /* HCI Command                      */
+#define BT_EVT_TO_LM_HCI_ACL        0x2100      /* HCI ACL Data                     */
+#define BT_EVT_TO_LM_HCI_SCO        0x2200      /* HCI SCO Data                     */
+#define BT_EVT_TO_LM_HCIT_ERR       0x2300      /* HCI Transport Error              */
+#define BT_EVT_TO_LM_LC_EVT         0x2400      /* LC event                         */
+#define BT_EVT_TO_LM_LC_LMP         0x2500      /* LC Received LMP command frame    */
+#define BT_EVT_TO_LM_LC_ACL         0x2600      /* LC Received ACL data             */
+#define BT_EVT_TO_LM_LC_SCO         0x2700      /* LC Received SCO data  (not used) */
+#define BT_EVT_TO_LM_LC_ACL_TX      0x2800      /* LMP data transmit complete       */
+#define BT_EVT_TO_LM_LC_LMPC_TX     0x2900      /* LMP Command transmit complete    */
+#define BT_EVT_TO_LM_LOCAL_ACL_LB   0x2a00      /* Data to be locally loopbacked    */
+#define BT_EVT_TO_LM_HCI_ACL_ACK    0x2b00      /* HCI ACL Data ack      (not used) */
+#define BT_EVT_TO_LM_DIAG           0x2c00      /* LM Diagnostics commands          */
+
+
+#define BT_EVT_TO_BTM_CMDS          0x2f00
+#define BT_EVT_TO_BTM_PM_MDCHG_EVT (0x0001 | BT_EVT_TO_BTM_CMDS)
+
+#define BT_EVT_TO_TCS_CMDS          0x3000
+
+#define BT_EVT_TO_OBX_CL_MSG        0x3100
+#define BT_EVT_TO_OBX_SR_MSG        0x3200
+
+#define BT_EVT_TO_CTP_CMDS          0x3300
+
+/* Obex Over L2CAP */
+#define BT_EVT_TO_OBX_CL_L2C_MSG    0x3400
+#define BT_EVT_TO_OBX_SR_L2C_MSG    0x3500
+
+/* ftp events */
+#define BT_EVT_TO_FTP_SRVR_CMDS     0x3600
+#define BT_EVT_TO_FTP_CLNT_CMDS     0x3700
+
+#define BT_EVT_TO_BTU_SAP           0x3800       /* SIM Access Profile events */
+
+/* opp events */
+#define BT_EVT_TO_OPP_SRVR_CMDS     0x3900
+#define BT_EVT_TO_OPP_CLNT_CMDS     0x3a00
+
+/* gap events */
+#define BT_EVT_TO_GAP_MSG           0x3b00
+
+/* start timer */
+#define BT_EVT_TO_START_TIMER       0x3c00
+
+/* stop timer */
+#define BT_EVT_TO_STOP_TIMER        0x3d00
+
+/* start quick timer */
+#define BT_EVT_TO_START_QUICK_TIMER 0x3e00
+
+
+/* for NFC                          */
+                                                /************************************/
+#define BT_EVT_TO_NFC_NCI           0x4000      /* NCI Command, Notification or Data*/
+#define BT_EVT_TO_NFC_NCI_VS        0x4200      /* Vendor specific message */
+#define BT_EVT_TO_NFC_MSGS          0x4300      /* messages between NFC and NCI task */
+
+#define BT_EVT_TO_NFCCSIM_NCI       0x4a00      /* events to NFCC simulation (NCI packets) */
+
+/* HCISU Events */
+
+#define BT_EVT_HCISU                0x5000
+
+#define BT_EVT_TO_HCISU_LP_APP_SLEEPING_EVT     (0x0005 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_ALLOW_BT_SLEEP_EVT   (0x0006 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_WAKEUP_HOST_EVT      (0x0007 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_LP_RCV_H4IBSS_EVT       (0x0008 | BT_EVT_HCISU)
+#define BT_EVT_TO_HCISU_H5_RESET_EVT            (0x0009 | BT_EVT_HCISU)
+#define BT_EVT_HCISU_START_QUICK_TIMER          (0x000a | BT_EVT_HCISU)
+
+#define BT_EVT_DATA_TO_AMP_1        0x5100
+#define BT_EVT_DATA_TO_AMP_15       0x5f00
+
+/* HSP Events */
+
+#define BT_EVT_BTU_HSP2             0x6000
+
+#define BT_EVT_TO_BTU_HSP2_EVT     (0x0001 | BT_EVT_BTU_HSP2)
+
+/* BPP Events */
+#define BT_EVT_TO_BPP_PR_CMDS       0x6100      /* Printer Events */
+#define BT_EVT_TO_BPP_SND_CMDS      0x6200      /* BPP Sender Events */
+
+/* BIP Events */
+#define BT_EVT_TO_BIP_CMDS          0x6300
+
+/* HCRP Events */
+
+#define BT_EVT_BTU_HCRP             0x7000
+
+#define BT_EVT_TO_BTU_HCRP_EVT     (0x0001 | BT_EVT_BTU_HCRP)
+#define BT_EVT_TO_BTU_HCRPM_EVT    (0x0002 | BT_EVT_BTU_HCRP)
+
+
+#define BT_EVT_BTU_HFP              0x8000
+#define BT_EVT_TO_BTU_HFP_EVT      (0x0001 | BT_EVT_BTU_HFP)
+
+#define BT_EVT_BTU_IPC_EVT          0x9000
+#define BT_EVT_BTU_IPC_LOGMSG_EVT  (0x0000 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_ACL_EVT     (0x0001 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTU_EVT     (0x0002 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_L2C_EVT     (0x0003 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_L2C_MSG_EVT (0x0004 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTM_EVT     (0x0005 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_AVDT_EVT    (0x0006 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_SLIP_EVT    (0x0007 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_MGMT_EVT    (0x0008 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BTTRC_EVT   (0x0009 | BT_EVT_BTU_IPC_EVT)
+#define BT_EVT_BTU_IPC_BURST_EVT   (0x000A | BT_EVT_BTU_IPC_EVT)
+
+/* Define the header of each buffer used in the Bluetooth stack.
+*/
+typedef struct
+{
+    UINT16          event;
+    UINT16          len;
+    UINT16          offset;
+    UINT16          layer_specific;
+} BT_HDR;
+
+#define BT_HDR_SIZE (sizeof (BT_HDR))
+
+#define BT_PSM_SDP                      0x0001
+#define BT_PSM_RFCOMM                   0x0003
+#define BT_PSM_TCS                      0x0005
+#define BT_PSM_CTP                      0x0007
+#define BT_PSM_BNEP                     0x000F
+#define BT_PSM_HIDC                     0x0011
+#define BT_PSM_HIDI                     0x0013
+#define BT_PSM_UPNP                     0x0015
+#define BT_PSM_AVCTP                    0x0017
+#define BT_PSM_AVDTP                    0x0019
+#define BT_PSM_AVCTP_13                 0x001B /* Advanced Control - Browsing */
+#define BT_PSM_UDI_CP                   0x001D /* Unrestricted Digital Information Profile C-Plane  */
+#define BT_PSM_ATT                      0x001F /* Attribute Protocol  */
+
+
+/* These macros extract the HCI opcodes from a buffer
+*/
+#define HCI_GET_CMD_HDR_OPCODE(p)    (UINT16)((*((UINT8 *)((p) + 1) + p->offset) + \
+                                              (*((UINT8 *)((p) + 1) + p->offset + 1) << 8)))
+#define HCI_GET_CMD_HDR_PARAM_LEN(p) (UINT8)  (*((UINT8 *)((p) + 1) + p->offset + 2))
+
+#define HCI_GET_EVT_HDR_OPCODE(p)    (UINT8)(*((UINT8 *)((p) + 1) + p->offset))
+#define HCI_GET_EVT_HDR_PARAM_LEN(p) (UINT8)  (*((UINT8 *)((p) + 1) + p->offset + 1))
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a stream (Little Endian format).
+*/
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (UINT8)(u32); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 24);}
+#define UINT24_TO_STREAM(p, u24) {*(p)++ = (UINT8)(u24); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)((u24) >> 16);}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (UINT8)(u16); *(p)++ = (UINT8)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define INT8_TO_STREAM(p, u8)    {*(p)++ = (INT8)(u8);}
+#define ARRAY32_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 32;           ijk++) *(p)++ = (UINT8) a[31 - ijk];}
+#define ARRAY16_TO_STREAM(p, a)  {register int ijk; for (ijk = 0; ijk < 16;           ijk++) *(p)++ = (UINT8) a[15 - ijk];}
+#define ARRAY8_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < 8;            ijk++) *(p)++ = (UINT8) a[7 - ijk];}
+#define BDADDR_TO_STREAM(p, a)   {register int ijk; for (ijk = 0; ijk < BD_ADDR_LEN;  ijk++) *(p)++ = (UINT8) a[BD_ADDR_LEN - 1 - ijk];}
+#define LAP_TO_STREAM(p, a)      {register int ijk; for (ijk = 0; ijk < LAP_LEN;      ijk++) *(p)++ = (UINT8) a[LAP_LEN - 1 - ijk];}
+#define DEVCLASS_TO_STREAM(p, a) {register int ijk; for (ijk = 0; ijk < DEV_CLASS_LEN;ijk++) *(p)++ = (UINT8) a[DEV_CLASS_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len;        ijk++) *(p)++ = (UINT8) a[ijk];}
+#define REVERSE_ARRAY_TO_STREAM(p, a, len)  {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - 1 - ijk];}
+
+#define STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define STREAM_TO_UINT16(u16, p) {u16 = ((UINT16)(*(p)) + (((UINT16)(*((p) + 1))) << 8)); (p) += 2;}
+#define STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) ); (p) += 3;}
+#define STREAM_TO_UINT32(u32, p) {u32 = (((UINT32)(*(p))) + ((((UINT32)(*((p) + 1)))) << 8) + ((((UINT32)(*((p) + 2)))) << 16) + ((((UINT32)(*((p) + 3)))) << 24)); (p) += 4;}
+#define STREAM_TO_BDADDR(a, p)   {register int ijk; register UINT8 *pbda = (UINT8 *)a + BD_ADDR_LEN - 1; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *pbda-- = *p++;}
+#define STREAM_TO_ARRAY32(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 31; for (ijk = 0; ijk < 32; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY16(a, p)  {register int ijk; register UINT8 *_pa = (UINT8 *)a + 15; for (ijk = 0; ijk < 16; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_ARRAY8(a, p)   {register int ijk; register UINT8 *_pa = (UINT8 *)a + 7; for (ijk = 0; ijk < 8; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_DEVCLASS(a, p) {register int ijk; register UINT8 *_pa = (UINT8 *)a + DEV_CLASS_LEN - 1; for (ijk = 0; ijk < DEV_CLASS_LEN; ijk++) *_pa-- = *p++;}
+#define STREAM_TO_LAP(a, p)      {register int ijk; register UINT8 *plap = (UINT8 *)a + LAP_LEN - 1; for (ijk = 0; ijk < LAP_LEN; ijk++) *plap-- = *p++;}
+#define STREAM_TO_ARRAY(a, p, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+#define REVERSE_STREAM_TO_ARRAY(a, p, len) {register int ijk; register UINT8 *_pa = (UINT8 *)a + len - 1; for (ijk = 0; ijk < len; ijk++) *_pa-- = *p++;}
+
+/********************************************************************************
+** Macros to get and put bytes to and from a field (Little Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*/
+#define UINT32_TO_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)(u32); *((UINT8 *)(p)+1) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+3) = (UINT8)((u32) >> 24);}
+#define UINT24_TO_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)(u24); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)((u24) >> 16);}
+#define UINT16_TO_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)(u16); *((UINT8 *)(p)+1) = (UINT8)((u16) >> 8);}
+#define UINT8_TO_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a stream (Big Endian format)
+*/
+#define UINT32_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 24);  *(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
+#define UINT24_TO_BE_STREAM(p, u24) {*(p)++ = (UINT8)((u24) >> 16); *(p)++ = (UINT8)((u24) >> 8); *(p)++ = (UINT8)(u24);}
+#define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);}
+#define UINT8_TO_BE_STREAM(p, u8)   {*(p)++ = (UINT8)(u8);}
+#define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];}
+
+#define BE_STREAM_TO_UINT8(u8, p)   {u8 = (UINT8)(*(p)); (p) += 1;}
+#define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;}
+#define BE_STREAM_TO_UINT24(u32, p) {u32 = (((UINT32)(*((p) + 2))) + ((UINT32)(*((p) + 1)) << 8) + ((UINT32)(*(p)) << 16)); (p) += 3;}
+#define BE_STREAM_TO_UINT32(u32, p) {u32 = ((UINT32)(*((p) + 3)) + ((UINT32)(*((p) + 2)) << 8) + ((UINT32)(*((p) + 1)) << 16) + ((UINT32)(*(p)) << 24)); (p) += 4;}
+#define BE_STREAM_TO_ARRAY(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) ((UINT8 *) a)[ijk] = *p++;}
+
+
+/********************************************************************************
+** Macros to get and put bytes to and from a field (Big Endian format).
+** These are the same as to stream, except the pointer is not incremented.
+*/
+#define UINT32_TO_BE_FIELD(p, u32) {*(UINT8 *)(p) = (UINT8)((u32) >> 24);  *((UINT8 *)(p)+1) = (UINT8)((u32) >> 16); *((UINT8 *)(p)+2) = (UINT8)((u32) >> 8); *((UINT8 *)(p)+3) = (UINT8)(u32); }
+#define UINT24_TO_BE_FIELD(p, u24) {*(UINT8 *)(p) = (UINT8)((u24) >> 16); *((UINT8 *)(p)+1) = (UINT8)((u24) >> 8); *((UINT8 *)(p)+2) = (UINT8)(u24);}
+#define UINT16_TO_BE_FIELD(p, u16) {*(UINT8 *)(p) = (UINT8)((u16) >> 8); *((UINT8 *)(p)+1) = (UINT8)(u16);}
+#define UINT8_TO_BE_FIELD(p, u8)   {*(UINT8 *)(p) = (UINT8)(u8);}
+
+
+/* Common Bluetooth field definitions */
+#define BD_ADDR_LEN     6                   /* Device address length */
+typedef UINT8 BD_ADDR[BD_ADDR_LEN];         /* Device address */
+typedef UINT8 *BD_ADDR_PTR;                 /* Pointer to Device Address */
+
+#define AMP_KEY_TYPE_GAMP       0
+#define AMP_KEY_TYPE_WIFI       1
+#define AMP_KEY_TYPE_UWB        2
+typedef UINT8 tAMP_KEY_TYPE;
+
+#define BT_OCTET8_LEN    8
+typedef UINT8 BT_OCTET8[BT_OCTET8_LEN];   /* octet array: size 16 */
+
+#define LINK_KEY_LEN    16
+typedef UINT8 LINK_KEY[LINK_KEY_LEN];       /* Link Key */
+
+#define AMP_LINK_KEY_LEN        32
+typedef UINT8 AMP_LINK_KEY[AMP_LINK_KEY_LEN];   /* Dedicated AMP and GAMP Link Keys */
+
+#define BT_OCTET16_LEN    16
+typedef UINT8 BT_OCTET16[BT_OCTET16_LEN];   /* octet array: size 16 */
+
+#define PIN_CODE_LEN    16
+typedef UINT8 PIN_CODE[PIN_CODE_LEN];       /* Pin Code (upto 128 bits) MSB is 0 */
+typedef UINT8 *PIN_CODE_PTR;                /* Pointer to Pin Code */
+
+#define DEV_CLASS_LEN   3
+typedef UINT8 DEV_CLASS[DEV_CLASS_LEN];     /* Device class */
+typedef UINT8 *DEV_CLASS_PTR;               /* Pointer to Device class */
+
+#define EXT_INQ_RESP_LEN   3
+typedef UINT8 EXT_INQ_RESP[EXT_INQ_RESP_LEN];/* Extended Inquiry Response */
+typedef UINT8 *EXT_INQ_RESP_PTR;             /* Pointer to Extended Inquiry Response */
+
+#define BD_NAME_LEN     248
+typedef UINT8 BD_NAME[BD_NAME_LEN + 1];         /* Device name */
+typedef UINT8 *BD_NAME_PTR;                 /* Pointer to Device name */
+
+#define BD_FEATURES_LEN 8
+typedef UINT8 BD_FEATURES[BD_FEATURES_LEN]; /* LMP features supported by device */
+
+#define BT_EVENT_MASK_LEN  8
+typedef UINT8 BT_EVENT_MASK[BT_EVENT_MASK_LEN];   /* Event Mask */
+
+#define LAP_LEN         3
+typedef UINT8 LAP[LAP_LEN];                 /* IAC as passed to Inquiry (LAP) */
+typedef UINT8 INQ_LAP[LAP_LEN];             /* IAC as passed to Inquiry (LAP) */
+
+#define RAND_NUM_LEN    16
+typedef UINT8 RAND_NUM[RAND_NUM_LEN];
+
+#define ACO_LEN         12
+typedef UINT8 ACO[ACO_LEN];                 /* Authenticated ciphering offset */
+
+#define COF_LEN         12
+typedef UINT8 COF[COF_LEN];                 /* ciphering offset number */
+
+typedef struct {
+    UINT8               qos_flags;          /* TBD */
+    UINT8               service_type;       /* see below */
+    UINT32              token_rate;         /* bytes/second */
+    UINT32              token_bucket_size;  /* bytes */
+    UINT32              peak_bandwidth;     /* bytes/second */
+    UINT32              latency;            /* microseconds */
+    UINT32              delay_variation;    /* microseconds */
+} FLOW_SPEC;
+
+/* Values for service_type */
+#define NO_TRAFFIC      0
+#define BEST_EFFORT     1
+#define GUARANTEED      2
+
+/* Service class of the CoD */
+#define SERV_CLASS_NETWORKING               (1 << 1)
+#define SERV_CLASS_RENDERING                (1 << 2)
+#define SERV_CLASS_CAPTURING                (1 << 3)
+#define SERV_CLASS_OBJECT_TRANSFER          (1 << 4)
+#define SERV_CLASS_OBJECT_AUDIO             (1 << 5)
+#define SERV_CLASS_OBJECT_TELEPHONY         (1 << 6)
+#define SERV_CLASS_OBJECT_INFORMATION       (1 << 7)
+
+/* Second byte */
+#define SERV_CLASS_LIMITED_DISC_MODE        (0x20)
+
+/* Field size definitions. Note that byte lengths are rounded up. */
+#define ACCESS_CODE_BIT_LEN             72
+#define ACCESS_CODE_BYTE_LEN            9
+#define SHORTENED_ACCESS_CODE_BIT_LEN   68
+
+typedef UINT8 ACCESS_CODE[ACCESS_CODE_BYTE_LEN];
+
+#define SYNTH_TX                1           /* want synth code to TRANSMIT at this freq */
+#define SYNTH_RX                2           /* want synth code to RECEIVE at this freq */
+
+#define SYNC_REPS 1             /* repeats of sync word transmitted to start of burst */
+
+/* Bluetooth CLK27 */
+#define BT_CLK27            (2 << 26)
+
+/* Bluetooth CLK12 is 1.28 sec */
+#define BT_CLK12_TO_MS(x)    ((x) * 1280)
+#define BT_MS_TO_CLK12(x)    ((x) / 1280)
+#define BT_CLK12_TO_SLOTS(x) ((x) << 11)
+
+/* Bluetooth CLK is 0.625 msec */
+#define BT_CLK_TO_MS(x)      (((x) * 5 + 3) / 8)
+#define BT_MS_TO_CLK(x)      (((x) * 8 + 2) / 5)
+
+#define BT_CLK_TO_MICROSECS(x)  (((x) * 5000 + 3) / 8)
+#define BT_MICROSECS_TO_CLK(x)  (((x) * 8 + 2499) / 5000)
+
+/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */
+#define MAX_UUID_SIZE              16
+typedef struct
+{
+#define LEN_UUID_16     2
+#define LEN_UUID_32     4
+#define LEN_UUID_128    16
+
+    UINT16          len;
+
+    union
+    {
+        UINT16      uuid16;
+        UINT32      uuid32;
+        UINT8       uuid128[MAX_UUID_SIZE];
+    } uu;
+
+} tBT_UUID;
+
+#define BT_EIR_FLAGS_TYPE                   0x01
+#define BT_EIR_MORE_16BITS_UUID_TYPE        0x02
+#define BT_EIR_COMPLETE_16BITS_UUID_TYPE    0x03
+#define BT_EIR_MORE_32BITS_UUID_TYPE        0x04
+#define BT_EIR_COMPLETE_32BITS_UUID_TYPE    0x05
+#define BT_EIR_MORE_128BITS_UUID_TYPE       0x06
+#define BT_EIR_COMPLETE_128BITS_UUID_TYPE   0x07
+#define BT_EIR_SHORTENED_LOCAL_NAME_TYPE    0x08
+#define BT_EIR_COMPLETE_LOCAL_NAME_TYPE     0x09
+#define BT_EIR_TX_POWER_LEVEL_TYPE          0x0A
+#define BT_EIR_OOB_BD_ADDR_TYPE             0x0C
+#define BT_EIR_OOB_COD_TYPE                 0x0D
+#define BT_EIR_OOB_SSP_HASH_C_TYPE          0x0E
+#define BT_EIR_OOB_SSP_RAND_R_TYPE          0x0F
+#define BT_EIR_MANUFACTURER_SPECIFIC_TYPE   0xFF
+
+#define BT_OOB_COD_SIZE            3
+#define BT_OOB_HASH_C_SIZE         16
+#define BT_OOB_RAND_R_SIZE         16
+
+/* Broadcom proprietary UUIDs and reserved PSMs
+**
+** The lowest 4 bytes byte of the UUID or GUID depends on the feature. Typically,
+** the value of those bytes will be the PSM or SCN, but it is up to the features.
+*/
+#define BRCM_PROPRIETARY_UUID_BASE  0xDA, 0x23, 0x41, 0x02, 0xA3, 0xBB, 0xC1, 0x71, 0xBA, 0x09, 0x6f, 0x21
+#define BRCM_PROPRIETARY_GUID_BASE  0xda23, 0x4102, 0xa3, 0xbb, 0xc1, 0x71, 0xba, 0x09, 0x6f, 0x21
+
+/* We will not allocate a PSM in the reserved range to 3rd party apps
+*/
+#define BRCM_RESERVED_PSM_START	    0x5AE1
+#define BRCM_RESERVED_PSM_END	    0x5AFF
+
+#define BRCM_UTILITY_SERVICE_PSM    0x5AE1
+#define BRCM_MATCHER_PSM            0x5AE3
+
+/* Connection statistics
+*/
+
+/* Structure to hold connection stats */
+#ifndef BT_CONN_STATS_DEFINED
+#define BT_CONN_STATS_DEFINED
+
+/* These bits are used in the bIsConnected field */
+#define BT_CONNECTED_USING_BREDR   1
+#define BT_CONNECTED_USING_AMP     2
+
+typedef struct
+{
+    UINT32   is_connected;
+    INT32    rssi;
+    UINT32   bytes_sent;
+    UINT32   bytes_rcvd;
+    UINT32   duration;
+} tBT_CONN_STATS;
+
+#endif
+
+/* AMP transport selection criteria definitions.
+** NOTE: if underlying L2CAP connection uses basic mode than it can use only BR/EDR.
+**       For such L2CAP connections AMP connection the criteria provided by application
+**       is reset by AMP manager to AMP_USE_AMP_NEVER.
+*/
+#define AMP_USE_AMP_NEVER                      0   /* Connection only via BR/EDR controller, no AMP allowed        */
+#define AMP_USE_AMP_IF_PEER_TRIES_IT           1   /* Allow AMP to be used if the peer tries to use it             */
+#define AMP_USE_AMP_IF_PHY_CONN_EXISTS         2   /* Use AMP if there is already a physical connection (default)  */
+#define AMP_USE_AMP_IF_LC_POWER_ON             3   /* Only try to use AMP if the Local Controller is powered on    */
+#define AMP_USE_AMP_IF_LC_AND_PEER_POWER_ON    4   /* Only try to use AMP if both LC and peer are powered on       */
+#define AMP_USE_AMP_IF_POSSIBLE                5   /* Try to use AMP if at all possible                            */
+#define AMP_USE_AMP_ONLY                       6   /* Only use AMP, never use BR/EDR                               */
+#define AMP_USE_AMP_MAX_DEF            AMP_USE_AMP_ONLY /* Maximum enum defined for AMP Criteria                        */
+
+#define	AMP_AUTOSWITCH_ALLOWED 		           0x80000000  /* flag to indicate that this connection is auto-switch ready */
+#define AMP_USE_CURRENT_CRITERIA               0xFFFFFFFF  /* Flag if previous criteria was to be still used        */
+
+typedef UINT32 tAMP_CRITERIA;
+
+
+/*****************************************************************************
+**                          Low Energy definitions
+**
+** Address types
+*/
+#define BLE_ADDR_PUBLIC         0x00
+#define BLE_ADDR_RANDOM         0x01
+#define BLE_ADDR_TYPE_MASK      (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
+typedef UINT8 tBLE_ADDR_TYPE;
+
+#define BLE_ADDR_IS_STATIC(x)   ((x[0] & 0xC0) == 0xC0)
+
+typedef struct
+{
+    tBLE_ADDR_TYPE      type;
+    BD_ADDR             bda;
+} tBLE_BD_ADDR;
+
+/* Device Types
+*/
+#define BT_DEVICE_TYPE_BREDR   0x01
+#define BT_DEVICE_TYPE_BLE     0x02
+#define BT_DEVICE_TYPE_DUMO    0x03
+typedef UINT8 tBT_DEVICE_TYPE;
+/*****************************************************************************/
+
+
+/* Define trace levels */
+#define BT_TRACE_LEVEL_NONE    0          /* No trace messages to be generated    */
+#define BT_TRACE_LEVEL_ERROR   1          /* Error condition trace messages       */
+#define BT_TRACE_LEVEL_WARNING 2          /* Warning condition trace messages     */
+#define BT_TRACE_LEVEL_API     3          /* API traces                           */
+#define BT_TRACE_LEVEL_EVENT   4          /* Debug messages for events            */
+#define BT_TRACE_LEVEL_DEBUG   5          /* Full debug messages                  */
+
+#define MAX_TRACE_LEVEL        5
+
+
+/* Define New Trace Type Definition */
+/* TRACE_CTRL_TYPE                  0x^^000000*/
+#define TRACE_CTRL_MASK             0xff000000
+#define TRACE_GET_CTRL(x)           ((((UINT32)(x)) & TRACE_CTRL_MASK) >> 24)
+
+#define TRACE_CTRL_GENERAL          0x00000000
+#define TRACE_CTRL_STR_RESOURCE     0x01000000
+#define TRACE_CTRL_SEQ_FLOW         0x02000000
+#define TRACE_CTRL_MAX_NUM          3
+
+/* LAYER SPECIFIC                   0x00^^0000*/
+#define TRACE_LAYER_MASK            0x00ff0000
+#define TRACE_GET_LAYER(x)          ((((UINT32)(x)) & TRACE_LAYER_MASK) >> 16)
+
+#define TRACE_LAYER_NONE            0x00000000
+#define TRACE_LAYER_USB             0x00010000
+#define TRACE_LAYER_SERIAL          0x00020000
+#define TRACE_LAYER_SOCKET          0x00030000
+#define TRACE_LAYER_RS232           0x00040000
+#define TRACE_LAYER_TRANS_MAX_NUM   5
+#define TRACE_LAYER_TRANS_ALL       0x007f0000
+#define TRACE_LAYER_LC              0x00050000
+#define TRACE_LAYER_LM              0x00060000
+#define TRACE_LAYER_HCI             0x00070000
+#define TRACE_LAYER_L2CAP           0x00080000
+#define TRACE_LAYER_RFCOMM          0x00090000
+#define TRACE_LAYER_SDP             0x000a0000
+#define TRACE_LAYER_TCS             0x000b0000
+#define TRACE_LAYER_OBEX            0x000c0000
+#define TRACE_LAYER_BTM             0x000d0000
+#define TRACE_LAYER_GAP             0x000e0000
+#define TRACE_LAYER_DUN             0x000f0000
+#define TRACE_LAYER_GOEP            0x00100000
+#define TRACE_LAYER_ICP             0x00110000
+#define TRACE_LAYER_HSP2            0x00120000
+#define TRACE_LAYER_SPP             0x00130000
+#define TRACE_LAYER_CTP             0x00140000
+#define TRACE_LAYER_BPP             0x00150000
+#define TRACE_LAYER_HCRP            0x00160000
+#define TRACE_LAYER_FTP             0x00170000
+#define TRACE_LAYER_OPP             0x00180000
+#define TRACE_LAYER_BTU             0x00190000
+#define TRACE_LAYER_GKI             0x001a0000
+#define TRACE_LAYER_BNEP            0x001b0000
+#define TRACE_LAYER_PAN             0x001c0000
+#define TRACE_LAYER_HFP             0x001d0000
+#define TRACE_LAYER_HID             0x001e0000
+#define TRACE_LAYER_BIP             0x001f0000
+#define TRACE_LAYER_AVP             0x00200000
+#define TRACE_LAYER_A2D             0x00210000
+#define TRACE_LAYER_SAP             0x00220000
+#define TRACE_LAYER_AMP             0x00230000
+#define TRACE_LAYER_MCA             0x00240000
+#define TRACE_LAYER_ATT             0x00250000
+#define TRACE_LAYER_SMP             0x00260000
+#define TRACE_LAYER_NFC             0x00270000
+#define TRACE_LAYER_NCI             0x00280000
+#define TRACE_LAYER_LLCP            0x00290000
+#define TRACE_LAYER_NDEF            0x002a0000
+#define TRACE_LAYER_RW              0x002b0000
+#define TRACE_LAYER_CE              0x002c0000
+#define TRACE_LAYER_P2P             0x002d0000
+#define TRACE_LAYER_SNEP            0x002e0000
+#define TRACE_LAYER_CHO             0x002f0000
+#define TRACE_LAYER_NFA             0x00300000
+
+#define TRACE_LAYER_MAX_NUM         0x0031
+
+
+/* TRACE_ORIGINATOR                 0x0000^^00*/
+#define TRACE_ORG_MASK              0x0000ff00
+#define TRACE_GET_ORG(x)            ((((UINT32)(x)) & TRACE_ORG_MASK) >> 8)
+
+#define TRACE_ORG_STACK             0x00000000
+#define TRACE_ORG_HCI_TRANS         0x00000100
+#define TRACE_ORG_PROTO_DISP        0x00000200
+#define TRACE_ORG_RPC               0x00000300
+#define TRACE_ORG_GKI               0x00000400
+#define TRACE_ORG_APPL              0x00000500
+#define TRACE_ORG_SCR_WRAPPER       0x00000600
+#define TRACE_ORG_SCR_ENGINE        0x00000700
+#define TRACE_ORG_USER_SCR          0x00000800
+#define TRACE_ORG_TESTER            0x00000900
+#define TRACE_ORG_MAX_NUM           10          /* 32-bit mask; must be < 32 */
+#define TRACE_LITE_ORG_MAX_NUM		6
+#define TRACE_ORG_ALL               0x03ff
+#define TRACE_ORG_RPC_TRANS         0x04
+
+#define TRACE_ORG_REG               0x00000909
+#define TRACE_ORG_REG_SUCCESS       0x0000090a
+
+/* TRACE_TYPE                       0x000000^^*/
+#define TRACE_TYPE_MASK             0x000000ff
+#define TRACE_GET_TYPE(x)           (((UINT32)(x)) & TRACE_TYPE_MASK)
+
+#define TRACE_TYPE_ERROR            0x00000000
+#define TRACE_TYPE_WARNING          0x00000001
+#define TRACE_TYPE_API              0x00000002
+#define TRACE_TYPE_EVENT            0x00000003
+#define TRACE_TYPE_DEBUG            0x00000004
+#define TRACE_TYPE_STACK_ONLY_MAX   TRACE_TYPE_DEBUG
+#define TRACE_TYPE_TX               0x00000005
+#define TRACE_TYPE_RX               0x00000006
+#define TRACE_TYPE_DEBUG_ASSERT     0x00000007
+#define TRACE_TYPE_GENERIC          0x00000008
+#define TRACE_TYPE_REG              0x00000009
+#define TRACE_TYPE_REG_SUCCESS      0x0000000a
+#define TRACE_TYPE_CMD_TX           0x0000000b
+#define TRACE_TYPE_EVT_TX           0x0000000c
+#define TRACE_TYPE_ACL_TX           0x0000000d
+#define TRACE_TYPE_CMD_RX           0x0000000e
+#define TRACE_TYPE_EVT_RX           0x0000000f
+#define TRACE_TYPE_ACL_RX           0x00000010
+#define TRACE_TYPE_TARGET_TRACE     0x00000011
+#define TRACE_TYPE_SCO_TX           0x00000012
+#define TRACE_TYPE_SCO_RX           0x00000013
+
+
+#define TRACE_TYPE_MAX_NUM          20
+#define TRACE_TYPE_ALL              0xffff
+
+/* Define color for script type */
+#define SCR_COLOR_DEFAULT       0
+#define SCR_COLOR_TYPE_COMMENT  1
+#define SCR_COLOR_TYPE_COMMAND  2
+#define SCR_COLOR_TYPE_EVENT    3
+#define SCR_COLOR_TYPE_SELECT   4
+
+/* Define protocol trace flag values */
+#define SCR_PROTO_TRACE_HCI_SUMMARY 0x00000001
+#define SCR_PROTO_TRACE_HCI_DATA    0x00000002
+#define SCR_PROTO_TRACE_L2CAP       0x00000004
+#define SCR_PROTO_TRACE_RFCOMM      0x00000008
+#define SCR_PROTO_TRACE_SDP         0x00000010
+#define SCR_PROTO_TRACE_TCS         0x00000020
+#define SCR_PROTO_TRACE_OBEX        0x00000040
+#define SCR_PROTO_TRACE_OAPP        0x00000080 /* OBEX Application Profile */
+#define SCR_PROTO_TRACE_AMP         0x00000100
+#define SCR_PROTO_TRACE_BNEP        0x00000200
+#define SCR_PROTO_TRACE_AVP         0x00000400
+#define SCR_PROTO_TRACE_MCA         0x00000800
+#define SCR_PROTO_TRACE_ATT         0x00001000
+#define SCR_PROTO_TRACE_SMP         0x00002000
+#define SCR_PROTO_TRACE_NCI         0x00004000
+#define SCR_PROTO_TRACE_LLCP        0x00008000
+#define SCR_PROTO_TRACE_NDEF        0x00010000
+#define SCR_PROTO_TRACE_RW          0x00020000
+#define SCR_PROTO_TRACE_CE          0x00040000
+#define SCR_PROTO_TRACE_SNEP        0x00080000
+#define SCR_PROTO_TRACE_CHO         0x00100000
+#define SCR_PROTO_TRACE_ALL         0x001fffff
+#define SCR_PROTO_TRACE_HCI_LOGGING_VSE 0x0800 /* Brcm vs event for logmsg and protocol traces */
+
+#define MAX_SCRIPT_TYPE             5
+
+#define TCS_PSM_INTERCOM        5
+#define TCS_PSM_CORDLESS        7
+#define BT_PSM_BNEP             0x000F
+/* Define PSMs HID uses */
+#define HID_PSM_CONTROL         0x0011
+#define HID_PSM_INTERRUPT       0x0013
+
+#if defined(UCD_HID_INCLUDED) && (UCD_HID_INCLUDED == TRUE)
+#define UCD_PSM_MIN     0x8003
+#define UCD_PSM_MAX     0x8003
+#define UCD_PSM_HID     0x8003
+#endif
+
+/* Define a function for logging */
+typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...);
+
+#endif
+
diff --git a/src/include/btdisp_lock.h b/src/include/btdisp_lock.h
new file mode 100644
index 0000000..b220b2d
--- /dev/null
+++ b/src/include/btdisp_lock.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Critical section definitions for btdisp functions.
+ *
+ ******************************************************************************/
diff --git a/src/include/btu_api.h b/src/include/btu_api.h
new file mode 100644
index 0000000..83c7d87
--- /dev/null
+++ b/src/include/btu_api.h
@@ -0,0 +1,20 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 BTU_API_H
+#define BTU_API_H
+#endif /* BTU_APU_H */
diff --git a/src/include/buildcfg.h b/src/include/buildcfg.h
new file mode 100755
index 0000000..8f03bd9
--- /dev/null
+++ b/src/include/buildcfg.h
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 __BUILDCFG_H
+#define __BUILDCFG_H
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+#include "data_types.h"
+
+#include "btdisp_lock.h"
+#ifndef NFC_CONTORLLER_ID
+#define NFC_CONTORLLER_ID       (1)
+#endif
+
+#ifdef ANDROID_USE_LOGCAT
+#undef ANDROID_USE_LOGCAT
+#endif
+
+#define BTE_APPL_MAX_USERIAL_DEV_NAME           (256)
+
+#define ANDROID_USE_LOGCAT      TRUE
+
+#ifdef BT_TRACE_PROTOCOL
+#undef BT_TRACE_PROTOCOL
+#endif
+
+#ifdef BT_TRACE_VERBOSE
+#undef BT_TRACE_VERBOSE
+#endif
+#define BT_TRACE_VERBOSE      TRUE
+
+#define TRACE_TASK_INCLUDED   TRUE
+
+#define GKI_BUF1_MAX            0
+// 2 is in use
+#define GKI_BUF3_MAX            30
+#define GKI_BUF4_SIZE           2400
+#define GKI_BUF4_MAX            30
+#define GKI_BUF5_MAX            0
+#define GKI_BUF6_MAX            0
+#define GKI_BUF7_MAX            0
+#define GKI_BUF8_MAX            0
+
+#define GKI_BUF2_SIZE           660
+#define GKI_BUF2_MAX            50
+
+#define GKI_BUF0_SIZE           268
+#define GKI_BUF0_MAX            40
+
+#define NCI_BUF_POOL_ID         GKI_POOL_ID_0
+#define GKI_NUM_FIXED_BUF_POOLS 4
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+// +++from bte.h...
+enum
+{
+                            /* BTE                  BBY                     */
+                            /* J3   J4              SW3-3   SW3-2   SW3-1   */
+                            /* -------------------------------------------- */
+    BTE_MODE_SERIAL_APP,    /* OUT  OUT             OFF     OFF     OFF     Sample serial port application      */
+    BTE_MODE_APPL,    	    /* IN   OUT             OFF     OFF     ON      Target used with Tester through RPC */
+    BTE_MODE_RESERVED,      /* OUT  IN              OFF     ON      OFF     Reserved                            */
+    BTE_MODE_SAMPLE_APPS,   /* IN   IN              OFF     ON      ON      Sample applications (ICP/HSP)       */
+    BTE_MODE_DONGLE,        /* not yet supported    ON      OFF     OFF     Dongle mode                         */
+    BTE_MODE_APPL_PROTOCOL_TRACE, /* this is a fake mode do allow protocol tracing in application without rpc */
+    BTE_MODE_INVALID
+};
+/* Protocol trace mask */
+extern UINT32 bte_proto_trace_mask;/* = 0xFFFFFFFF;*/
+extern volatile UINT8 bte_target_mode;
+// ---from bte.h...
+
+
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+extern void ScrLog(UINT32 trace_set_mask, const char *fmt_str, ...);
+extern void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+
+extern void downloadFirmwarePatchFile (UINT32 brcm_hw_id);
+
+#define DISP_NCI	(DispNciDump)
+extern void DispNciDump(UINT8 *p, UINT16 len, BOOLEAN is_recv);
+
+#ifndef _TIMEB
+#define _TIMEB
+struct _timeb
+{
+    long    time;
+    short   millitm;
+    short   timezone;
+    short   dstflag;
+};
+void    _ftime (struct _timeb*);
+
+#endif
+
+#ifdef	__cplusplus
+};
+#endif
+#endif
diff --git a/src/include/buildcfg_hal.h b/src/include/buildcfg_hal.h
new file mode 100644
index 0000000..a491bac
--- /dev/null
+++ b/src/include/buildcfg_hal.h
@@ -0,0 +1,25 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains constant definitions for customizing NFA
+ *
+ ******************************************************************************/
+#pragma once
+
diff --git a/src/include/config.h b/src/include/config.h
new file mode 100755
index 0000000..0660c1b
--- /dev/null
+++ b/src/include/config.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 __CONFIG_H
+#define __CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int GetStrValue(const char* name, char* p_value, unsigned long len);
+int GetNumValue(const char* name, void* p_value, unsigned long len);
+
+#ifdef __cplusplus
+};
+#endif
+
+#define NAME_USE_NXP_P2P_RC_WORKAROUND  "USE_NXP_P2P_RC_WORKAROUND"
+#define NAME_NFA_DM_ENABLE_SLEEP        "NFA_DM_ENABLE_SLEEP"
+#define NAME_ENABLE_BRCM_EXTRAS_API     "ENABLE_BRCM_EXTRAS_API"
+#define NAME_POLLING_TECH_MASK          "POLLING_TECH_MASK"
+#define NAME_REGISTER_VIRTUAL_SE        "REGISTER_VIRTUAL_SE"
+#define NAME_APPL_TRACE_LEVEL           "APPL_TRACE_LEVEL"
+#define NAME_LPTD_CFG                   "LPTD_CFG"
+#define NAME_SCREEN_OFF_POWER_STATE     "SCREEN_OFF_POWER_STATE"
+#define NAME_UICC_IDLE_TIMEOUT          "UICC_IDLE_TIMEOUT"
+#define NAME_PREINIT_DSP_CFG            "PREINIT_DSP_CFG"
+#define NAME_DTA_START_CFG              "DTA_START_CFG"
+#define NAME_TRANSPORT_DRIVER           "TRANSPORT_DRIVER"
+#define NAME_POWER_CONTROL_DRIVER       "POWER_CONTROL_DRIVER"
+#define NAME_PROTOCOL_TRACE_LEVEL       "PROTOCOL_TRACE_LEVEL"
+#define NAME_UART_PORT                  "UART_PORT"
+#define NAME_UART_BAUD                  "UART_BAUD"
+#define NAME_UART_PARITY                "UART_PARITY"
+#define NAME_UART_STOPBITS              "UART_STOPBITS"
+#define NAME_UART_DATABITS              "UART_DATABITS"
+#define NAME_CLIENT_ADDRESS             "BCMI2CNFC_ADDRESS"
+#define NAME_NFA_DM_START_UP_CFG        "NFA_DM_START_UP_CFG"
+#define NAME_NFA_DM_CFG                 "NFA_DM_CFG"
+#define NAME_NFA_DM_LP_CFG              "NFA_DM_LP_CFG"
+#define NAME_LOW_SPEED_TRANSPORT        "LOW_SPEED_TRANSPORT"
+#define NAME_NFC_WAKE_DELAY             "NFC_WAKE_DELAY"
+#define NAME_NFC_WRITE_DELAY            "NFC_WRITE_DELAY"
+#define NAME_PERF_MEASURE_FREQ          "REPORT_PERFORMANCE_MEASURE"
+#define NAME_READ_MULTI_PACKETS         "READ_MULTIPLE_PACKETS"
+#define NAME_POWER_ON_DELAY             "POWER_ON_DELAY"
+#define NAME_PRE_POWER_OFF_DELAY        "PRE_POWER_OFF_DELAY"
+#define NAME_POST_POWER_OFF_DELAY       "POST_POWER_OFF_DELAY"
+#define NAME_NFA_STORAGE                "NFA_STORAGE"
+#define NAME_NFA_DM_START_UP_VSC_CFG    "NFA_DM_START_UP_VSC_CFG"
+#define NAME_UICC_LISTEN_TECH_MASK      "UICC_LISTEN_TECH_MASK"
+#define NAME_SNOOZE_MODE_CFG            "SNOOZE_MODE_CFG"
+#define NAME_XTAL_FREQUENCY             "XTAL_FREQUENCY"
+#define NAME_NFA_DM_DISC_DURATION_POLL  "NFA_DM_DISC_DURATION_POLL"
+#define NAME_AID_FOR_EMPTY_SELECT       "AID_FOR_EMPTY_SELECT"
+
+#define                     LPTD_PARAM_LEN (40)
+
+// default configuration
+#define default_transport       "/dev/bcm2079x"
+#define default_storage_location "/data/nfc"
+
+struct tUART_CONFIG {
+    int     m_iBaudrate;            // 115200
+    int     m_iDatabits;            // 8
+    int     m_iParity;              // 0 - none, 1 = odd, 2 = even
+    int     m_iStopbits;
+};
+
+extern struct tUART_CONFIG  uartConfig;
+#define MAX_CHIPID_LEN  (16)
+void    readOptionalConfig(const char* option);
+
+/* Snooze mode configuration structure */
+typedef struct
+{
+    unsigned char   snooze_mode;            /* Snooze Mode */
+    unsigned char   idle_threshold_dh;      /* Idle Threshold Host */
+    unsigned char   idle_threshold_nfcc;    /* Idle Threshold NFCC   */
+    unsigned char   nfc_wake_active_mode;   /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+    unsigned char   dh_wake_active_mode;    /* NFC_LP_ACTIVE_LOW or NFC_LP_ACTIVE_HIGH */
+} tSNOOZE_MODE_CONFIG;
+#endif
diff --git a/src/include/dyn_mem.h b/src/include/dyn_mem.h
new file mode 100644
index 0000000..2ee0169
--- /dev/null
+++ b/src/include/dyn_mem.h
@@ -0,0 +1,191 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 DYN_MEM_H
+#define DYN_MEM_H
+
+/****************************************************************************
+** Define memory usage for GKI (if not defined in buildcfg.h)
+**  The default for GKI is to use static memory allocation for its control
+**  block.
+*/
+#ifndef GKI_DYNAMIC_MEMORY
+#define GKI_DYNAMIC_MEMORY  FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for each CORE component (if not defined in buildcfg.h)
+**  The default for each component is to use static memory allocations.
+*/
+#ifndef BTU_DYNAMIC_MEMORY
+#define BTU_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef BTM_DYNAMIC_MEMORY
+#define BTM_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SDP_DYNAMIC_MEMORY
+#define SDP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef L2C_DYNAMIC_MEMORY
+#define L2C_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef A2MP_DYNAMIC_MEMORY
+#define A2MP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef RFC_DYNAMIC_MEMORY
+#define RFC_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef TCS_DYNAMIC_MEMORY
+#define TCS_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef OBX_DYNAMIC_MEMORY
+#define OBX_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef BNEP_DYNAMIC_MEMORY
+#define BNEP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVDT_DYNAMIC_MEMORY
+#define AVDT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef AVCT_DYNAMIC_MEMORY
+#define AVCT_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef MCA_DYNAMIC_MEMORY
+#define MCA_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef GATT_DYNAMIC_MEMORY
+#define GATT_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SMP_DYNAMIC_MEMORY
+#define SMP_DYNAMIC_MEMORY  FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for each PROFILE component (if not defined in buildcfg.h)
+**  The default for each component is to use static memory allocations.
+*/
+#ifndef A2D_DYNAMIC_MEMORY
+#define A2D_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef VDP_DYNAMIC_MEMORY
+#define VDP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef AVRC_DYNAMIC_MEMORY
+#define AVRC_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef BIP_DYNAMIC_MEMORY
+#define BIP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef BPP_DYNAMIC_MEMORY
+#define BPP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef CTP_DYNAMIC_MEMORY
+#define CTP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef DUN_DYNAMIC_MEMORY
+#define DUN_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef FTP_DYNAMIC_MEMORY
+#define FTP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef GAP_DYNAMIC_MEMORY
+#define GAP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef GOEP_DYNAMIC_MEMORY
+#define GOEP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HCRP_DYNAMIC_MEMORY
+#define HCRP_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef HFP_DYNAMIC_MEMORY
+#define HFP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef HID_DYNAMIC_MEMORY
+#define HID_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef HSP2_DYNAMIC_MEMORY
+#define HSP2_DYNAMIC_MEMORY FALSE
+#endif
+
+#ifndef ICP_DYNAMIC_MEMORY
+#define ICP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef OPP_DYNAMIC_MEMORY
+#define OPP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef PAN_DYNAMIC_MEMORY
+#define PAN_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SPP_DYNAMIC_MEMORY
+#define SPP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef SLIP_DYNAMIC_MEMORY
+#define SLIP_DYNAMIC_MEMORY  FALSE
+#endif
+
+#ifndef LLCP_DYNAMIC_MEMORY
+#define LLCP_DYNAMIC_MEMORY  FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for BTA (if not defined in buildcfg.h)
+**  The default for each component is to use static memory allocations.
+*/
+#ifndef BTA_DYNAMIC_MEMORY
+#define BTA_DYNAMIC_MEMORY FALSE
+#endif
+
+/****************************************************************************
+** Define memory usage for BT Trace (if not defined in buildcfg.h)
+**  The default is to use static memory allocations.
+*/
+#ifndef BTTRC_DYNAMIC_MEMORY
+#define BTTRC_DYNAMIC_MEMORY FALSE
+#endif
+
+#endif  /* #ifdef DYN_MEM_H */
+
diff --git a/src/include/gki_target.h b/src/include/gki_target.h
new file mode 100644
index 0000000..602f37a
--- /dev/null
+++ b/src/include/gki_target.h
@@ -0,0 +1,427 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 GKI_TARGET_H
+#define GKI_TARGET_H
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+#include "data_types.h"
+
+/* Operating System Selection */
+#ifndef BTE_SIM_APP
+#define _GKI_ARM
+#define _GKI_STANDALONE
+#else
+#define _BT_WIN32
+#endif
+
+/* define prefix for exporting APIs from libraries */
+#define EXPORT_API
+
+#ifndef BTE_BSE_WRAPPER
+#ifdef  BTE_SIM_APP
+#undef  EXPORT_API
+#define EXPORT_API  __declspec(dllexport)
+#endif
+#endif
+
+#define GKI_API EXPORT_API
+#define UDRV_API EXPORT_API
+
+
+/******************************************************************************
+**
+** Task configuration
+**
+******************************************************************************/
+
+/* Definitions of task IDs for inter-task messaging */
+#ifndef MMI_TASK
+#define MMI_TASK                0
+#endif
+
+#ifndef HCISU_TASK
+#define HCISU_TASK              1
+#endif
+
+#ifndef NCIT_TASK
+#define NCIT_TASK                2
+#endif
+
+#ifndef NFC_TASK
+#define NFC_TASK                3
+#endif
+
+#ifndef BTU_TASK
+#define BTU_TASK                4
+#endif
+
+/* BTE Application, Sample Apps, or Serial port Demo based on JP3 and JP4 setting) */
+#ifndef BTE_APPL_TASK
+#define BTE_APPL_TASK           5
+#endif
+
+#ifndef DEV_MGR_TASK
+#define DEV_MGR_TASK            6
+#endif
+
+#ifndef ISE_SCR_TASK
+#define ISE_SCR_TASK            7
+#endif
+
+#ifndef UCODEC_TASK
+#define UCODEC_TASK             8
+#endif
+
+#ifndef RPCT_TASK
+#define RPCT_TASK               9
+#endif
+
+#ifndef UNV_TASK
+#define UNV_TASK                10
+#endif
+
+#ifndef BTE_IDLE_TASK
+#define BTE_IDLE_TASK           11
+#endif
+
+#ifndef UIPC_TASK
+#define UIPC_TASK               12
+#endif
+
+#ifndef HCISU_AMP_TASK
+#define HCISU_AMP_TASK          13
+#endif
+
+
+/* The number of GKI tasks in the software system. */
+#ifndef GKI_MAX_TASKS
+#define GKI_MAX_TASKS               14
+#endif
+
+/******************************************************************************
+**
+** Timer configuration
+**
+******************************************************************************/
+
+/* The number of GKI timers in the software system. */
+#ifndef GKI_NUM_TIMERS
+#define GKI_NUM_TIMERS              3
+#endif
+
+/* A conversion value for translating ticks to calculate GKI timer.  */
+#ifndef TICKS_PER_SEC
+#define TICKS_PER_SEC               100
+#endif
+
+/* delay in ticks before stopping system tick. */
+#ifndef GKI_DELAY_STOP_SYS_TICK
+#define GKI_DELAY_STOP_SYS_TICK     10
+#endif
+
+/******************************************************************************
+**
+** Buffer configuration
+**
+******************************************************************************/
+
+/* TRUE if GKI uses dynamic buffers. */
+#ifndef GKI_USE_DYNAMIC_BUFFERS
+#define GKI_USE_DYNAMIC_BUFFERS     FALSE
+#endif
+
+/* The size of the buffers in pool 0. */
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE               64
+#endif
+
+/* The number of buffers in buffer pool 0. */
+#ifndef GKI_BUF0_MAX
+#define GKI_BUF0_MAX                48
+#endif
+
+/* The ID of buffer pool 0. */
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0               0
+#endif
+
+/* The size of the buffers in pool 1. */
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE               128
+#endif
+
+/* The number of buffers in buffer pool 1. */
+#ifndef GKI_BUF1_MAX
+#define GKI_BUF1_MAX                26
+#endif
+
+/* The ID of buffer pool 1. */
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1               1
+#endif
+
+/* The size of the buffers in pool 2. */
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE               660
+#endif
+
+/* The number of buffers in buffer pool 2. */
+#ifndef GKI_BUF2_MAX
+#define GKI_BUF2_MAX                45
+#endif
+
+/* The ID of buffer pool 2. */
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2               2
+#endif
+
+/* The size of the buffers in pool 3. */
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE               2500
+#endif
+
+/* The number of buffers in buffer pool 3. */
+#ifndef GKI_BUF3_MAX
+#define GKI_BUF3_MAX                30
+#endif
+
+/* The ID of buffer pool 3. */
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3               3
+#endif
+
+/* The size of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE
+#define GKI_MAX_BUF_SIZE            GKI_BUF3_SIZE
+#endif
+
+/* The pool ID of the largest PUBLIC fixed buffer in system. */
+#ifndef GKI_MAX_BUF_SIZE_POOL_ID
+#define GKI_MAX_BUF_SIZE_POOL_ID    GKI_POOL_ID_3
+#endif
+
+/* RESERVED buffer pool for OBX */
+/* Ideally there should be 1 buffer for each instance for RX data, and some number
+of TX buffers based on active instances. OBX will only use these if packet size
+requires it. In most cases the large packets are used in only one direction so
+the other direction will use smaller buffers.
+Devices with small amount of RAM should limit the number of active obex objects.
+*/
+/* The size of the buffers in pool 4. */
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE               0x2000
+#endif
+
+/* The number of buffers in buffer pool 4. */
+#ifndef GKI_BUF4_MAX
+#define GKI_BUF4_MAX                (OBX_NUM_SERVERS + OBX_NUM_CLIENTS)
+#endif
+
+/* The ID of buffer pool 4. */
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4               4
+#endif
+
+/* The number of fixed GKI buffer pools.
+If L2CAP_FCR_INCLUDED is FALSE, Pool ID 5 is unnecessary
+If BTM_SCO_HCI_INCLUDED is FALSE, Pool ID 6 is unnecessary, otherwise set to 7
+If BTA_HL_INCLUDED is FALSE then Pool ID 7 is uncessary and set the following to 7, otherwise set to 8
+If GATT_SERVER_ENABLED is FALSE then Pool ID 8 is uncessary and set the following to 8, otherwise set to 9
+*/
+#ifndef GKI_NUM_FIXED_BUF_POOLS
+#define GKI_NUM_FIXED_BUF_POOLS     9
+#endif
+
+/* The buffer pool usage mask. */
+#ifndef GKI_DEF_BUFPOOL_PERM_MASK
+#define GKI_DEF_BUFPOOL_PERM_MASK   0xfff0
+#endif
+
+/* The number of fixed and dynamic buffer pools.
+If L2CAP_FCR_INCLUDED is FALSE, Pool ID 4 is unnecessary */
+#ifndef GKI_NUM_TOTAL_BUF_POOLS
+#define GKI_NUM_TOTAL_BUF_POOLS     10
+#endif
+
+/* The following is intended to be a reserved pool for L2CAP
+Flow control and retransmissions and intentionally kept out
+of order */
+
+/* The number of buffers in buffer pool 5. */
+#ifndef GKI_BUF5_MAX
+#define GKI_BUF5_MAX                64
+#endif
+
+/* The ID of buffer pool 5. */
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5               5
+#endif
+
+/* The size of the buffers in pool 5
+** Special pool used by l2cap retransmissions only.  This size based on segment
+** that will fit into both DH5 and 2-DH3 packet types after accounting for GKI
+** header.  13 bytes of max headers allows us a 339 payload max. (in btui_app.txt)
+** Note: 748 used for insight scriptwrapper with CAT-2 scripts.
+*/
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE               748
+#endif
+
+/* The buffer corruption check flag. */
+#ifndef GKI_ENABLE_BUF_CORRUPTION_CHECK
+#define GKI_ENABLE_BUF_CORRUPTION_CHECK TRUE
+#endif
+
+/* The GKI severe error macro. */
+#ifndef GKI_SEVERE
+#define GKI_SEVERE(code)
+#endif
+
+/* TRUE if GKI includes debug functionality. */
+#ifndef GKI_DEBUG
+#define GKI_DEBUG                   FALSE
+#endif
+
+/* Maximum number of exceptions logged. */
+#ifndef GKI_MAX_EXCEPTION
+#define GKI_MAX_EXCEPTION           8
+#endif
+
+/* Maximum number of chars stored for each exception message. */
+#ifndef GKI_MAX_EXCEPTION_MSGLEN
+#define GKI_MAX_EXCEPTION_MSGLEN    64
+#endif
+
+#ifndef GKI_SEND_MSG_FROM_ISR
+#define GKI_SEND_MSG_FROM_ISR    FALSE
+#endif
+
+
+/* The following is intended to be a reserved pool for SCO
+over HCI data and intentionally kept out of order */
+
+/* The ID of buffer pool 6. */
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6               6
+#endif
+
+/* The size of the buffers in pool 6,
+  BUF_SIZE = max SCO data 255 + sizeof(BT_HDR) = 8 + SCO packet header 3 + padding 2 = 268 */
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE               268
+#endif
+
+/* The number of buffers in buffer pool 6. */
+#ifndef GKI_BUF6_MAX
+#define GKI_BUF6_MAX                60
+#endif
+
+
+/* The following pool is a dedicated pool for HDP
+   If a shared pool is more desirable then
+   1. set BTA_HL_LRG_DATA_POOL_ID to the desired Gki Pool ID
+   2. make sure that the shared pool size is larger than 9472
+   3. adjust GKI_NUM_FIXED_BUF_POOLS accordingly since
+      POOL ID 7 is not needed
+*/
+
+/* The ID of buffer pool 7. */
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7               7
+#endif
+
+/* The size of the buffers in pool 7 */
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE               9472
+#endif
+
+/* The number of buffers in buffer pool 7. */
+#ifndef GKI_BUF7_MAX
+#define GKI_BUF7_MAX                2
+#endif
+
+/* The following pool is a dedicated pool for GATT
+   If a shared pool is more desirable then
+   1. set GATT_DB_POOL_ID to the desired Gki Pool ID
+   2. make sure that the shared pool size fit a common GATT database needs
+   3. adjust GKI_NUM_FIXED_BUF_POOLS accordingly since
+      POOL ID 8 is not needed
+*/
+
+/* The ID of buffer pool 8. */
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8               8
+#endif
+
+/* The size of the buffers in pool 8 */
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE               128
+#endif
+
+/* The number of buffers in buffer pool 8. */
+#ifndef GKI_BUF8_MAX
+#define GKI_BUF8_MAX                30
+#endif
+
+#if defined(GKI_DEBUG) && (GKI_DEBUG == TRUE)
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "GKI_LINUX"
+/* GKI Trace Macros */
+#define GKI_TRACE_0(m)                          LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m)
+#define GKI_TRACE_1(m,p1)                       LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1)
+#define GKI_TRACE_2(m,p1,p2)                    LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2)
+#define GKI_TRACE_3(m,p1,p2,p3)                 LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3)
+#define GKI_TRACE_4(m,p1,p2,p3,p4)              LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4)
+#define GKI_TRACE_5(m,p1,p2,p3,p4,p5)           LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_6(m,p1,p2,p3,p4,p5,p6)        LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC,m,p1,p2,p3,p4,p5,p6)
+#else
+#define GKI_TRACE_0(m)
+#define GKI_TRACE_1(m,p1)
+#define GKI_TRACE_2(m,p1,p2)
+#define GKI_TRACE_3(m,p1,p2,p3)
+#define GKI_TRACE_4(m,p1,p2,p3,p4)
+#define GKI_TRACE_5(m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_6(m,p1,p2,p3,p4,p5,p6)
+
+#endif
+
+#define GKI_TRACE_ERROR_0(m)                    LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m)
+#define GKI_TRACE_ERROR_1(m,p1)                 LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1)
+#define GKI_TRACE_ERROR_2(m,p1,p2)              LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2)
+#define GKI_TRACE_ERROR_3(m,p1,p2,p3)           LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3)
+#define GKI_TRACE_ERROR_4(m,p1,p2,p3,p4)        LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4)
+#define GKI_TRACE_ERROR_5(m,p1,p2,p3,p4,p5)     LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5)
+#define GKI_TRACE_ERROR_6(m,p1,p2,p3,p4,p5,p6)  LogMsg(TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_ERROR,m,p1,p2,p3,p4,p5,p6)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* GKI_TARGET_H */
diff --git a/src/include/hcidefs.h b/src/include/hcidefs.h
new file mode 100644
index 0000000..9b9d5a6
--- /dev/null
+++ b/src/include/hcidefs.h
@@ -0,0 +1,2380 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 HCIDEFS_H
+#define HCIDEFS_H
+
+#define HCI_PROTO_VERSION     0x01      /* Version for BT spec 1.1          */
+#define HCI_PROTO_VERSION_1_2 0x02      /* Version for BT spec 1.2          */
+#define HCI_PROTO_VERSION_2_0 0x03      /* Version for BT spec 2.0          */
+#define HCI_PROTO_VERSION_2_1 0x04      /* Version for BT spec 2.1 [Lisbon] */
+#define HCI_PROTO_VERSION_3_0 0x05      /* Version for BT spec 3.0          */
+#define HCI_PROTO_REVISION    0x000C    /* Current implementation version   */
+/*
+**  Definitions for HCI groups
+*/
+#define HCI_GRP_LINK_CONTROL_CMDS       (0x01 << 10)            /* 0x0400 */
+#define HCI_GRP_LINK_POLICY_CMDS        (0x02 << 10)            /* 0x0800 */
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10)            /* 0x0C00 */
+#define HCI_GRP_INFORMATIONAL_PARAMS    (0x04 << 10)            /* 0x1000 */
+#define HCI_GRP_STATUS_PARAMS           (0x05 << 10)            /* 0x1400 */
+#define HCI_GRP_TESTING_CMDS            (0x06 << 10)            /* 0x1800 */
+
+#define HCI_GRP_VENDOR_SPECIFIC         (0x3F << 10)            /* 0xFC00 */
+
+/* Group occupies high 6 bits of the HCI command rest is opcode itself */
+#define HCI_OGF(p)  (UINT8)((0xFC00 & (p)) >> 10)
+#define HCI_OCF(p)  ( 0x3FF & (p))
+
+/*
+**  Defentions for Link Control Commands
+*/
+/* Following opcode is used only in command complete event for flow control */
+#define HCI_COMMAND_NONE                0x0000
+
+/* Commands of HCI_GRP_LINK_CONTROL_CMDS group */
+#define HCI_INQUIRY                     (0x0001 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_INQUIRY_CANCEL              (0x0002 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PERIODIC_INQUIRY_MODE       (0x0003 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_EXIT_PERIODIC_INQUIRY_MODE  (0x0004 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_CONNECTION           (0x0005 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT                  (0x0006 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ADD_SCO_CONNECTION          (0x0007 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_CONNECTION_CANCEL    (0x0008 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_CONNECTION_REQUEST   (0x0009 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REJECT_CONNECTION_REQUEST   (0x000A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LINK_KEY_REQUEST_REPLY      (0x000B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY  (0x000C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PIN_CODE_REQUEST_REPLY      (0x000D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY  (0x000E | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CHANGE_CONN_PACKET_TYPE     (0x000F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_AUTHENTICATION_REQUESTED    (0x0011 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SET_CONN_ENCRYPTION         (0x0013 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CHANGE_CONN_LINK_KEY        (0x0015 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_MASTER_LINK_KEY             (0x0017 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RMT_NAME_REQUEST            (0x0019 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_RMT_NAME_REQUEST_CANCEL     (0x001A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_FEATURES           (0x001B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_EXT_FEATURES       (0x001C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_VERSION_INFO       (0x001D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_RMT_CLOCK_OFFSET       (0x001F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_READ_LMP_HANDLE             (0x0020 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_SETUP_ESCO_CONNECTION       (0x0028 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_ESCO_CONNECTION      (0x0029 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REJECT_ESCO_CONNECTION      (0x002A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_IO_CAPABILITY_RESPONSE      (0x002B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_CONF_REQUEST_REPLY     (0x002C | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_CONF_VALUE_NEG_REPLY   (0x002D | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_PASSKEY_REQ_REPLY      (0x002E | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_USER_PASSKEY_REQ_NEG_REPLY  (0x002F | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REM_OOB_DATA_REQ_REPLY      (0x0030 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_REM_OOB_DATA_REQ_NEG_REPLY  (0x0033 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_IO_CAP_REQ_NEG_REPLY        (0x0034 | HCI_GRP_LINK_CONTROL_CMDS)
+
+/* AMP HCI */
+#define HCI_CREATE_PHYSICAL_LINK        (0x0035 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_PHYSICAL_LINK        (0x0036 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT_PHYSICAL_LINK    (0x0037 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_CREATE_LOGICAL_LINK         (0x0038 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_ACCEPT_LOGICAL_LINK         (0x0039 | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_DISCONNECT_LOGICAL_LINK     (0x003A | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_LOGICAL_LINK_CANCEL         (0x003B | HCI_GRP_LINK_CONTROL_CMDS)
+#define HCI_FLOW_SPEC_MODIFY            (0x003C | HCI_GRP_LINK_CONTROL_CMDS)
+
+#define HCI_LINK_CTRL_CMDS_FIRST        HCI_INQUIRY
+#define HCI_LINK_CTRL_CMDS_LAST         HCI_FLOW_SPEC_MODIFY
+
+/* Commands of HCI_GRP_LINK_POLICY_CMDS */
+#define HCI_HOLD_MODE                   (0x0001 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SNIFF_MODE                  (0x0003 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_EXIT_SNIFF_MODE             (0x0004 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_PARK_MODE                   (0x0005 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_EXIT_PARK_MODE              (0x0006 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_QOS_SETUP                   (0x0007 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_ROLE_DISCOVERY              (0x0009 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SWITCH_ROLE                 (0x000B | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_READ_POLICY_SETTINGS        (0x000C | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_WRITE_POLICY_SETTINGS       (0x000D | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_READ_DEF_POLICY_SETTINGS    (0x000E | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_WRITE_DEF_POLICY_SETTINGS   (0x000F | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_FLOW_SPECIFICATION          (0x0010 | HCI_GRP_LINK_POLICY_CMDS)
+#define HCI_SNIFF_SUB_RATE              (0x0011 | HCI_GRP_LINK_POLICY_CMDS)
+
+#define HCI_LINK_POLICY_CMDS_FIRST      HCI_HOLD_MODE
+#define HCI_LINK_POLICY_CMDS_LAST       HCI_SNIFF_SUB_RATE
+
+
+/* Commands of HCI_GRP_HOST_CONT_BASEBAND_CMDS */
+#define HCI_SET_EVENT_MASK              (0x0001 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_RESET                       (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EVENT_FILTER            (0x0005 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_FLUSH                       (0x0008 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PIN_TYPE               (0x0009 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PIN_TYPE              (0x000A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_CREATE_NEW_UNIT_KEY         (0x000B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_STORED_LINK_KEY        (0x000D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_STORED_LINK_KEY       (0x0011 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_DELETE_STORED_LINK_KEY      (0x0012 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_CHANGE_LOCAL_NAME           (0x0013 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCAL_NAME             (0x0014 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CONN_ACCEPT_TOUT       (0x0015 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CONN_ACCEPT_TOUT      (0x0016 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGE_TOUT              (0x0017 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGE_TOUT             (0x0018 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SCAN_ENABLE            (0x0019 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SCAN_ENABLE           (0x001A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_CFG           (0x001B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_CFG          (0x001C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQUIRYSCAN_CFG        (0x001D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQUIRYSCAN_CFG       (0x001E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTHENTICATION_ENABLE  (0x001F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTHENTICATION_ENABLE (0x0020 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_ENCRYPTION_MODE        (0x0021 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_ENCRYPTION_MODE       (0x0022 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CLASS_OF_DEVICE        (0x0023 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CLASS_OF_DEVICE       (0x0024 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_VOICE_SETTINGS         (0x0025 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_VOICE_SETTINGS        (0x0026 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AUTO_FLUSH_TOUT        (0x0027 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AUTO_FLUSH_TOUT       (0x0028 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_NUM_BCAST_REXMITS      (0x0029 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_NUM_BCAST_REXMITS     (0x002A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_HOLD_MODE_ACTIVITY     (0x002B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_HOLD_MODE_ACTIVITY    (0x002C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_TRANSMIT_POWER_LEVEL   (0x002D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SCO_FLOW_CTRL_ENABLE   (0x002E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SCO_FLOW_CTRL_ENABLE  (0x002F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_HC_TO_HOST_FLOW_CTRL    (0x0031 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_HOST_BUFFER_SIZE            (0x0033 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_HOST_NUM_PACKETS_DONE       (0x0035 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LINK_SUPER_TOUT        (0x0036 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LINK_SUPER_TOUT       (0x0037 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_NUM_SUPPORTED_IAC      (0x0038 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_CURRENT_IAC_LAP        (0x0039 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CURRENT_IAC_LAP       (0x003A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_PERIOD_MODE   (0x003B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_PERIOD_MODE  (0x003C | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_MODE          (0x003D | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_MODE         (0x003E | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_AFH_CHANNELS            (0x003F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+#define HCI_READ_INQSCAN_TYPE           (0x0042 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQSCAN_TYPE          (0x0043 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQUIRY_MODE           (0x0044 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQUIRY_MODE          (0x0045 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_PAGESCAN_TYPE          (0x0046 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_PAGESCAN_TYPE         (0x0047 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_AFH_ASSESSMENT_MODE    (0x0048 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_AFH_ASSESSMENT_MODE   (0x0049 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_EXT_INQ_RESPONSE       (0x0051 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_EXT_INQ_RESPONSE      (0x0052 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_REFRESH_ENCRYPTION_KEY      (0x0053 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SIMPLE_PAIRING_MODE    (0x0055 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SIMPLE_PAIRING_MODE   (0x0056 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCAL_OOB_DATA         (0x0057 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_INQ_TX_POWER_LEVEL     (0x0058 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_INQ_TX_POWER_LEVEL    (0x0059 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_ERRONEOUS_DATA_RPT     (0x005A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_ERRONEOUS_DATA_RPT    (0x005B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_ENHANCED_FLUSH              (0x005F | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SEND_KEYPRESS_NOTIF         (0x0060 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+
+
+/* AMP HCI */
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT  (0x0061 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT (0x0062 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_EVENT_MASK_PAGE_2             (0x0063 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_LOCATION_DATA                (0x0064 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_LOCATION_DATA               (0x0065 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_FLOW_CONTROL_MODE            (0x0066 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_FLOW_CONTROL_MODE           (0x0067 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_BE_FLUSH_TOUT                (0x0069 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_BE_FLUSH_TOUT               (0x006A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SHORT_RANGE_MODE                  (0x006B | HCI_GRP_HOST_CONT_BASEBAND_CMDS) /* 802.11 only */
+
+#define HCI_CONT_BASEBAND_CMDS_FIRST    HCI_SET_EVENT_MASK
+#define HCI_CONT_BASEBAND_CMDS_LAST     HCI_SHORT_RANGE_MODE
+
+
+/* Commands of HCI_GRP_INFORMATIONAL_PARAMS group */
+#define HCI_READ_LOCAL_VERSION_INFO     (0x0001 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_SUPPORTED_CMDS   (0x0002 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_FEATURES         (0x0003 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_LOCAL_EXT_FEATURES     (0x0004 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_BUFFER_SIZE            (0x0005 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_COUNTRY_CODE           (0x0007 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_BD_ADDR                (0x0009 | HCI_GRP_INFORMATIONAL_PARAMS)
+#define HCI_READ_DATA_BLOCK_SIZE        (0x000A | HCI_GRP_INFORMATIONAL_PARAMS)
+
+#define HCI_INFORMATIONAL_CMDS_FIRST    HCI_READ_LOCAL_VERSION_INFO
+#define HCI_INFORMATIONAL_CMDS_LAST     HCI_READ_BD_ADDR
+
+
+/* Commands of HCI_GRP_STATUS_PARAMS group */
+#define HCI_READ_FAILED_CONTACT_COUNT   (0x0001 | HCI_GRP_STATUS_PARAMS)
+#define HCI_RESET_FAILED_CONTACT_COUNT  (0x0002 | HCI_GRP_STATUS_PARAMS)
+#define HCI_GET_LINK_QUALITY            (0x0003 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_RSSI                   (0x0005 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_AFH_CH_MAP             (0x0006 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_CLOCK                  (0x0007 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_ENCR_KEY_SIZE          (0x0008 | HCI_GRP_STATUS_PARAMS)
+
+/* AMP HCI */
+#define HCI_READ_LOCAL_AMP_INFO         (0x0009 | HCI_GRP_STATUS_PARAMS)
+#define HCI_READ_LOCAL_AMP_ASSOC        (0x000A | HCI_GRP_STATUS_PARAMS)
+#define HCI_WRITE_REMOTE_AMP_ASSOC      (0x000B | HCI_GRP_STATUS_PARAMS)
+
+#define HCI_STATUS_PARAMS_CMDS_FIRST    HCI_READ_FAILED_CONTACT_COUNT
+#define HCI_STATUS_PARAMS_CMDS_LAST     HCI_WRITE_REMOTE_AMP_ASSOC
+
+/* Commands of HCI_GRP_TESTING_CMDS group */
+#define HCI_READ_LOOPBACK_MODE          (0x0001 | HCI_GRP_TESTING_CMDS)
+#define HCI_WRITE_LOOPBACK_MODE         (0x0002 | HCI_GRP_TESTING_CMDS)
+#define HCI_ENABLE_DEV_UNDER_TEST_MODE  (0x0003 | HCI_GRP_TESTING_CMDS)
+#define HCI_WRITE_SIMP_PAIR_DEBUG_MODE  (0x0004 | HCI_GRP_TESTING_CMDS)
+
+/* AMP HCI */
+#define HCI_ENABLE_AMP_RCVR_REPORTS     (0x0007 | HCI_GRP_TESTING_CMDS)
+#define HCI_AMP_TEST_END                (0x0008 | HCI_GRP_TESTING_CMDS)
+#define HCI_AMP_TEST                    (0x0009 | HCI_GRP_TESTING_CMDS)
+
+#define HCI_TESTING_CMDS_FIRST          HCI_READ_LOOPBACK_MODE
+#define HCI_TESTING_CMDS_LAST           HCI_AMP_TEST
+
+#define HCI_VENDOR_CMDS_FIRST           0x0001
+#define HCI_VENDOR_CMDS_LAST            0xFFFF
+#define HCI_VSC_MULTI_AV_HANDLE         0x0AAA
+#define HCI_VSC_BURST_MODE_HANDLE       0x0BBB
+
+/* BLE HCI */
+#define HCI_GRP_BLE_CMDS                (0x08 << 10)
+/* Commands of BLE Controller setup and configuration */
+#define HCI_BLE_SET_EVENT_MASK          (0x0001 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_BUFFER_SIZE        (0x0002 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_LOCAL_SPT_FEAT     (0x0003 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_LOCAL_SPT_FEAT    (0x0004 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_RANDOM_ADDR       (0x0005 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_PARAMS        (0x0006 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_ADV_CHNL_TX_POWER  (0x0007 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_DATA          (0x0008 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_RSP_DATA     (0x0009 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_ENABLE        (0x000A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_PARAMS       (0x000B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_SCAN_ENABLE       (0x000C | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_LL_CONN          (0x000D | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CREATE_CONN_CANCEL      (0x000E | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_WHITE_LIST_SIZE    (0x000F | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_CLEAR_WHITE_LIST        (0x0010 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ADD_WHITE_LIST          (0x0011 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_REMOVE_WHITE_LIST       (0x0012 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_UPD_LL_CONN_PARAMS      (0x0013 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_SET_HOST_CHNL_CLASS     (0x0014 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_CHNL_MAP           (0x0015 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_REMOTE_FEAT        (0x0016 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_ENCRYPT                 (0x0017 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_RAND                    (0x0018 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_START_ENC               (0x0019 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_LTK_REQ_REPLY           (0x001A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_LTK_REQ_NEG_REPLY       (0x001B | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_READ_SUPPORTED_STATES   (0x001C | HCI_GRP_BLE_CMDS)
+
+#define HCI_BLE_RESET                   (0x0020 | HCI_GRP_BLE_CMDS)
+
+/* LE supported states definition */
+#define HCI_LE_ADV_STATE          0x00000001
+#define HCI_LE_SCAN_STATE         0x00000002
+#define HCI_LE_INIT_STATE         0x00000004
+#define HCI_LE_CONN_SL_STATE      0x00000008
+#define HCI_LE_ADV_SCAN_STATE     0x00000010
+#define HCI_LE_ADV_INIT_STATE     0x00000020
+#define HCI_LE_ADV_MA_STATE       0x00000040
+#define HCI_LE_ADV_SL_STATE       0x00000080
+#define HCI_LE_SCAN_INIT_STATE    0x00000100
+#define HCI_LE_SCAN_MA_STATE      0x00000200
+#define HCI_LE_SCAN_SL_STATE      0x00000400
+#define HCI_LE_INIT_MA_STATE      0x00000800
+
+/* Vendor specific commands for BRCM chipset */
+#define HCI_BRCM_UPDATE_BAUD_RATE_ENCODED_LENGTH        0x02
+#define HCI_BRCM_UPDATE_BAUD_RATE_UNENCODED_LENGTH      0x06
+#define HCI_BRCM_WRITE_SLEEP_MODE_LENGTH                12
+#define HCI_BRCM_ENABLE_H4IBSS_LENGTH                   7
+#define HCI_BRCM_CUSTOMER_EXT               (0x0000 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_FM_OPCODE                  (0x0015 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_FMTX_OPCODE                (0x0082 | HCI_GRP_VENDOR_SPECIFIC)  /* FMTX VSC opcode */
+#define HCI_BRCM_UPDATE_BAUDRATE_CMD        (0x0018 | HCI_GRP_VENDOR_SPECIFIC)    /* set baudrate of BCM2035 */
+#define HCI_BRCM_WRITE_SCO_PCM_INT_PARAM    (0x001C | HCI_GRP_VENDOR_SPECIFIC)    /* set SCO interface param */
+#define HCI_BRCM_READ_SCO_PCM_INT_PARAM     (0x001D | HCI_GRP_VENDOR_SPECIFIC)    /* read SCO interface param */
+#define HCI_BRCM_WRITE_SLEEP_MODE           (0x0027 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_SLEEP_MODE            (0x0028 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_H4IBSS_CMD                 (0x0029 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_DOWNLOAD_MINI_DRV          (0x002E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_USER_DEFINED_NVRAM    (0x0033 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_RADIO               (0x0034 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_DIAGNOSTIC_VALUE      (0x0035 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_GET_HID_DEVICE_LIST        (0x0036 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ADD_HID_DEVICE             (0x0037 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_WRITE_HID_DEVICE_NVRAM     (0x0038 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_DELETE_HID_DEVICE          (0x0039 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_USB_HID_EMULATION   (0x003B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_WRITE_RAM                  (0x004C | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_LAUNCH_RAM                 (0x004E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_BTW_STARTUP                (0x0053 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_SET_ACL_PRIORITY           (0x0057 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_SET_SEC_MODE               (0x0096 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_H4IBSS              (0x00D4 | HCI_GRP_VENDOR_SPECIFIC)
+
+#define HCI_BRCM_SUPER_PEEK_POKE            (0x000A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_ARM_MEM_PEEK                    0x04
+#define HCI_ARM_MEM_POKE                    0x05
+#define HCI_BRCM_SUPER_PEEK_POKE_LENGTH     9
+
+#define HCI_BRCM_WRITE_I2SPCM_INTF_PARAM    (0x006D | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_CONTROLLER_FEATURES   (0x006E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_FEATURE_NFC_MASK           0x10
+#define HCI_BRCM_FEATURE_NFC_OFF            0
+
+#define HCI_BRCM_READ_VERBOSE_CFG_VER_INFO  (0x0079 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* Dual Stack */
+#define HCI_BRCM_PAUSE_TRANSPORT            (0x007A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_TRANSPORT_RESUME           (0x007B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_TRANSPORT_ERROR_EVT        0x0C
+
+#define HCI_BRCM_TX_POWER_OPCODE            (0x007D | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_ENABLE_WBS                 (0x007E | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_UIPC_OVER_HCI              (0x008B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_READ_AUDIO_ROUTE_INFO      (0x00A2 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_UIPC_OVER_HCI_EVT          0x1A
+#define HCI_BRCM_ENCAPSULATED_HCI           (0x00A3 | HCI_GRP_VENDOR_SPECIFIC)
+/* VSE subcode - VSE format FF [len] [subcode] [vse params...] */
+#define HCI_BRCM_ENCAPSULATED_HCI_EVT       0x1E
+
+/* PCM2 Setup */
+#define HCI_BRCM_PCM2_SETUP                 (0x00AE | HCI_GRP_VENDOR_SPECIFIC)
+
+/* BRR */
+#define HCI_BRCM_SET_BRR                    (0x00AA | HCI_GRP_VENDOR_SPECIFIC)
+
+/* 3DTV */
+#define HCI_BRCM_3D_CTRL                    (0x00B7 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_3D_OFFSET_DELAY            (0x00D6 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* GPS */
+#define HCI_BRCM_GPS_DATA                   (0x0089 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_GPS_SENSOR_OPCODE          (0x008F | HCI_GRP_VENDOR_SPECIFIC)  /* GPS sensor VSC opcode */
+
+/* MIP: Multicast Individual Polling */
+#define HCI_BRCM_INIT_MIP                   (0x00DC | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_MIP_OPEN_CMD               (0x00DD | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_MIP_CLOSE_CMD              (0x00DE | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_MIP_ENC_KEY_CMD            (0x00DF | HCI_GRP_VENDOR_SPECIFIC)
+
+/* MIP-related definitions */
+#define BRCM_MIP_ROLE_MASTER                0x00
+#define BRCM_MIP_ROLE_SLAVE                 0x01
+
+#define BRCM_MIP_MODE_A2DP                  0x00
+#define BRCM_MIP_MODE_3DG                   0x01
+#define BRCM_MIP_MODE_CMBO                  0x02    /* A2DP + 3DG */
+
+/* Parameter information for HCI_BRCM_SET_ACL_PRIORITY */
+#define HCI_BRCM_ACL_PRIORITY_PARAM_SIZE    3
+#define HCI_BRCM_ACL_PRIORITY_LOW           0x00
+#define HCI_BRCM_ACL_PRIORITY_HIGH          0xFF
+
+#define HCI_BRCM_PAUSE_TRANSPORT_LENGTH     6
+
+/* Parameter information for HCI_BRCM_SCO_PCM_INT_PARAM */
+#define HCI_BRCM_SCO_PCM_PARAM_SIZE         5
+#define HCI_BRCM_SCO_ROUTE_PCM              0
+#define HCI_BRCM_SCO_ROUTE_HCI              1
+
+/* Parameter information for HCI_BRCM_WRITE_I2SPCM_INTF_PARAM */
+#define HCI_BRCM_I2SPCM_PARAM_SIZE          4
+#define HCI_BRCM_I2SPCM_I2S_DISABLE         0
+#define HCI_BRCM_I2SPCM_I2S_ENABLE          1
+#define HCI_BRCM_I2SPCM_IS_SLAVE            0
+#define HCI_BRCM_I2SPCM_IS_MASTER           1
+#define HCI_BRCM_I2SPCM_IS_DEFAULT_ROLE     2
+#define HCI_BRCM_I2SPCM_SAMPLE_8K           0
+#define HCI_BRCM_I2SPCM_SAMPLE_16K          1
+#define HCI_BRCM_I2SPCM_SAMPLE_4K           2
+#define HCI_BRCM_I2SPCM_SAMPLE_DEFAULT      3
+#define HCI_BRCM_I2SPCM_CLOCK_128K          0
+#define HCI_BRCM_I2SPCM_CLOCK_256K          1
+#define HCI_BRCM_I2SPCM_CLOCK_512K          2
+#define HCI_BRCM_I2SPCM_CLOCK_1024K         3
+#define HCI_BRCM_I2SPCM_CLOCK_2048K         4
+#define HCI_BRCM_I2SPCM_CLOCK_DEFAULT       5
+
+/*
+**  Definitions for HCI Events
+*/
+#define HCI_INQUIRY_COMP_EVT                0x01
+#define HCI_INQUIRY_RESULT_EVT              0x02
+#define HCI_CONNECTION_COMP_EVT             0x03
+#define HCI_CONNECTION_REQUEST_EVT          0x04
+#define HCI_DISCONNECTION_COMP_EVT          0x05
+#define HCI_AUTHENTICATION_COMP_EVT         0x06
+#define HCI_RMT_NAME_REQUEST_COMP_EVT       0x07
+#define HCI_ENCRYPTION_CHANGE_EVT           0x08
+#define HCI_CHANGE_CONN_LINK_KEY_EVT        0x09
+#define HCI_MASTER_LINK_KEY_COMP_EVT        0x0A
+#define HCI_READ_RMT_FEATURES_COMP_EVT      0x0B
+#define HCI_READ_RMT_VERSION_COMP_EVT       0x0C
+#define HCI_QOS_SETUP_COMP_EVT              0x0D
+#define HCI_COMMAND_COMPLETE_EVT            0x0E
+#define HCI_COMMAND_STATUS_EVT              0x0F
+#define HCI_HARDWARE_ERROR_EVT              0x10
+#define HCI_FLUSH_OCCURED_EVT               0x11
+#define HCI_ROLE_CHANGE_EVT                 0x12
+#define HCI_NUM_COMPL_DATA_PKTS_EVT         0x13
+#define HCI_MODE_CHANGE_EVT                 0x14
+#define HCI_RETURN_LINK_KEYS_EVT            0x15
+#define HCI_PIN_CODE_REQUEST_EVT            0x16
+#define HCI_LINK_KEY_REQUEST_EVT            0x17
+#define HCI_LINK_KEY_NOTIFICATION_EVT       0x18
+#define HCI_LOOPBACK_COMMAND_EVT            0x19
+#define HCI_DATA_BUF_OVERFLOW_EVT           0x1A
+#define HCI_MAX_SLOTS_CHANGED_EVT           0x1B
+#define HCI_READ_CLOCK_OFF_COMP_EVT         0x1C
+#define HCI_CONN_PKT_TYPE_CHANGE_EVT        0x1D
+#define HCI_QOS_VIOLATION_EVT               0x1E
+#define HCI_PAGE_SCAN_MODE_CHANGE_EVT       0x1F
+#define HCI_PAGE_SCAN_REP_MODE_CHNG_EVT     0x20
+#define HCI_FLOW_SPECIFICATION_COMP_EVT     0x21
+#define HCI_INQUIRY_RSSI_RESULT_EVT         0x22
+#define HCI_READ_RMT_EXT_FEATURES_COMP_EVT  0x23
+#define HCI_ESCO_CONNECTION_COMP_EVT        0x2C
+#define HCI_ESCO_CONNECTION_CHANGED_EVT     0x2D
+#define HCI_SNIFF_SUB_RATE_EVT              0x2E
+#define HCI_EXTENDED_INQUIRY_RESULT_EVT     0x2F
+#define HCI_ENCRYPTION_KEY_REFRESH_COMP_EVT 0x30
+#define HCI_IO_CAPABILITY_REQUEST_EVT       0x31
+#define HCI_IO_CAPABILITY_RESPONSE_EVT      0x32
+#define HCI_USER_CONFIRMATION_REQUEST_EVT   0x33
+#define HCI_USER_PASSKEY_REQUEST_EVT        0x34
+#define HCI_REMOTE_OOB_DATA_REQUEST_EVT     0x35
+#define HCI_SIMPLE_PAIRING_COMPLETE_EVT     0x36
+#define HCI_LINK_SUPER_TOUT_CHANGED_EVT     0x38
+#define HCI_ENHANCED_FLUSH_COMPLETE_EVT     0x39
+#define HCI_USER_PASSKEY_NOTIFY_EVT         0x3B
+#define HCI_KEYPRESS_NOTIFY_EVT             0x3C
+#define HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT    0x3D
+
+/*#define HCI_GENERIC_AMP_LINK_KEY_NOTIF_EVT  0x3E Removed from spec */
+#define HCI_PHYSICAL_LINK_COMP_EVT          0x40
+#define HCI_CHANNEL_SELECTED_EVT            0x41
+#define HCI_DISC_PHYSICAL_LINK_COMP_EVT     0x42
+#define HCI_PHY_LINK_LOSS_EARLY_WARNING_EVT 0x43
+#define HCI_PHY_LINK_RECOVERY_EVT           0x44
+#define HCI_LOGICAL_LINK_COMP_EVT           0x45
+#define HCI_DISC_LOGICAL_LINK_COMP_EVT      0x46
+#define HCI_FLOW_SPEC_MODIFY_COMP_EVT       0x47
+#define HCI_NUM_COMPL_DATA_BLOCKS_EVT       0x48
+#define HCI_SHORT_RANGE_MODE_COMPLETE_EVT   0x4C
+#define HCI_AMP_STATUS_CHANGE_EVT           0x4D
+
+/* ULP HCI Event */
+#define HCI_BLE_EVENT                   0x03E
+/* ULP Event sub code */
+#define HCI_BLE_CONN_COMPLETE_EVT           0x01
+#define HCI_BLE_ADV_PKT_RPT_EVT             0x02
+#define HCI_BLE_LL_CONN_PARAM_UPD_EVT       0x03
+#define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT   0x04
+#define HCI_BLE_LTK_REQ_EVT                 0x05
+
+#define HCI_EVENT_RSP_FIRST             HCI_INQUIRY_COMP_EVT
+#define HCI_EVENT_RSP_LAST              HCI_AMP_STATUS_CHANGE_EVT
+
+#define HCI_BRCM_H4IBSS_EVT             0xEF  /* Vendor specific events for H4IBSS */
+#define HCI_VENDOR_SPECIFIC_EVT         0xFF  /* Vendor specific events */
+#define HCI_NAP_TRACE_EVT               0xFF  /* was define 0xFE, 0xFD, change to 0xFF
+                                                 because conflict w/ TCI_EVT and per
+                                                 specification compliant */
+
+
+
+/*
+**  Defentions for HCI Error Codes that are past in the events
+*/
+#define HCI_SUCCESS                                     0x00
+#define HCI_PENDING                                     0x00
+#define HCI_ERR_ILLEGAL_COMMAND                         0x01
+#define HCI_ERR_NO_CONNECTION                           0x02
+#define HCI_ERR_HW_FAILURE                              0x03
+#define HCI_ERR_PAGE_TIMEOUT                            0x04
+#define HCI_ERR_AUTH_FAILURE                            0x05
+#define HCI_ERR_KEY_MISSING                             0x06
+#define HCI_ERR_MEMORY_FULL                             0x07
+#define HCI_ERR_CONNECTION_TOUT                         0x08
+#define HCI_ERR_MAX_NUM_OF_CONNECTIONS                  0x09
+#define HCI_ERR_MAX_NUM_OF_SCOS                         0x0A
+#define HCI_ERR_CONNECTION_EXISTS                       0x0B
+#define HCI_ERR_COMMAND_DISALLOWED                      0x0C
+#define HCI_ERR_HOST_REJECT_RESOURCES                   0x0D
+#define HCI_ERR_HOST_REJECT_SECURITY                    0x0E
+#define HCI_ERR_HOST_REJECT_DEVICE                      0x0F
+#define HCI_ERR_HOST_TIMEOUT                            0x10
+#define HCI_ERR_UNSUPPORTED_VALUE                       0x11
+#define HCI_ERR_ILLEGAL_PARAMETER_FMT                   0x12
+#define HCI_ERR_PEER_USER                               0x13
+#define HCI_ERR_PEER_LOW_RESOURCES                      0x14
+#define HCI_ERR_PEER_POWER_OFF                          0x15
+#define HCI_ERR_CONN_CAUSE_LOCAL_HOST                   0x16
+#define HCI_ERR_REPEATED_ATTEMPTS                       0x17
+#define HCI_ERR_PAIRING_NOT_ALLOWED                     0x18
+#define HCI_ERR_UNKNOWN_LMP_PDU                         0x19
+#define HCI_ERR_UNSUPPORTED_REM_FEATURE                 0x1A
+#define HCI_ERR_SCO_OFFSET_REJECTED                     0x1B
+#define HCI_ERR_SCO_INTERVAL_REJECTED                   0x1C
+#define HCI_ERR_SCO_AIR_MODE                            0x1D
+#define HCI_ERR_INVALID_LMP_PARAM                       0x1E
+#define HCI_ERR_UNSPECIFIED                             0x1F
+#define HCI_ERR_UNSUPPORTED_LMP_FEATURE                 0x20
+#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED                 0x21
+#define HCI_ERR_LMP_RESPONSE_TIMEOUT                    0x22
+#define HCI_ERR_LMP_ERR_TRANS_COLLISION                 0x23
+#define HCI_ERR_LMP_PDU_NOT_ALLOWED                     0x24
+#define HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE               0x25
+#define HCI_ERR_UNIT_KEY_USED                           0x26
+#define HCI_ERR_QOS_NOT_SUPPORTED                       0x27
+#define HCI_ERR_INSTANT_PASSED                          0x28
+#define HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED     0x29
+#define HCI_ERR_DIFF_TRANSACTION_COLLISION              0x2A
+#define HCI_ERR_UNDEFINED_0x2B                          0x2B
+#define HCI_ERR_QOS_UNACCEPTABLE_PARAM                  0x2C
+#define HCI_ERR_QOS_REJECTED                            0x2D
+#define HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED              0x2E
+#define HCI_ERR_INSUFFCIENT_SECURITY                    0x2F
+#define HCI_ERR_PARAM_OUT_OF_RANGE                      0x30
+#define HCI_ERR_UNDEFINED_0x31                          0x31
+#define HCI_ERR_ROLE_SWITCH_PENDING                     0x32
+#define HCI_ERR_UNDEFINED_0x33                          0x33
+#define HCI_ERR_RESERVED_SLOT_VIOLATION                 0x34
+#define HCI_ERR_ROLE_SWITCH_FAILED                      0x35
+#define HCI_ERR_INQ_RSP_DATA_TOO_LARGE                  0x36
+#define HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED            0x37
+#define HCI_ERR_HOST_BUSY_PAIRING                       0x38
+#define HCI_ERR_REJ_NO_SUITABLE_CHANNEL                 0x39
+#define HCI_ERR_CONTROLLER_BUSY                         0x3A
+#define HCI_ERR_UNACCEPT_CONN_INTERVAL                  0x3B
+#define HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT            0x3C
+#define HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE            0x3D
+#define HCI_ERR_CONN_FAILED_ESTABLISHMENT               0x3E
+#define HCI_ERR_MAC_CONNECTION_FAILED                   0x3F
+
+#define HCI_ERR_MAX_ERR                                 0x40
+
+#define HCI_HINT_TO_RECREATE_AMP_PHYS_LINK              0xFF
+
+/*
+** Definitions for HCI enable event
+*/
+#define HCI_INQUIRY_COMPLETE_EV(p)          (*((UINT32 *)(p)) & 0x00000001)
+#define HCI_INQUIRY_RESULT_EV(p)            (*((UINT32 *)(p)) & 0x00000002)
+#define HCI_CONNECTION_COMPLETE_EV(p)       (*((UINT32 *)(p)) & 0x00000004)
+#define HCI_CONNECTION_REQUEST_EV(p)        (*((UINT32 *)(p)) & 0x00000008)
+#define HCI_DISCONNECTION_COMPLETE_EV(p)    (*((UINT32 *)(p)) & 0x00000010)
+#define HCI_AUTHENTICATION_COMPLETE_EV(p)   (*((UINT32 *)(p)) & 0x00000020)
+#define HCI_RMT_NAME_REQUEST_COMPL_EV(p)    (*((UINT32 *)(p)) & 0x00000040)
+#define HCI_CHANGE_CONN_ENCRPT_ENABLE_EV(p) (*((UINT32 *)(p)) & 0x00000080)
+#define HCI_CHANGE_CONN_LINK_KEY_EV(p)      (*((UINT32 *)(p)) & 0x00000100)
+#define HCI_MASTER_LINK_KEY_COMPLETE_EV(p)  (*((UINT32 *)(p)) & 0x00000200)
+#define HCI_READ_RMT_FEATURES_COMPL_EV(p)   (*((UINT32 *)(p)) & 0x00000400)
+#define HCI_READ_RMT_VERSION_COMPL_EV(p)    (*((UINT32 *)(p)) & 0x00000800)
+#define HCI_QOS_SETUP_COMPLETE_EV(p)        (*((UINT32 *)(p)) & 0x00001000)
+#define HCI_COMMAND_COMPLETE_EV(p)          (*((UINT32 *)(p)) & 0x00002000)
+#define HCI_COMMAND_STATUS_EV(p)            (*((UINT32 *)(p)) & 0x00004000)
+#define HCI_HARDWARE_ERROR_EV(p)            (*((UINT32 *)(p)) & 0x00008000)
+#define HCI_FLASH_OCCURED_EV(p)             (*((UINT32 *)(p)) & 0x00010000)
+#define HCI_ROLE_CHANGE_EV(p)               (*((UINT32 *)(p)) & 0x00020000)
+#define HCI_NUM_COMPLETED_PKTS_EV(p)        (*((UINT32 *)(p)) & 0x00040000)
+#define HCI_MODE_CHANGE_EV(p)               (*((UINT32 *)(p)) & 0x00080000)
+#define HCI_RETURN_LINK_KEYS_EV(p)          (*((UINT32 *)(p)) & 0x00100000)
+#define HCI_PIN_CODE_REQUEST_EV(p)          (*((UINT32 *)(p)) & 0x00200000)
+#define HCI_LINK_KEY_REQUEST_EV(p)          (*((UINT32 *)(p)) & 0x00400000)
+#define HCI_LINK_KEY_NOTIFICATION_EV(p)     (*((UINT32 *)(p)) & 0x00800000)
+#define HCI_LOOPBACK_COMMAND_EV(p)          (*((UINT32 *)(p)) & 0x01000000)
+#define HCI_DATA_BUF_OVERFLOW_EV(p)         (*((UINT32 *)(p)) & 0x02000000)
+#define HCI_MAX_SLOTS_CHANGE_EV(p)          (*((UINT32 *)(p)) & 0x04000000)
+#define HCI_READ_CLOCK_OFFSET_COMP_EV(p)    (*((UINT32 *)(p)) & 0x08000000)
+#define HCI_CONN_PKT_TYPE_CHANGED_EV(p)     (*((UINT32 *)(p)) & 0x10000000)
+#define HCI_QOS_VIOLATION_EV(p)             (*((UINT32 *)(p)) & 0x20000000)
+#define HCI_PAGE_SCAN_MODE_CHANGED_EV(p)    (*((UINT32 *)(p)) & 0x40000000)
+#define HCI_PAGE_SCAN_REP_MODE_CHNG_EV(p)   (*((UINT32 *)(p)) & 0x80000000)
+
+/* the default event mask for 2.1+EDR (Lisbon) does not include Lisbon events */
+#define HCI_DEFAULT_EVENT_MASK_0            0xFFFFFFFF
+#define HCI_DEFAULT_EVENT_MASK_1            0x00001FFF
+
+/* the event mask for 2.0 + EDR and later (includes Lisbon events) */
+#define HCI_LISBON_EVENT_MASK_0             0xFFFFFFFF
+#define HCI_LISBON_EVENT_MASK_1             0x1DBFFFFF
+#define HCI_LISBON_EVENT_MASK               "\x0D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+#define HCI_LISBON_EVENT_MASK_EXT           "\x1D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+#define HCI_DUMO_EVENT_MASK_EXT             "\x3D\xBF\xFF\xFF\xFF\xFF\xFF\xFF"
+/*  0x00001FFF FFFFFFFF Default - no Lisbon events
+    0x00000800 00000000 Synchronous Connection Complete Event
+    0x00001000 00000000 Synchronous Connection Changed Event
+    0x00002000 00000000 Sniff Subrate Event
+    0x00004000 00000000 Extended Inquiry Result Event
+    0x00008000 00000000 Encryption Key Refresh Complete Event
+    0x00010000 00000000 IO Capability Request Event
+    0x00020000 00000000 IO Capability Response Event
+    0x00040000 00000000 User Confirmation Request Event
+    0x00080000 00000000 User Passkey Request Event
+    0x00100000 00000000 Remote OOB Data Request Event
+    0x00200000 00000000 Simple Pairing Complete Event
+    0x00400000 00000000 Generic AMP Link Key Notification Event
+    0x00800000 00000000 Link Supervision Timeout Changed Event
+    0x01000000 00000000 Enhanced Flush Complete Event
+    0x04000000 00000000 User Passkey Notification Event
+    0x08000000 00000000 Keypress Notification Event
+    0x10000000 00000000 Remote Host Supported Features Notification Event
+    0x20000000 00000000 LE Meta Event
+ */
+
+
+/* the event mask for AMP controllers */
+#define HCI_AMP_EVENT_MASK_3_0               "\x00\x00\x00\x00\x00\x00\x3F\xFF"
+
+/*  0x0000000000000000 No events specified (default)
+    0x0000000000000001 Physical Link Complete Event
+    0x0000000000000002 Channel Selected Event
+    0x0000000000000004 Disconnection Physical Link Event
+    0x0000000000000008 Physical Link Loss Early Warning Event
+    0x0000000000000010 Physical Link Recovery Event
+    0x0000000000000020 Logical Link Complete Event
+    0x0000000000000040 Disconnection Logical Link Complete Event
+    0x0000000000000080 Flow Spec Modify Complete Event
+    0x0000000000000100 Number of Completed Data Blocks Event
+    0x0000000000000200 AMP Start Test Event
+    0x0000000000000400 AMP Test End Event
+    0x0000000000000800 AMP Receiver Report Event
+    0x0000000000001000 Short Range Mode Change Complete Event
+    0x0000000000002000 AMP Status Change Event
+*/
+
+
+/*
+** Definitions for packet type masks (BT1.2 and BT2.0 definitions)
+*/
+#define HCI_PKT_TYPES_MASK_NO_2_DH1         0x0002
+#define HCI_PKT_TYPES_MASK_NO_3_DH1         0x0004
+#define HCI_PKT_TYPES_MASK_DM1              0x0008
+#define HCI_PKT_TYPES_MASK_DH1              0x0010
+#define HCI_PKT_TYPES_MASK_HV1              0x0020
+#define HCI_PKT_TYPES_MASK_HV2              0x0040
+#define HCI_PKT_TYPES_MASK_HV3              0x0080
+#define HCI_PKT_TYPES_MASK_NO_2_DH3         0x0100
+#define HCI_PKT_TYPES_MASK_NO_3_DH3         0x0200
+#define HCI_PKT_TYPES_MASK_DM3              0x0400
+#define HCI_PKT_TYPES_MASK_DH3              0x0800
+#define HCI_PKT_TYPES_MASK_NO_2_DH5         0x1000
+#define HCI_PKT_TYPES_MASK_NO_3_DH5         0x2000
+#define HCI_PKT_TYPES_MASK_DM5              0x4000
+#define HCI_PKT_TYPES_MASK_DH5              0x8000
+
+/* Packet type should be one of valid but at least one should be specified */
+#define HCI_VALID_SCO_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_HV1       \
+                                           |  HCI_PKT_TYPES_MASK_HV2       \
+                                           |  HCI_PKT_TYPES_MASK_HV3)) == 0)) \
+                                    && ((t) != 0))
+
+
+
+
+
+/* Packet type should not be invalid and at least one should be specified */
+#define HCI_VALID_ACL_PKT_TYPE(t) (((((t) & ~(HCI_PKT_TYPES_MASK_DM1        \
+                                           |  HCI_PKT_TYPES_MASK_DH1        \
+                                           |  HCI_PKT_TYPES_MASK_DM3        \
+                                           |  HCI_PKT_TYPES_MASK_DH3        \
+                                           |  HCI_PKT_TYPES_MASK_DM5        \
+                                           |  HCI_PKT_TYPES_MASK_DH5        \
+                                           |  HCI_PKT_TYPES_MASK_NO_2_DH1   \
+                                           |  HCI_PKT_TYPES_MASK_NO_3_DH1   \
+                                           |  HCI_PKT_TYPES_MASK_NO_2_DH3   \
+                                           |  HCI_PKT_TYPES_MASK_NO_3_DH3   \
+                                           |  HCI_PKT_TYPES_MASK_NO_2_DH5   \
+                                           |  HCI_PKT_TYPES_MASK_NO_3_DH5  )) == 0)) \
+                                    && (((t) &  (HCI_PKT_TYPES_MASK_DM1        \
+                                              |  HCI_PKT_TYPES_MASK_DH1        \
+                                              |  HCI_PKT_TYPES_MASK_DM3        \
+                                              |  HCI_PKT_TYPES_MASK_DH3        \
+                                              |  HCI_PKT_TYPES_MASK_DM5        \
+                                              |  HCI_PKT_TYPES_MASK_DH5)) != 0))
+
+/*
+** Definitions for eSCO packet type masks (BT1.2 and BT2.0 definitions)
+*/
+#define HCI_ESCO_PKT_TYPES_MASK_HV1         0x0001
+#define HCI_ESCO_PKT_TYPES_MASK_HV2         0x0002
+#define HCI_ESCO_PKT_TYPES_MASK_HV3         0x0004
+#define HCI_ESCO_PKT_TYPES_MASK_EV3         0x0008
+#define HCI_ESCO_PKT_TYPES_MASK_EV4         0x0010
+#define HCI_ESCO_PKT_TYPES_MASK_EV5         0x0020
+#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3    0x0040
+#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3    0x0080
+#define HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5    0x0100
+#define HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5    0x0200
+
+/* Packet type should be one of valid but at least one should be specified for 1.2 */
+#define HCI_VALID_ESCO_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_EV3       \
+                                           |   HCI_ESCO_PKT_TYPES_MASK_EV4       \
+                                           |   HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \
+                                    && ((t) != 0))/* Packet type should be one of valid but at least one should be specified */
+
+#define HCI_VALID_ESCO_SCOPKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV2       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV3)) == 0)) \
+                                    && ((t) != 0))
+
+#define HCI_VALID_SCO_ALL_PKT_TYPE(t) (((((t) & ~(HCI_ESCO_PKT_TYPES_MASK_HV1       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV2       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_HV3       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_EV3       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_EV4       \
+                                           |      HCI_ESCO_PKT_TYPES_MASK_EV5)) == 0)) \
+                                    && ((t) != 0))
+
+/*
+** Define parameters to allow role switch during create connection
+*/
+#define HCI_CR_CONN_NOT_ALLOW_SWITCH    0x00
+#define HCI_CR_CONN_ALLOW_SWITCH        0x01
+
+/*
+** Hold Mode command destination
+*/
+#define HOLD_MODE_DEST_LOCAL_DEVICE     0x00
+#define HOLD_MODE_DEST_RMT_DEVICE       0x01
+
+/*
+**  Definitions for different HCI parameters
+*/
+#define HCI_PER_INQ_MIN_MAX_PERIOD      0x0003
+#define HCI_PER_INQ_MAX_MAX_PERIOD      0xFFFF
+#define HCI_PER_INQ_MIN_MIN_PERIOD      0x0002
+#define HCI_PER_INQ_MAX_MIN_PERIOD      0xFFFE
+
+#define HCI_MAX_INQUIRY_LENGTH          0x30
+
+#define HCI_MIN_INQ_LAP                 0x9E8B00
+#define HCI_MAX_INQ_LAP                 0x9E8B3F
+
+/* HCI role defenitions */
+#define HCI_ROLE_MASTER                 0x00
+#define HCI_ROLE_SLAVE                  0x01
+#define HCI_ROLE_UNKNOWN                0xff
+
+/* HCI mode defenitions */
+#define HCI_MODE_ACTIVE                 0x00
+#define HCI_MODE_HOLD                   0x01
+#define HCI_MODE_SNIFF                  0x02
+#define HCI_MODE_PARK                   0x03
+
+/* HCI Flow Control Mode defenitions */
+#define HCI_PACKET_BASED_FC_MODE        0x00
+#define HCI_BLOCK_BASED_FC_MODE         0x01
+
+/* Define Packet types as requested by the Host */
+#define HCI_ACL_PKT_TYPE_NONE           0x0000
+#define HCI_ACL_PKT_TYPE_DM1            0x0008
+#define HCI_ACL_PKT_TYPE_DH1            0x0010
+#define HCI_ACL_PKT_TYPE_AUX1           0x0200
+#define HCI_ACL_PKT_TYPE_DM3            0x0400
+#define HCI_ACL_PKT_TYPE_DH3            0x0800
+#define HCI_ACL_PKT_TYPE_DM5            0x4000
+#define HCI_ACL_PKT_TYPE_DH5            0x8000
+
+/* Define key type in the Master Link Key command */
+#define HCI_USE_SEMI_PERMANENT_KEY      0x00
+#define HCI_USE_TEMPORARY_KEY           0x01
+
+/* Page scan period modes */
+#define HCI_PAGE_SCAN_REP_MODE_R0       0x00
+#define HCI_PAGE_SCAN_REP_MODE_R1       0x01
+#define HCI_PAGE_SCAN_REP_MODE_R2       0x02
+
+/* Define limits for page scan repetition modes */
+#define HCI_PAGE_SCAN_R1_LIMIT          0x0800
+#define HCI_PAGE_SCAN_R2_LIMIT          0x1000
+
+/* Page scan period modes */
+#define HCI_PAGE_SCAN_PER_MODE_P0       0x00
+#define HCI_PAGE_SCAN_PER_MODE_P1       0x01
+#define HCI_PAGE_SCAN_PER_MODE_P2       0x02
+
+/* Page scan modes */
+#define HCI_MANDATARY_PAGE_SCAN_MODE    0x00
+#define HCI_OPTIONAL_PAGE_SCAN_MODE1    0x01
+#define HCI_OPTIONAL_PAGE_SCAN_MODE2    0x02
+#define HCI_OPTIONAL_PAGE_SCAN_MODE3    0x03
+
+/* Page and inquiry scan types */
+#define HCI_SCAN_TYPE_STANDARD          0x00
+#define HCI_SCAN_TYPE_INTERLACED        0x01       /* 1.2 devices or later */
+#define HCI_DEF_SCAN_TYPE               HCI_SCAN_TYPE_STANDARD
+
+/* Definitions for quality of service service types */
+#define HCI_SERVICE_NO_TRAFFIC          0x00
+#define HCI_SERVICE_BEST_EFFORT         0x01
+#define HCI_SERVICE_GUARANTEED          0x02
+
+#define HCI_QOS_LATENCY_DO_NOT_CARE     0xFFFFFFFF
+#define HCI_QOS_DELAY_DO_NOT_CARE       0xFFFFFFFF
+
+/* Definitions for Flow Specification */
+#define HCI_FLOW_SPEC_LATENCY_DO_NOT_CARE 0xFFFFFFFF
+
+/* Definitions for AFH Channel Map */
+#define HCI_AFH_CHANNEL_MAP_LEN         10
+
+/* Definitions for Extended Inquiry Response */
+#define HCI_EXT_INQ_RESPONSE_LEN        240
+#define HCI_EIR_FLAGS_TYPE                   BT_EIR_FLAGS_TYPE
+#define HCI_EIR_MORE_16BITS_UUID_TYPE        BT_EIR_MORE_16BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_16BITS_UUID_TYPE    BT_EIR_COMPLETE_16BITS_UUID_TYPE
+#define HCI_EIR_MORE_32BITS_UUID_TYPE        BT_EIR_MORE_32BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_32BITS_UUID_TYPE    BT_EIR_COMPLETE_32BITS_UUID_TYPE
+#define HCI_EIR_MORE_128BITS_UUID_TYPE       BT_EIR_MORE_128BITS_UUID_TYPE
+#define HCI_EIR_COMPLETE_128BITS_UUID_TYPE   BT_EIR_COMPLETE_128BITS_UUID_TYPE
+#define HCI_EIR_SHORTENED_LOCAL_NAME_TYPE    BT_EIR_SHORTENED_LOCAL_NAME_TYPE
+#define HCI_EIR_COMPLETE_LOCAL_NAME_TYPE     BT_EIR_COMPLETE_LOCAL_NAME_TYPE
+#define HCI_EIR_TX_POWER_LEVEL_TYPE          BT_EIR_TX_POWER_LEVEL_TYPE
+#define HCI_EIR_MANUFACTURER_SPECIFIC_TYPE   BT_EIR_MANUFACTURER_SPECIFIC_TYPE
+#define HCI_EIR_OOB_BD_ADDR_TYPE             BT_EIR_OOB_BD_ADDR_TYPE
+#define HCI_EIR_OOB_COD_TYPE                 BT_EIR_OOB_COD_TYPE
+#define HCI_EIR_OOB_SSP_HASH_C_TYPE          BT_EIR_OOB_SSP_HASH_C_TYPE
+#define HCI_EIR_OOB_SSP_RAND_R_TYPE          BT_EIR_OOB_SSP_RAND_R_TYPE
+
+/* Definitions for Write Simple Pairing Mode */
+#define HCI_SP_MODE_UNDEFINED           0x00
+#define HCI_SP_MODE_ENABLED             0x01
+
+/* Definitions for Write Simple Pairing Debug Mode */
+#define HCI_SPD_MODE_DISABLED           0x00
+#define HCI_SPD_MODE_ENABLED            0x01
+
+/* Definitions for IO Capability Response/Command */
+#define HCI_IO_CAP_DISPLAY_ONLY         0x00
+#define HCI_IO_CAP_DISPLAY_YESNO        0x01
+#define HCI_IO_CAP_KEYBOARD_ONLY        0x02
+#define HCI_IO_CAP_NO_IO                0x03
+
+#define HCI_OOB_AUTH_DATA_NOT_PRESENT   0x00
+#define HCI_OOB_REM_AUTH_DATA_PRESENT   0x01
+
+#define HCI_MITM_PROTECT_NOT_REQUIRED  0x00
+#define HCI_MITM_PROTECT_REQUIRED      0x01
+
+
+/* Policy settings status */
+#define HCI_DISABLE_ALL_LM_MODES        0x0000
+#define HCI_ENABLE_MASTER_SLAVE_SWITCH  0x0001
+#define HCI_ENABLE_HOLD_MODE            0x0002
+#define HCI_ENABLE_SNIFF_MODE           0x0004
+#define HCI_ENABLE_PARK_MODE            0x0008
+
+/* By default allow switch, because host can not allow that */
+/* that until he created the connection */
+#define HCI_DEFAULT_POLICY_SETTINGS     HCI_DISABLE_ALL_LM_MODES
+
+/* Filters that are sent in set filter command */
+#define HCI_FILTER_TYPE_CLEAR_ALL       0x00
+#define HCI_FILTER_INQUIRY_RESULT       0x01
+#define HCI_FILTER_CONNECTION_SETUP     0x02
+
+#define HCI_FILTER_COND_NEW_DEVICE      0x00
+#define HCI_FILTER_COND_DEVICE_CLASS    0x01
+#define HCI_FILTER_COND_BD_ADDR         0x02
+
+#define HCI_DO_NOT_AUTO_ACCEPT_CONNECT  1
+#define HCI_DO_AUTO_ACCEPT_CONNECT      2   /* role switch disabled */
+#define HCI_DO_AUTO_ACCEPT_CONNECT_RS   3   /* role switch enabled (1.1 errata 1115) */
+
+/* Auto accept flags */
+#define HCI_AUTO_ACCEPT_OFF             0x00
+#define HCI_AUTO_ACCEPT_ACL_CONNECTIONS 0x01
+#define HCI_AUTO_ACCEPT_SCO_CONNECTIONS 0x02
+
+/* PIN type */
+#define HCI_PIN_TYPE_VARIABLE           0
+#define HCI_PIN_TYPE_FIXED              1
+
+/* Loopback Modes */
+#define HCI_LOOPBACK_MODE_DISABLED      0
+#define HCI_LOOPBACK_MODE_LOCAL         1
+#define HCI_LOOPBACK_MODE_REMOTE        2
+
+#define SLOTS_PER_10MS                  16      /* 0.625 ms slots in a 10 ms tick */
+
+/* Maximum connection accept timeout in 0.625msec */
+#define HCI_MAX_CONN_ACCEPT_TOUT        0xB540  /* 29 sec */
+#define HCI_DEF_CONN_ACCEPT_TOUT        0x1F40  /* 5 sec */
+
+/* Page timeout is used in LC only and LC is counting down slots not using OS */
+#define HCI_DEFAULT_PAGE_TOUT           0x2000  /* 5.12 sec (in slots) */
+
+/* Scan enable flags */
+#define HCI_NO_SCAN_ENABLED             0x00
+#define HCI_INQUIRY_SCAN_ENABLED        0x01
+#define HCI_PAGE_SCAN_ENABLED           0x02
+
+/* Pagescan timer definitions in 0.625 ms */
+#define HCI_MIN_PAGESCAN_INTERVAL       0x12    /* 11.25 ms */
+#define HCI_MAX_PAGESCAN_INTERVAL       0x1000  /* 2.56 sec */
+#define HCI_DEF_PAGESCAN_INTERVAL       0x0800  /* 1.28 sec */
+
+/* Parameter for pagescan window is passed to LC and is kept in slots */
+#define HCI_MIN_PAGESCAN_WINDOW         0x11    /* 10.625 ms */
+#define HCI_MAX_PAGESCAN_WINDOW         0x1000  /* 2.56  sec */
+#define HCI_DEF_PAGESCAN_WINDOW         0x12    /* 11.25 ms  */
+
+/* Inquiryscan timer definitions in 0.625 ms */
+#define HCI_MIN_INQUIRYSCAN_INTERVAL    0x12    /* 11.25 ms */
+#define HCI_MAX_INQUIRYSCAN_INTERVAL    0x1000  /* 2.56 sec */
+#define HCI_DEF_INQUIRYSCAN_INTERVAL    0x1000  /* 2.56 sec */
+
+/* Parameter for inquiryscan window is passed to LC and is kept in slots */
+#define HCI_MIN_INQUIRYSCAN_WINDOW      0x11    /* 10.625 ms */
+#define HCI_MAX_INQUIRYSCAN_WINDOW      0x1000  /* 2.56 sec */
+#define HCI_DEF_INQUIRYSCAN_WINDOW      0x12    /* 11.25 ms */
+
+/* Encryption modes */
+#define HCI_ENCRYPT_MODE_DISABLED       0x00
+#define HCI_ENCRYPT_MODE_POINT_TO_POINT 0x01
+#define HCI_ENCRYPT_MODE_ALL            0x02
+
+/* Voice settings */
+#define HCI_INP_CODING_LINEAR           0x0000 /* 0000000000 */
+#define HCI_INP_CODING_U_LAW            0x0100 /* 0100000000 */
+#define HCI_INP_CODING_A_LAW            0x0200 /* 1000000000 */
+#define HCI_INP_CODING_MASK             0x0300 /* 1100000000 */
+
+#define HCI_INP_DATA_FMT_1S_COMPLEMENT  0x0000 /* 0000000000 */
+#define HCI_INP_DATA_FMT_2S_COMPLEMENT  0x0040 /* 0001000000 */
+#define HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 /* 0010000000 */
+#define HCI_INP_DATA_FMT_UNSIGNED       0x00c0 /* 0011000000 */
+#define HCI_INP_DATA_FMT_MASK           0x00c0 /* 0011000000 */
+
+#define HCI_INP_SAMPLE_SIZE_8BIT        0x0000 /* 0000000000 */
+#define HCI_INP_SAMPLE_SIZE_16BIT       0x0020 /* 0000100000 */
+#define HCI_INP_SAMPLE_SIZE_MASK        0x0020 /* 0000100000 */
+
+#define HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c /* 0000011100 */
+#define HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
+
+#define HCI_AIR_CODING_FORMAT_CVSD      0x0000 /* 0000000000 */
+#define HCI_AIR_CODING_FORMAT_U_LAW     0x0001 /* 0000000001 */
+#define HCI_AIR_CODING_FORMAT_A_LAW     0x0002 /* 0000000010 */
+#define HCI_AIR_CODING_FORMAT_TRANSPNT  0x0003 /* 0000000011 */
+#define HCI_AIR_CODING_FORMAT_MASK      0x0003 /* 0000000011 */
+
+/* default                                        0001100000 */
+#define HCI_DEFAULT_VOICE_SETTINGS    (HCI_INP_CODING_LINEAR \
+                                     | HCI_INP_DATA_FMT_2S_COMPLEMENT \
+                                     | HCI_INP_SAMPLE_SIZE_16BIT \
+                                     | HCI_AIR_CODING_FORMAT_CVSD)
+
+#define HCI_CVSD_SUPPORTED(x)       (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_CVSD)
+#define HCI_U_LAW_SUPPORTED(x)      (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_U_LAW)
+#define HCI_A_LAW_SUPPORTED(x)      (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_A_LAW)
+#define HCI_TRANSPNT_SUPPORTED(x)   (((x) & HCI_AIR_CODING_FORMAT_MASK) == HCI_AIR_CODING_FORMAT_TRANSPNT)
+
+/* Retransmit timer definitions in 0.625 */
+#define HCI_MAX_AUTO_FLUSH_TOUT         0x07FF
+#define HCI_DEFAULT_AUTO_FLUSH_TOUT     0       /* No auto flush */
+
+/* Broadcast retransmitions */
+#define HCI_DEFAULT_NUM_BCAST_RETRAN    1
+
+/* Define broadcast data types as passed in the hci data packet */
+#define HCI_DATA_POINT_TO_POINT         0x00
+#define HCI_DATA_ACTIVE_BCAST           0x01
+#define HCI_DATA_PICONET_BCAST          0x02
+
+/* Hold mode activity */
+#define HCI_MAINTAIN_CUR_POWER_STATE    0x00
+#define HCI_SUSPEND_PAGE_SCAN           0x01
+#define HCI_SUSPEND_INQUIRY_SCAN        0x02
+#define HCI_SUSPEND_PERIODIC_INQUIRIES  0x04
+
+/* Default Link Supervision timeoout */
+#define HCI_DEFAULT_INACT_TOUT          0x7D00  /* BR/EDR (20 seconds) */
+#define HCI_DEFAULT_AMP_INACT_TOUT      0x3E80  /* AMP    (10 seconds) */
+
+/* Read transmit power level parameter */
+#define HCI_READ_CURRENT                0x00
+#define HCI_READ_MAXIMUM                0x01
+
+/* Link types for connection complete event */
+#define HCI_LINK_TYPE_SCO               0x00
+#define HCI_LINK_TYPE_ACL               0x01
+#define HCI_LINK_TYPE_ESCO              0x02
+
+/* Link Key Notification Event (Key Type) definitions */
+#define HCI_LKEY_TYPE_COMBINATION       0x00
+#define HCI_LKEY_TYPE_LOCAL_UNIT        0x01
+#define HCI_LKEY_TYPE_REMOTE_UNIT       0x02
+#define HCI_LKEY_TYPE_DEBUG_COMB        0x03
+#define HCI_LKEY_TYPE_UNAUTH_COMB       0x04
+#define HCI_LKEY_TYPE_AUTH_COMB         0x05
+#define HCI_LKEY_TYPE_CHANGED_COMB      0x06
+
+/* Internal definitions - not used over HCI */
+#define HCI_LKEY_TYPE_AMP_WIFI          0x80
+#define HCI_LKEY_TYPE_AMP_UWB           0x81
+#define HCI_LKEY_TYPE_UNKNOWN           0xff
+
+/* Read Local Version HCI Version return values (Command Complete Event) */
+#define HCI_VERSION_1_0B                0x00
+#define HCI_VERSION_1_1                 0x01
+
+/* Define an invalid value for a handle */
+#define HCI_INVALID_HANDLE              0xFFFF
+
+/* Define max ammount of data in the HCI command */
+#define HCI_COMMAND_SIZE        255
+
+/* Define the preamble length for all HCI Commands.
+** This is 2-bytes for opcode and 1 byte for length
+*/
+#define HCIC_PREAMBLE_SIZE      3
+
+/* Define the preamble length for all HCI Events
+** This is 1-byte for opcode and 1 byte for length
+*/
+#define HCIE_PREAMBLE_SIZE      2
+#define HCI_SCO_PREAMBLE_SIZE   3
+#define HCI_DATA_PREAMBLE_SIZE  4
+
+/* local Bluetooth controller id for AMP HCI */
+#define LOCAL_BR_EDR_CONTROLLER_ID      0
+
+/* controller id types for AMP HCI */
+#define HCI_CONTROLLER_TYPE_BR_EDR      0
+#define HCI_CONTROLLER_TYPE_802_11      1
+#define HCI_CONTROLLER_TYPE_ECMA        2
+#define HCI_MAX_CONTROLLER_TYPES        3
+
+
+
+
+/* AMP Controller Status codes
+*/
+#define HCI_AMP_CTRLR_PHYSICALLY_DOWN   0
+#define HCI_AMP_CTRLR_USABLE_BY_BT      1
+#define HCI_AMP_CTRLR_UNUSABLE_FOR_BT   2
+#define HCI_AMP_CTRLR_LOW_CAP_FOR_BT    3
+#define HCI_AMP_CTRLR_MED_CAP_FOR_BT    4
+#define HCI_AMP_CTRLR_HIGH_CAP_FOR_BT   5
+#define HCI_AMP_CTRLR_FULL_CAP_FOR_BT   6
+
+#define HCI_MAX_AMP_STATUS_TYPES        7
+
+
+/* Define the extended flow specification fields used by AMP */
+typedef struct
+{
+    UINT8       id;
+    UINT8       stype;
+    UINT16      max_sdu_size;
+    UINT32      sdu_inter_time;
+    UINT32      access_latency;
+    UINT32      flush_timeout;
+} tHCI_EXT_FLOW_SPEC;
+
+
+/* HCI message type definitions (for H4 messages) */
+#define HCIT_TYPE_COMMAND   1
+#define HCIT_TYPE_ACL_DATA  2
+#define HCIT_TYPE_SCO_DATA  3
+#define HCIT_TYPE_EVENT     4
+#define HCIT_TYPE_LM_DIAG   7
+#define HCIT_TYPE_NFC       16
+
+#define HCIT_LM_DIAG_LENGTH 63
+
+/* Define values for LMP Test Control parameters
+** Test Scenario, Hopping Mode, Power Control Mode
+*/
+#define LMP_TESTCTL_TESTSC_PAUSE        0
+#define LMP_TESTCTL_TESTSC_TXTEST_0     1
+#define LMP_TESTCTL_TESTSC_TXTEST_1     2
+#define LMP_TESTCTL_TESTSC_TXTEST_1010  3
+#define LMP_TESTCTL_TESTSC_PSRND_BITSEQ 4
+#define LMP_TESTCTL_TESTSC_CLOSEDLB_ACL 5
+#define LMP_TESTCTL_TESTSC_CLOSEDLB_SCO 6
+#define LMP_TESTCTL_TESTSC_ACL_NOWHIT   7
+#define LMP_TESTCTL_TESTSC_SCO_NOWHIT   8
+#define LMP_TESTCTL_TESTSC_TXTEST_11110000  9
+#define LMP_TESTCTL_TESTSC_EXITTESTMODE 255
+
+#define LMP_TESTCTL_HOPMOD_RXTX1FREQ    0
+#define LMP_TESTCTL_HOPMOD_HOP_EURUSA   1
+#define LMP_TESTCTL_HOPMOD_HOP_JAPAN    2
+#define LMP_TESTCTL_HOPMOD_HOP_FRANCE   3
+#define LMP_TESTCTL_HOPMOD_HOP_SPAIN    4
+#define LMP_TESTCTL_HOPMOD_REDUCED_HOP  5
+
+#define LMP_TESTCTL_POWCTL_FIXEDTX_OP   0
+#define LMP_TESTCTL_POWCTL_ADAPTIVE     1
+
+
+/*
+** Define company IDs (from Bluetooth Assigned Numbers v1.1, section 2.2)
+*/
+#define LMP_COMPID_ERICSSON             0
+#define LMP_COMPID_NOKIA                1
+#define LMP_COMPID_INTEL                2
+#define LMP_COMPID_IBM                  3
+#define LMP_COMPID_TOSHIBA              4
+#define LMP_COMPID_3COM                 5
+#define LMP_COMPID_MICROSOFT            6
+#define LMP_COMPID_LUCENT               7
+#define LMP_COMPID_MOTOROLA             8
+#define LMP_COMPID_INFINEON             9
+#define LMP_COMPID_CSR                  10
+#define LMP_COMPID_SILICON_WAVE         11
+#define LMP_COMPID_DIGIANSWER           12
+#define LMP_COMPID_TEXAS_INSTRUMENTS    13
+#define LMP_COMPID_PARTHUS              14
+#define LMP_COMPID_BROADCOM             15
+#define LMP_COMPID_MITEL_SEMI           16
+#define LMP_COMPID_WIDCOMM              17
+#define LMP_COMPID_ZEEVO                18
+#define LMP_COMPID_ATMEL                19
+#define LMP_COMPID_MITSUBISHI           20
+#define LMP_COMPID_RTX_TELECOM          21
+#define LMP_COMPID_KC_TECH              22
+#define LMP_COMPID_NEWLOGIC             23
+#define LMP_COMPID_TRANSILICA           24
+#define LMP_COMPID_ROHDE_SCHWARZ        25
+#define LMP_COMPID_TTPCOM               26
+#define LMP_COMPID_SIGNIA               27
+#define LMP_COMPID_CONEXANT             28
+#define LMP_COMPID_QUALCOMM             29
+#define LMP_COMPID_INVENTEL             30
+#define LMP_COMPID_AVM                  31
+#define LMP_COMPID_BANDSPEED            32
+#define LMP_COMPID_MANSELLA             33
+#define LMP_COMPID_NEC_CORP             34
+#define LMP_COMPID_WAVEPLUS             35
+#define LMP_COMPID_ALCATEL              36
+#define LMP_COMPID_PHILIPS              37
+#define LMP_COMPID_C_TECHNOLOGIES       38
+#define LMP_COMPID_OPEN_INTERFACE       39
+#define LMP_COMPID_RF_MICRO             40
+#define LMP_COMPID_HITACHI              41
+#define LMP_COMPID_SYMBOL_TECH          42
+#define LMP_COMPID_TENOVIS              43
+#define LMP_COMPID_MACRONIX             44
+#define LMP_COMPID_GCT_SEMI             45
+#define LMP_COMPID_NORWOOD_SYSTEMS      46
+#define LMP_COMPID_MEWTEL_TECH          47
+#define LMP_COMPID_STM                  48
+#define LMP_COMPID_SYNOPSYS             49
+#define LMP_COMPID_RED_M_LTD            50
+#define LMP_COMPID_COMMIL_LTD           51
+#define LMP_COMPID_CATC                 52
+#define LMP_COMPID_ECLIPSE              53
+#define LMP_COMPID_RENESAS_TECH         54
+#define LMP_COMPID_MOBILIAN_CORP        55
+#define LMP_COMPID_TERAX                56
+#define LMP_COMPID_ISSC                 57
+#define LMP_COMPID_MATSUSHITA           58
+#define LMP_COMPID_GENNUM_CORP          59
+#define LMP_COMPID_RESEARCH_IN_MOTION   60
+#define LMP_COMPID_IPEXTREME            61
+#define LMP_COMPID_SYSTEMS_AND_CHIPS    62
+#define LMP_COMPID_BLUETOOTH_SIG        63
+#define LMP_COMPID_SEIKO_EPSON_CORP     64
+#define LMP_COMPID_ISS_TAIWAN           65
+#define LMP_COMPID_CONWISE_TECHNOLOGIES 66
+#define LMP_COMPID_PARROT_SA            67
+#define LMP_COMPID_SOCKET_COMM          68
+#define LMP_COMPID_ALTHEROS             69
+#define LMP_COMPID_MEDIATEK             70
+#define LMP_COMPID_BLUEGIGA             71
+#define LMP_COMPID_MARVELL              72
+#define LMP_COMPID_3DSP_CORP            73
+#define LMP_COMPID_ACCEL_SEMICONDUCTOR  74
+#define LMP_COMPID_CONTINENTAL_AUTO     75
+#define LMP_COMPID_APPLE                76
+#define LMP_COMPID_STACCATO             77
+#define LMP_COMPID_AVAGO_TECHNOLOGIES   78
+#define LMP_COMPID_APT_LTD              79
+#define LMP_COMPID_SIRF_TECHNOLOGY      80
+#define LMP_COMPID_TZERO_TECHNOLOGY     81
+#define LMP_COMPID_J_AND_M_CORP         82
+#define LMP_COMPID_FREE_2_MOVE          83
+#define LMP_COMPID_3DIJOY_CORP          84
+#define LMP_COMPID_PLANTRONICS          85
+#define LMP_COMPID_SONY_ERICSSON_MOBILE 86
+#define LMP_COMPID_HARMON_INTL_IND      87
+#define LMP_COMPID_VIZIO                88
+#define LMP_COMPID_NORDIC SEMI          89
+#define LMP_COMPID_EM MICRO             90
+#define LMP_COMPID_RALINK TECH          91
+#define LMP_COMPID_BELKIN INC           92
+#define LMP_COMPID_REALTEK SEMI         93
+#define LMP_COMPID_STONESTREET ONE      94
+#define LMP_COMPID_WICENTRIC            95
+#define LMP_COMPID_RIVIERAWAVES         96
+#define LMP_COMPID_RDA MICRO            97
+#define LMP_COMPID_GIBSON GUITARS       98
+#define LMP_COMPID_MICOMMAND INC        99
+#define LMP_COMPID_BAND XI              100
+#define LMP_COMPID_HP COMPANY           101
+#define LMP_COMPID_9SOLUTIONS OY        102
+#define LMP_COMPID_GN NETCOM            103
+#define LMP_COMPID_GENERAL MOTORS       104
+#define LMP_COMPID_AD ENGINEERING       105
+#define LMP_COMPID_MINDTREE LTD         106
+#define LMP_COMPID_POLAR ELECTRO        107
+#define LMP_COMPID_BEAUTIFUL ENTERPRISE 108
+#define LMP_COMPID_BRIARTEK             109
+#define LMP_COMPID_SUMMIT DATA COMM     110
+#define LMP_COMPID_SOUND ID             111
+#define LMP_COMPID_MONSTER LLC          112
+#define LMP_COMPID_CONNECTBLU           113
+#define LMP_COMPID_MAX_ID               114 /* this is a place holder */
+#define LMP_COMPID_INTERNAL             65535
+
+#define MAX_LMP_COMPID                  (LMP_COMPID_MAX_ID)
+/*
+** Define the packet types in the packet header, and a couple extra
+*/
+#define PKT_TYPE_NULL   0x00
+#define PKT_TYPE_POLL   0x01
+#define PKT_TYPE_FHS    0x02
+#define PKT_TYPE_DM1    0x03
+
+#define PKT_TYPE_DH1    0x04
+#define PKT_TYPE_HV1    0x05
+#define PKT_TYPE_HV2    0x06
+#define PKT_TYPE_HV3    0x07
+#define PKT_TYPE_DV     0x08
+#define PKT_TYPE_AUX1   0x09
+
+#define PKT_TYPE_DM3    0x0a
+#define PKT_TYPE_DH3    0x0b
+
+#define PKT_TYPE_DM5    0x0e
+#define PKT_TYPE_DH5    0x0f
+
+
+#define PKT_TYPE_ID     0x10        /* Internally used packet types */
+#define PKT_TYPE_BAD    0x11
+#define PKT_TYPE_NONE   0x12
+
+/*
+** Define packet size
+*/
+#define HCI_DM1_PACKET_SIZE         17
+#define HCI_DH1_PACKET_SIZE         27
+#define HCI_DM3_PACKET_SIZE         121
+#define HCI_DH3_PACKET_SIZE         183
+#define HCI_DM5_PACKET_SIZE         224
+#define HCI_DH5_PACKET_SIZE         339
+#define HCI_AUX1_PACKET_SIZE        29
+#define HCI_HV1_PACKET_SIZE         10
+#define HCI_HV2_PACKET_SIZE         20
+#define HCI_HV3_PACKET_SIZE         30
+#define HCI_DV_PACKET_SIZE          9
+#define HCI_EDR2_DH1_PACKET_SIZE    54
+#define HCI_EDR2_DH3_PACKET_SIZE    367
+#define HCI_EDR2_DH5_PACKET_SIZE    679
+#define HCI_EDR3_DH1_PACKET_SIZE    83
+#define HCI_EDR3_DH3_PACKET_SIZE    552
+#define HCI_EDR3_DH5_PACKET_SIZE    1021
+
+/*
+**   Features encoding - page 0
+*/
+#define HCI_NUM_FEATURE_BYTES           8
+#define HCI_FEATURES_KNOWN(x) ((x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | x[6] | x[7]) != 0)
+
+#define HCI_FEATURE_3_SLOT_PACKETS_MASK 0x01
+#define HCI_FEATURE_3_SLOT_PACKETS_OFF  0
+#define HCI_3_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_PACKETS_OFF] & HCI_FEATURE_3_SLOT_PACKETS_MASK)
+
+#define HCI_FEATURE_5_SLOT_PACKETS_MASK 0x02
+#define HCI_FEATURE_5_SLOT_PACKETS_OFF  0
+#define HCI_5_SLOT_PACKETS_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_PACKETS_OFF] & HCI_FEATURE_5_SLOT_PACKETS_MASK)
+
+#define HCI_FEATURE_ENCRYPTION_MASK     0x04
+#define HCI_FEATURE_ENCRYPTION_OFF      0
+#define HCI_ENCRYPTION_SUPPORTED(x)     ((x)[HCI_FEATURE_ENCRYPTION_OFF] & HCI_FEATURE_ENCRYPTION_MASK)
+
+#define HCI_FEATURE_SLOT_OFFSET_MASK    0x08
+#define HCI_FEATURE_SLOT_OFFSET_OFF     0
+#define HCI_SLOT_OFFSET_SUPPORTED(x)    ((x)[HCI_FEATURE_SLOT_OFFSET_OFF] & HCI_FEATURE_SLOT_OFFSET_MASK)
+
+#define HCI_FEATURE_TIMING_ACC_MASK     0x10
+#define HCI_FEATURE_TIMING_ACC_OFF      0
+#define HCI_TIMING_ACC_SUPPORTED(x)     ((x)[HCI_FEATURE_TIMING_ACC_OFF] & HCI_FEATURE_TIMING_ACC_MASK)
+
+#define HCI_FEATURE_SWITCH_MASK         0x20
+#define HCI_FEATURE_SWITCH_OFF          0
+#define HCI_SWITCH_SUPPORTED(x)         ((x)[HCI_FEATURE_SWITCH_OFF] & HCI_FEATURE_SWITCH_MASK)
+
+#define HCI_FEATURE_HOLD_MODE_MASK      0x40
+#define HCI_FEATURE_HOLD_MODE_OFF       0
+#define HCI_HOLD_MODE_SUPPORTED(x)      ((x)[HCI_FEATURE_HOLD_MODE_OFF] & HCI_FEATURE_HOLD_MODE_MASK)
+
+#define HCI_FEATURE_SNIFF_MODE_MASK     0x80
+#define HCI_FEATURE_SNIFF_MODE_OFF      0
+#define HCI_SNIFF_MODE_SUPPORTED(x)      ((x)[HCI_FEATURE_SNIFF_MODE_OFF] & HCI_FEATURE_SNIFF_MODE_MASK)
+
+#define HCI_FEATURE_PARK_MODE_MASK      0x01
+#define HCI_FEATURE_PARK_MODE_OFF       1
+#define HCI_PARK_MODE_SUPPORTED(x)      ((x)[HCI_FEATURE_PARK_MODE_OFF] & HCI_FEATURE_PARK_MODE_MASK)
+
+#define HCI_FEATURE_RSSI_MASK           0x02
+#define HCI_FEATURE_RSSI_OFF            1
+#define HCI_RSSI_SUPPORTED(x)           ((x)[HCI_FEATURE_RSSI_OFF] & HCI_FEATURE_RSSI_MASK)
+
+#define HCI_FEATURE_CQM_DATA_RATE_MASK  0x04
+#define HCI_FEATURE_CQM_DATA_RATE_OFF   1
+#define HCI_CQM_DATA_RATE_SUPPORTED(x)  ((x)[HCI_FEATURE_CQM_DATA_RATE_OFF] & HCI_FEATURE_CQM_DATA_RATE_MASK)
+
+#define HCI_FEATURE_SCO_LINK_MASK       0x08
+#define HCI_FEATURE_SCO_LINK_OFF        1
+#define HCI_SCO_LINK_SUPPORTED(x)       ((x)[HCI_FEATURE_SCO_LINK_OFF] & HCI_FEATURE_SCO_LINK_MASK)
+
+#define HCI_FEATURE_HV2_PACKETS_MASK    0x10
+#define HCI_FEATURE_HV2_PACKETS_OFF     1
+#define HCI_HV2_PACKETS_SUPPORTED(x)    ((x)[HCI_FEATURE_HV2_PACKETS_OFF] & HCI_FEATURE_HV2_PACKETS_MASK)
+
+#define HCI_FEATURE_HV3_PACKETS_MASK    0x20
+#define HCI_FEATURE_HV3_PACKETS_OFF     1
+#define HCI_HV3_PACKETS_SUPPORTED(x)    ((x)[HCI_FEATURE_HV3_PACKETS_OFF] & HCI_FEATURE_HV3_PACKETS_MASK)
+
+#define HCI_FEATURE_U_LAW_MASK          0x40
+#define HCI_FEATURE_U_LAW_OFF           1
+#define HCI_LMP_U_LAW_SUPPORTED(x)      ((x)[HCI_FEATURE_U_LAW_OFF] & HCI_FEATURE_U_LAW_MASK)
+
+#define HCI_FEATURE_A_LAW_MASK          0x80
+#define HCI_FEATURE_A_LAW_OFF           1
+#define HCI_LMP_A_LAW_SUPPORTED(x)      ((x)[HCI_FEATURE_A_LAW_OFF] & HCI_FEATURE_A_LAW_MASK)
+
+#define HCI_FEATURE_CVSD_MASK           0x01
+#define HCI_FEATURE_CVSD_OFF            2
+#define HCI_LMP_CVSD_SUPPORTED(x)       ((x)[HCI_FEATURE_CVSD_OFF] & HCI_FEATURE_CVSD_MASK)
+
+#define HCI_FEATURE_PAGING_SCHEME_MASK  0x02
+#define HCI_FEATURE_PAGING_SCHEME_OFF   2
+#define HCI_PAGING_SCHEME_SUPPORTED(x) ((x)[HCI_FEATURE_PAGING_SCHEME_OFF] & HCI_FEATURE_PAGING_SCHEME_MASK)
+
+#define HCI_FEATURE_POWER_CTRL_MASK     0x04
+#define HCI_FEATURE_POWER_CTRL_OFF      2
+#define HCI_POWER_CTRL_SUPPORTED(x)     ((x)[HCI_FEATURE_POWER_CTRL_OFF] & HCI_FEATURE_POWER_CTRL_MASK)
+
+#define HCI_FEATURE_TRANSPNT_MASK       0x08
+#define HCI_FEATURE_TRANSPNT_OFF        2
+#define HCI_LMP_TRANSPNT_SUPPORTED(x)   ((x)[HCI_FEATURE_TRANSPNT_OFF] & HCI_FEATURE_TRANSPNT_MASK)
+
+#define HCI_FEATURE_FLOW_CTRL_LAG_MASK  0x70
+#define HCI_FEATURE_FLOW_CTRL_LAG_OFF   2
+#define HCI_FLOW_CTRL_LAG_VALUE(x)      (((x)[HCI_FEATURE_FLOW_CTRL_LAG_OFF] & HCI_FEATURE_FLOW_CTRL_LAG_MASK) >> 4)
+
+#define HCI_FEATURE_BROADCAST_ENC_MASK  0x80
+#define HCI_FEATURE_BROADCAST_ENC_OFF   2
+#define HCI_LMP_BCAST_ENC_SUPPORTED(x)  ((x)[HCI_FEATURE_BROADCAST_ENC_OFF] & HCI_FEATURE_BROADCAST_ENC_MASK)
+
+#define HCI_FEATURE_SCATTER_MODE_MASK   0x01
+#define HCI_FEATURE_SCATTER_MODE_OFF    3
+#define HCI_LMP_SCATTER_MODE_SUPPORTED(x) ((x)[HCI_FEATURE_SCATTER_MODE_OFF] & HCI_FEATURE_SCATTER_MODE_MASK)
+
+#define HCI_FEATURE_EDR_ACL_2MPS_MASK   0x02
+#define HCI_FEATURE_EDR_ACL_2MPS_OFF    3
+#define HCI_EDR_ACL_2MPS_SUPPORTED(x)   ((x)[HCI_FEATURE_EDR_ACL_2MPS_OFF] & HCI_FEATURE_EDR_ACL_2MPS_MASK)
+
+#define HCI_FEATURE_EDR_ACL_3MPS_MASK   0x04
+#define HCI_FEATURE_EDR_ACL_3MPS_OFF    3
+#define HCI_EDR_ACL_3MPS_SUPPORTED(x)   ((x)[HCI_FEATURE_EDR_ACL_3MPS_OFF] & HCI_FEATURE_EDR_ACL_3MPS_MASK)
+
+#define HCI_FEATURE_ENHANCED_INQ_MASK   0x08
+#define HCI_FEATURE_ENHANCED_INQ_OFF    3
+#define HCI_ENHANCED_INQ_SUPPORTED(x)   ((x)[HCI_FEATURE_ENHANCED_INQ_OFF] & HCI_FEATURE_ENHANCED_INQ_MASK)
+
+#define HCI_FEATURE_INTERLACED_INQ_SCAN_MASK   0x10
+#define HCI_FEATURE_INTERLACED_INQ_SCAN_OFF    3
+#define HCI_LMP_INTERLACED_INQ_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_INQ_SCAN_OFF] & HCI_FEATURE_INTERLACED_INQ_SCAN_MASK)
+
+#define HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK  0x20
+#define HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF   3
+#define HCI_LMP_INTERLACED_PAGE_SCAN_SUPPORTED(x) ((x)[HCI_FEATURE_INTERLACED_PAGE_SCAN_OFF] & HCI_FEATURE_INTERLACED_PAGE_SCAN_MASK)
+
+#define HCI_FEATURE_INQ_RSSI_MASK       0x40
+#define HCI_FEATURE_INQ_RSSI_OFF        3
+#define HCI_LMP_INQ_RSSI_SUPPORTED(x)   ((x)[HCI_FEATURE_INQ_RSSI_OFF] & HCI_FEATURE_INQ_RSSI_MASK)
+
+#define HCI_FEATURE_ESCO_EV3_MASK       0x80
+#define HCI_FEATURE_ESCO_EV3_OFF        3
+#define HCI_ESCO_EV3_SUPPORTED(x)       ((x)[HCI_FEATURE_ESCO_EV3_OFF] & HCI_FEATURE_ESCO_EV3_MASK)
+
+#define HCI_FEATURE_ESCO_EV4_MASK       0x01
+#define HCI_FEATURE_ESCO_EV4_OFF        4
+#define HCI_ESCO_EV4_SUPPORTED(x)       ((x)[HCI_FEATURE_ESCO_EV4_OFF] & HCI_FEATURE_ESCO_EV4_MASK)
+
+#define HCI_FEATURE_ESCO_EV5_MASK       0x02
+#define HCI_FEATURE_ESCO_EV5_OFF        4
+#define HCI_ESCO_EV5_SUPPORTED(x)       ((x)[HCI_FEATURE_ESCO_EV5_OFF] & HCI_FEATURE_ESCO_EV5_MASK)
+
+#define HCI_FEATURE_ABSENCE_MASKS_MASK  0x04
+#define HCI_FEATURE_ABSENCE_MASKS_OFF   4
+#define HCI_LMP_ABSENCE_MASKS_SUPPORTED(x) ((x)[HCI_FEATURE_ABSENCE_MASKS_OFF] & HCI_FEATURE_ABSENCE_MASKS_MASK)
+
+#define HCI_FEATURE_AFH_CAP_SLAVE_MASK  0x08
+#define HCI_FEATURE_AFH_CAP_SLAVE_OFF   4
+#define HCI_LMP_AFH_CAP_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_SLAVE_OFF] & HCI_FEATURE_AFH_CAP_SLAVE_MASK)
+
+#define HCI_FEATURE_AFH_CLASS_SLAVE_MASK 0x10
+#define HCI_FEATURE_AFH_CLASS_SLAVE_OFF  4
+#define HCI_LMP_AFH_CLASS_SLAVE_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_SLAVE_OFF] & HCI_FEATURE_AFH_CLASS_SLAVE_MASK)
+
+#define HCI_FEATURE_ALIAS_AUTH_MASK     0x20
+#define HCI_FEATURE_ALIAS_AUTH_OFF      4
+#define HCI_LMP_ALIAS_AUTH_SUPPORTED(x) ((x)[HCI_FEATURE_ALIAS_AUTH_OFF] & HCI_FEATURE_ALIAS_AUTH_MASK)
+
+#define HCI_FEATURE_ANON_MODE_MASK      0x40
+#define HCI_FEATURE_ANON_MODE_OFF       4
+#define HCI_LMP_ANON_MODE_SUPPORTED(x)  ((x)[HCI_FEATURE_ANON_MODE_OFF] & HCI_FEATURE_ANON_MODE_MASK)
+
+#define HCI_FEATURE_3_SLOT_EDR_ACL_MASK 0x80
+#define HCI_FEATURE_3_SLOT_EDR_ACL_OFF  4
+#define HCI_3_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ACL_OFF] & HCI_FEATURE_3_SLOT_EDR_ACL_MASK)
+
+#define HCI_FEATURE_5_SLOT_EDR_ACL_MASK 0x01
+#define HCI_FEATURE_5_SLOT_EDR_ACL_OFF  5
+#define HCI_5_SLOT_EDR_ACL_SUPPORTED(x) ((x)[HCI_FEATURE_5_SLOT_EDR_ACL_OFF] & HCI_FEATURE_5_SLOT_EDR_ACL_MASK)
+
+#define HCI_FEATURE_SNIFF_SUB_RATE_MASK 0x02
+#define HCI_FEATURE_SNIFF_SUB_RATE_OFF  5
+#define HCI_SNIFF_SUB_RATE_SUPPORTED(x) ((x)[HCI_FEATURE_SNIFF_SUB_RATE_OFF] & HCI_FEATURE_SNIFF_SUB_RATE_MASK)
+
+#define HCI_FEATURE_ATOMIC_ENCRYPT_MASK 0x04
+#define HCI_FEATURE_ATOMIC_ENCRYPT_OFF  5
+#define HCI_ATOMIC_ENCRYPT_SUPPORTED(x) ((x)[HCI_FEATURE_ATOMIC_ENCRYPT_OFF] & HCI_FEATURE_ATOMIC_ENCRYPT_MASK)
+
+#define HCI_FEATURE_AFH_CAP_MASTR_MASK  0x08
+#define HCI_FEATURE_AFH_CAP_MASTR_OFF   5
+#define HCI_LMP_AFH_CAP_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CAP_MASTR_OFF] & HCI_FEATURE_AFH_CAP_MASTR_MASK)
+
+#define HCI_FEATURE_AFH_CLASS_MASTR_MASK 0x10
+#define HCI_FEATURE_AFH_CLASS_MASTR_OFF  5
+#define HCI_LMP_AFH_CLASS_MASTR_SUPPORTED(x) ((x)[HCI_FEATURE_AFH_CLASS_MASTR_OFF] & HCI_FEATURE_AFH_CLASS_MASTR_MASK)
+
+#define HCI_FEATURE_EDR_ESCO_2MPS_MASK  0x20
+#define HCI_FEATURE_EDR_ESCO_2MPS_OFF   5
+#define HCI_EDR_ESCO_2MPS_SUPPORTED(x)  ((x)[HCI_FEATURE_EDR_ESCO_2MPS_OFF] & HCI_FEATURE_EDR_ESCO_2MPS_MASK)
+
+#define HCI_FEATURE_EDR_ESCO_3MPS_MASK  0x40
+#define HCI_FEATURE_EDR_ESCO_3MPS_OFF   5
+#define HCI_EDR_ESCO_3MPS_SUPPORTED(x)  ((x)[HCI_FEATURE_EDR_ESCO_3MPS_OFF] & HCI_FEATURE_EDR_ESCO_3MPS_MASK)
+
+#define HCI_FEATURE_3_SLOT_EDR_ESCO_MASK 0x80
+#define HCI_FEATURE_3_SLOT_EDR_ESCO_OFF  5
+#define HCI_3_SLOT_EDR_ESCO_SUPPORTED(x) ((x)[HCI_FEATURE_3_SLOT_EDR_ESCO_OFF] & HCI_FEATURE_3_SLOT_EDR_ESCO_MASK)
+
+#define HCI_FEATURE_EXT_INQ_RSP_MASK    0x01
+#define HCI_FEATURE_EXT_INQ_RSP_OFF     6
+#define HCI_EXT_INQ_RSP_SUPPORTED(x)    ((x)[HCI_FEATURE_EXT_INQ_RSP_OFF] & HCI_FEATURE_EXT_INQ_RSP_MASK)
+
+#define HCI_FEATURE_ANUM_PIN_AWARE_MASK 0x02
+#define HCI_FEATURE_ANUM_PIN_AWARE_OFF  6
+#define HCI_ANUM_PIN_AWARE_SUPPORTED(x) ((x)[HCI_FEATURE_ANUM_PIN_AWARE_OFF] & HCI_FEATURE_ANUM_PIN_AWARE_MASK)
+
+#define HCI_FEATURE_ANUM_PIN_CAP_MASK   0x04
+#define HCI_FEATURE_ANUM_PIN_CAP_OFF    6
+#define HCI_ANUM_PIN_CAP_SUPPORTED(x)   ((x)[HCI_FEATURE_ANUM_PIN_CAP_OFF] & HCI_FEATURE_ANUM_PIN_CAP_MASK)
+
+#define HCI_FEATURE_SIMPLE_PAIRING_MASK 0x08
+#define HCI_FEATURE_SIMPLE_PAIRING_OFF  6
+#define HCI_SIMPLE_PAIRING_SUPPORTED(x) ((x)[HCI_FEATURE_SIMPLE_PAIRING_OFF] & HCI_FEATURE_SIMPLE_PAIRING_MASK)
+
+#define HCI_FEATURE_ENCAP_PDU_MASK      0x10
+#define HCI_FEATURE_ENCAP_PDU_OFF       6
+#define HCI_ENCAP_PDU_SUPPORTED(x)      ((x)[HCI_FEATURE_ENCAP_PDU_OFF] & HCI_FEATURE_ENCAP_PDU_MASK)
+
+#define HCI_FEATURE_ERROR_DATA_MASK     0x20
+#define HCI_FEATURE_ERROR_DATA_OFF      6
+#define HCI_ERROR_DATA_SUPPORTED(x)     ((x)[HCI_FEATURE_ERROR_DATA_OFF] & HCI_FEATURE_ERROR_DATA_MASK)
+
+#define HCI_FEATURE_NON_FLUSHABLE_PB_MASK      0x40
+#define HCI_FEATURE_NON_FLUSHABLE_PB_OFF       6
+#define HCI_NON_FLUSHABLE_PB_SUPPORTED(x)      ((x)[HCI_FEATURE_NON_FLUSHABLE_PB_OFF] & HCI_FEATURE_NON_FLUSHABLE_PB_MASK)
+
+#define HCI_FEATURE_LINK_SUP_TO_EVT_MASK 0x01
+#define HCI_FEATURE_LINK_SUP_TO_EVT_OFF  7
+#define HCI_LINK_SUP_TO_EVT_SUPPORTED(x) ((x)[HCI_FEATURE_LINK_SUP_TO_EVT_OFF] & HCI_FEATURE_LINK_SUP_TO_EVT_MASK)
+
+#define HCI_FEATURE_INQ_RESP_TX_MASK     0x02
+#define HCI_FEATURE_INQ_RESP_TX_OFF      7
+#define HCI_INQ_RESP_TX_SUPPORTED(x)     ((x)[HCI_FEATURE_INQ_RESP_TX_OFF] & HCI_FEATURE_INQ_RESP_TX_MASK)
+
+#define HCI_FEATURE_EXTENDED_MASK       0x80
+#define HCI_FEATURE_EXTENDED_OFF        7
+#define HCI_LMP_EXTENDED_SUPPORTED(x)   ((x)[HCI_FEATURE_EXTENDED_OFF] & HCI_FEATURE_EXTENDED_MASK)
+
+/*
+**   Features encoding - page 1
+*/
+#define HCI_EXT_FEATURE_SSP_HOST_MASK 0x01
+#define HCI_EXT_FEATURE_SSP_HOST_OFF  0
+#define HCI_SSP_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SSP_HOST_OFF] & HCI_EXT_FEATURE_SSP_HOST_MASK)
+
+/*
+**   Local Supported Commands encoding
+*/
+#define HCI_NUM_SUPP_COMMANDS_BYTES           64
+
+#define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01
+#define HCI_SUPP_COMMANDS_INQUIRY_OFF  0
+#define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK 0x02
+#define HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF  0
+#define HCI_INQUIRY_CANCEL_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_CANCEL_OFF] & HCI_SUPP_COMMANDS_INQUIRY_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK     0x04
+#define HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF      0
+#define HCI_PERIODIC_INQUIRY_SUPPORTED(x)     ((x)[HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_PERIODIC_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK    0x08
+#define HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF     0
+#define HCI_EXIT_PERIODIC_INQUIRY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_OFF] & HCI_SUPP_COMMANDS_EXIT_PERIODIC_INQUIRY_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_CONN_MASK     0x10
+#define HCI_SUPP_COMMANDS_CREATE_CONN_OFF      0
+#define HCI_CREATE_CONN_SUPPORTED(x)     ((x)[HCI_SUPP_COMMANDS_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CREATE_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_MASK         0x20
+#define HCI_SUPP_COMMANDS_DISCONNECT_OFF          0
+#define HCI_DISCONNECT_SUPPORTED(x)         ((x)[HCI_SUPP_COMMANDS_DISCONNECT_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_MASK)
+
+#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK      0x40
+#define HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF       0
+#define HCI_ADD_SCO_CONN_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_ADD_SCO_CONN_OFF] & HCI_SUPP_COMMANDS_ADD_SCO_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK     0x80
+#define HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF      0
+#define HCI_CANCEL_CREATE_CONN_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_OFF] & HCI_SUPP_COMMANDS_CANCEL_CREATE_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK      0x01
+#define HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF       1
+#define HCI_ACCEPT_CONN_REQUEST_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_ACCEPT_CONN_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK           0x02
+#define HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF            1
+#define HCI_REJECT_CONN_REQUEST_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_OFF] & HCI_SUPP_COMMANDS_REJECT_CONN_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK  0x04
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF   1
+#define HCI_LINK_KEY_REQUEST_REPLY_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK       0x08
+#define HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF        1
+#define HCI_LINK_KEY_REQUEST_NEG_REPLY_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_LINK_KEY_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK    0x10
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF     1
+#define HCI_PIN_CODE_REQUEST_REPLY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK    0x20
+#define HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF     1
+#define HCI_PIN_CODE_REQUEST_NEG_REPLY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_PIN_CODE_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK          0x40
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF           1
+#define HCI_CHANGE_CONN_PKT_TYPE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_PKT_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK          0x80
+#define HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF           1
+#define HCI_AUTH_REQUEST_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_AUTH_REQUEST_OFF] & HCI_SUPP_COMMANDS_AUTH_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK      0x01
+#define HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF       2
+#define HCI_SET_CONN_ENCRYPTION_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_OFF] & HCI_SUPP_COMMANDS_SET_CONN_ENCRYPTION_MASK)
+
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK           0x02
+#define HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF            2
+#define HCI_CHANGE_CONN_LINK_KEY_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_CHANGE_CONN_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK  0x04
+#define HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF   2
+#define HCI_MASTER_LINK_KEY_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_MASTER_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_MASTER_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK       0x08
+#define HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF        2
+#define HCI_REMOTE_NAME_REQUEST_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_REMOTE_NAME_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK    0x10
+#define HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF     2
+#define HCI_CANCEL_REMOTE_NAME_REQUEST_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_OFF] & HCI_SUPP_COMMANDS_CANCEL_REMOTE_NAME_REQUEST_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF     2
+#define HCI_READ_REMOTE_SUPP_FEATURES_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_SUPP_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF           2
+#define HCI_READ_REMOTE_EXT_FEATURES_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_EXT_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF           2
+#define HCI_READ_REMOTE_VER_INFO_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_REMOTE_VER_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK           0x01
+#define HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF            3
+#define HCI_READ_CLOCK_OFFSET_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_OFF] & HCI_SUPP_COMMANDS_READ_CLOCK_OFFSET_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK  0x02
+#define HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF   3
+#define HCI_READ_LMP_HANDLE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_READ_LMP_HANDLE_OFF] & HCI_SUPP_COMMANDS_READ_LMP_HANDLE_MASK)
+
+#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK           0x02
+#define HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF            4
+#define HCI_HOLD_MODE_CMD_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_HOLD_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_HOLD_MODE_CMD_MASK)
+
+#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK  0x04
+#define HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF   4
+#define HCI_SNIFF_MODE_CMD_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_OFF] & HCI_SUPP_COMMANDS_SNIFF_MODE_CMD_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK       0x08
+#define HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF        4
+#define HCI_EXIT_SNIFF_MODE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_OFF] & HCI_SUPP_COMMANDS_EXIT_SNIFF_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_PARK_STATE_MASK    0x10
+#define HCI_SUPP_COMMANDS_PARK_STATE_OFF     4
+#define HCI_PARK_STATE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_PARK_STATE_MASK)
+
+#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK    0x20
+#define HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF     4
+#define HCI_EXIT_PARK_STATE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_EXIT_PARK_STATE_OFF] & HCI_SUPP_COMMANDS_EXIT_PARK_STATE_MASK)
+
+#define HCI_SUPP_COMMANDS_QOS_SETUP_MASK          0x40
+#define HCI_SUPP_COMMANDS_QOS_SETUP_OFF           4
+#define HCI_QOS_SETUP_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_QOS_SETUP_OFF] & HCI_SUPP_COMMANDS_QOS_SETUP_MASK)
+
+#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK          0x80
+#define HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF           4
+#define HCI_ROLE_DISCOVERY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_ROLE_DISCOVERY_OFF] & HCI_SUPP_COMMANDS_ROLE_DISCOVERY_MASK)
+
+#define HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK      0x01
+#define HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF       5
+#define HCI_SWITCH_ROLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SWITCH_ROLE_OFF] & HCI_SUPP_COMMANDS_SWITCH_ROLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK           0x02
+#define HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF            5
+#define HCI_READ_LINK_POLICY_SET_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK  0x04
+#define HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF   5
+#define HCI_WRITE_LINK_POLICY_SET_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF        5
+#define HCI_READ_DEF_LINK_POLICY_SET_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_READ_DEF_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK    0x10
+#define HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF     5
+#define HCI_WRITE_DEF_LINK_POLICY_SET_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_OFF] & HCI_SUPP_COMMANDS_WRITE_DEF_LINK_POLICY_SET_MASK)
+
+#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK    0x20
+#define HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF     5
+#define HCI_FLOW_SPECIFICATION_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_OFF] & HCI_SUPP_COMMANDS_FLOW_SPECIFICATION_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK          0x40
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF           5
+#define HCI_SET_EVENT_MASK_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_MASK)
+
+#define HCI_SUPP_COMMANDS_RESET_MASK          0x80
+#define HCI_SUPP_COMMANDS_RESET_OFF           5
+#define HCI_RESET_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_RESET_OFF] & HCI_SUPP_COMMANDS_RESET_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK      0x01
+#define HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF       6
+#define HCI_SET_EVENT_FILTER_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_SET_EVENT_FILTER_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_FILTER_MASK)
+
+#define HCI_SUPP_COMMANDS_FLUSH_MASK           0x02
+#define HCI_SUPP_COMMANDS_FLUSH_OFF            6
+#define HCI_FLUSH_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_FLUSH_OFF] & HCI_SUPP_COMMANDS_FLUSH_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF   6
+#define HCI_READ_PIN_TYPE_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PIN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF        6
+#define HCI_WRITE_PIN_TYPE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PIN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK    0x10
+#define HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF     6
+#define HCI_CREATE_NEW_UNIT_KEY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_OFF] & HCI_SUPP_COMMANDS_CREATE_NEW_UNIT_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF     6
+#define HCI_READ_STORED_LINK_KEY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_READ_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK          0x40
+#define HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF           6
+#define HCI_WRITE_STORED_LINK_KEY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_WRITE_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK          0x80
+#define HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF           6
+#define HCI_DELETE_STORED_LINK_KEY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_OFF] & HCI_SUPP_COMMANDS_DELETE_STORED_LINK_KEY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK      0x01
+#define HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF       7
+#define HCI_WRITE_LOCAL_NAME_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCAL_NAME_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK           0x02
+#define HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF            7
+#define HCI_READ_LOCAL_NAME_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_NAME_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_NAME_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF   7
+#define HCI_READ_CONN_ACCEPT_TOUT_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_CONN_ACCEPT_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF        7
+#define HCI_WRITE_CONN_ACCEPT_TOUT_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_CONN_ACCEPT_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF     7
+#define HCI_READ_PAGE_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF     7
+#define HCI_WRITE_PAGE_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF           7
+#define HCI_READ_SCAN_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SCAN_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF           7
+#define HCI_WRITE_SCAN_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SCAN_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF       8
+#define HCI_READ_PAGE_SCAN_ACTIVITY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF            8
+#define HCI_WRITE_PAGE_SCAN_ACTIVITY_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF   8
+#define HCI_READ_INQURIY_SCAN_ACTIVITY_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_INQURIY_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF        8
+#define HCI_WRITE_INQURIY_SCAN_ACTIVITY_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_INQURIY_SCAN_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF     8
+#define HCI_READ_AUTH_ENABLE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_AUTH_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF     8
+#define HCI_WRITE_AUTH_ENABLE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTH_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF           8
+#define HCI_READ_ENCRYPT_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_ENCRYPT_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF           8
+#define HCI_WRITE_ENCRYPT_ENABLE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_ENCRYPT_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF       9
+#define HCI_READ_CLASS_DEVICE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_READ_CLASS_DEVICE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF            9
+#define HCI_WRITE_CLASS_DEVICE_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_OFF] & HCI_SUPP_COMMANDS_WRITE_CLASS_DEVICE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF   9
+#define HCI_READ_VOICE_SETTING_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_READ_VOICE_SETTING_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF        9
+#define HCI_WRITE_VOICE_SETTING_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_OFF] & HCI_SUPP_COMMANDS_WRITE_VOICE_SETTING_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF     9
+#define HCI_READ_AUTO_FLUSH_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTO_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF     9
+#define HCI_WRITE_AUTO_FLUSH_TOUT_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTO_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF           9
+#define HCI_READ_NUM_BROAD_RETRANS_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_READ_NUM_BROAD_RETRANS_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF           9
+#define HCI_WRITE_NUM_BROAD_RETRANS_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_OFF] & HCI_SUPP_COMMANDS_WRITE_NUM_BROAD_RETRANS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF       10
+#define HCI_READ_HOLD_MODE_ACTIVITY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_READ_HOLD_MODE_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF            10
+#define HCI_WRITE_HOLD_MODE_ACTIVITY_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_OFF] & HCI_SUPP_COMMANDS_WRITE_HOLD_MODE_ACTIVITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF   10
+#define HCI_READ_TRANS_PWR_LEVEL_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANS_PWR_LEVEL_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF        10
+#define HCI_READ_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_READ_SYNCH_FLOW_CTRL_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK    0x10
+#define HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF     10
+#define HCI_WRITE_SYNCH_FLOW_CTRL_ENABLE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNCH_FLOW_CTRL_ENABLE_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK    0x20
+#define HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF     10
+#define HCI_SET_HOST_CTRLR_TO_HOST_FC_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_OFF] & HCI_SUPP_COMMANDS_SET_HOST_CTRLR_TO_HOST_FC_MASK)
+
+#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK          0x40
+#define HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF           10
+#define HCI_HOST_BUFFER_SIZE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_HOST_BUFFER_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK          0x80
+#define HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF           10
+#define HCI_HOST_NUM_COMPLETED_PKTS_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_OFF] & HCI_SUPP_COMMANDS_HOST_NUM_COMPLETED_PKTS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF       11
+#define HCI_READ_LINK_SUP_TOUT_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_LINK_SUP_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF            11
+#define HCI_WRITE_LINK_SUP_TOUT_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LINK_SUP_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF   11
+#define HCI_READ_NUM_SUPP_IAC_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_OFF] & HCI_SUPP_COMMANDS_READ_NUM_SUPP_IAC_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF        11
+#define HCI_READ_CURRENT_IAC_LAP_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_READ_CURRENT_IAC_LAP_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK    0x10
+#define HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF     11
+#define HCI_WRITE_CURRENT_IAC_LAP_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_OFF] & HCI_SUPP_COMMANDS_WRITE_CURRENT_IAC_LAP_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF     11
+#define HCI_READ_PAGE_SCAN_PER_MODE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_PER_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK          0x40
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF           11
+#define HCI_WRITE_PAGE_SCAN_PER_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_PER_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF           11
+#define HCI_READ_PAGE_SCAN_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK      0x01
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF       12
+#define HCI_WRITE_PAGE_SCAN_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK           0x02
+#define HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF            12
+#define HCI_SET_AFH_CHNL_CLASS_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_OFF] & HCI_SUPP_COMMANDS_SET_AFH_CHNL_CLASS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF     12
+#define HCI_READ_INQUIRY_SCAN_TYPE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK    0x20
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF     12
+#define HCI_WRITE_INQUIRY_SCAN_TYPE_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF           12
+#define HCI_READ_INQUIRY_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK          0x80
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF           12
+#define HCI_WRITE_INQUIRY_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF       13
+#define HCI_READ_PAGE_SCAN_TYPE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_READ_PAGE_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF            13
+#define HCI_WRITE_PAGE_SCAN_TYPE_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_OFF] & HCI_SUPP_COMMANDS_WRITE_PAGE_SCAN_TYPE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF   13
+#define HCI_READ_AFH_CHNL_ASSESS_MODE_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CHNL_ASSESS_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK       0x08
+#define HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF        13
+#define HCI_WRITE_AFH_CHNL_ASSESS_MODE_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_AFH_CHNL_ASSESS_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK       0x08
+#define HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF        14
+#define HCI_READ_LOCAL_VER_INFO_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_VER_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK       0x10
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF        14
+#define HCI_READ_LOCAL_SUP_CMDS_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUP_CMDS_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF     14
+#define HCI_READ_LOCAL_SUPP_FEATURES_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_SUPP_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF           14
+#define HCI_READ_LOCAL_EXT_FEATURES_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_EXT_FEATURES_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF           14
+#define HCI_READ_BUFFER_SIZE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_BUFFER_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF       15
+#define HCI_READ_COUNTRY_CODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_OFF] & HCI_SUPP_COMMANDS_READ_COUNTRY_CODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK           0x02
+#define HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF            15
+#define HCI_READ_BD_ADDR_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_READ_BD_ADDR_OFF] & HCI_SUPP_COMMANDS_READ_BD_ADDR_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK  0x04
+#define HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF   15
+#define HCI_READ_FAIL_CONTACT_CNTR_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_READ_FAIL_CONTACT_CNTR_MASK)
+
+#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK       0x08
+#define HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF        15
+#define HCI_RESET_FAIL_CONTACT_CNTR_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_OFF] & HCI_SUPP_COMMANDS_RESET_FAIL_CONTACT_CNTR_MASK)
+
+#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK    0x10
+#define HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF     15
+#define HCI_GET_LINK_QUALITY_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_GET_LINK_QUALITY_OFF] & HCI_SUPP_COMMANDS_GET_LINK_QUALITY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_RSSI_MASK    0x20
+#define HCI_SUPP_COMMANDS_READ_RSSI_OFF     15
+#define HCI_READ_RSSI_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_READ_RSSI_OFF] & HCI_SUPP_COMMANDS_READ_RSSI_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK          0x40
+#define HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF           15
+#define HCI_READ_AFH_CH_MAP_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_OFF] & HCI_SUPP_COMMANDS_READ_AFH_CH_MAP_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK          0x80
+#define HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF           15
+#define HCI_READ_BD_CLOCK_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_BD_CLOCK_OFF] & HCI_SUPP_COMMANDS_READ_BD_CLOCK_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK      0x01
+#define HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF       16
+#define HCI_READ_LOOPBACK_MODE_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_READ_LOOPBACK_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK           0x02
+#define HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF            16
+#define HCI_WRITE_LOOPBACK_MODE_SUPPORTED(x)           ((x)[HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_LOOPBACK_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK  0x04
+#define HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF   16
+#define HCI_ENABLE_DEV_UNDER_TEST_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_OFF] & HCI_SUPP_COMMANDS_ENABLE_DEV_UNDER_TEST_MASK)
+
+#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK       0x08
+#define HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF        16
+#define HCI_SETUP_SYNCH_CONN_SUPPORTED(x)       ((x)[HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_SETUP_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK    0x10
+#define HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF     16
+#define HCI_ACCEPT_SYNCH_CONN_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_ACCEPT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK    0x20
+#define HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF     16
+#define HCI_REJECT_SYNCH_CONN_SUPPORTED(x)    ((x)[HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_OFF] & HCI_SUPP_COMMANDS_REJECT_SYNCH_CONN_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF    17
+#define HCI_READ_EXT_INQUIRY_RESP_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_READ_EXT_INQUIRY_RESP_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK  0x02
+#define HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF   17
+#define HCI_WRITE_EXT_INQUIRY_RESP_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_OFF] & HCI_SUPP_COMMANDS_WRITE_EXT_INQUIRY_RESP_MASK)
+
+#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK   0x04
+#define HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF    17
+#define HCI_REFRESH_ENCRYPTION_KEY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_OFF] & HCI_SUPP_COMMANDS_REFRESH_ENCRYPTION_KEY_MASK)
+
+/* Octet 17, bit 3 is reserved */
+
+#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK       0x10
+#define HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF        17
+#define HCI_SNIFF_SUB_RATE_CMD_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_OFF] & HCI_SUPP_COMMANDS_SNIFF_SUB_RATE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK   0x20
+#define HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF    17
+#define HCI_READ_SIMPLE_PAIRING_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_READ_SIMPLE_PAIRING_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK   0x40
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF    17
+#define HCI_WRITE_SIMPLE_PAIRING_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK   0x80
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF    17
+#define HCI_READ_LOCAL_OOB_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF    18
+#define HCI_READ_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_READ_INQUIRY_RESPONSE_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK   0x02
+#define HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF    18
+#define HCI_WRITE_INQUIRY_RESPONSE_TX_POWER_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_OFF] & HCI_SUPP_COMMANDS_WRITE_INQUIRY_RESPONSE_TX_POWER_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK   0x04
+#define HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF    18
+#define HCI_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_READ_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK   0x08
+#define HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF    18
+#define HCI_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_OFF] & HCI_SUPP_COMMANDS_WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING_MASK)
+
+#define HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_MASK   0x80
+#define HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_OFF    18
+#define HCI_IO_CAPABILITY_RESPONSE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_OFF] & HCI_SUPP_COMMANDS_IO_CAPABILITY_RESPONSE_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK   0x01
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF    19
+#define HCI_USER_CONFIRMATION_REQUEST_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK   0x02
+#define HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF    19
+#define HCI_USER_CONFIRMATION_REQUEST_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_CONFIRMATION_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK   0x04
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF    19
+#define HCI_USER_PASSKEY_REQUEST_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK   0x08
+#define HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF    19
+#define HCI_USER_PASSKEY_REQUEST_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_USER_PASSKEY_REQUEST_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK   0x10
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF    19
+#define HCI_REMOTE_OOB_DATA_REQUEST_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK       0x20
+#define HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF        19
+#define HCI_WRITE_SIMPLE_PAIRING_DBG_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SIMPLE_PAIRING_DBG_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK   0x40
+#define HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF    19
+#define HCI_ENHANCED_FLUSH_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ENHANCED_FLUSH_OFF] & HCI_SUPP_COMMANDS_ENHANCED_FLUSH_MASK)
+
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK       0x80
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF        19
+#define HCI_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_DATA_REQUEST_NEG_REPLY_MASK)
+
+/* Supported Commands (Byte 20) */
+#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK       0x04
+#define HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF        20
+#define HCI_SEND_NOTIF_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_OFF] & HCI_SUPP_COMMANDS_SEND_KEYPRESS_NOTIF_MASK)
+
+#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK      0x08
+#define HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF       20
+#define HCI_IO_CAP_REQ_NEG_REPLY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_OFF] & HCI_SUPP_COMMANDS_IO_CAP_REQ_NEG_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK      0x10
+#define HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF       20
+#define HCI_READ_ENCR_KEY_SIZE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_ENCR_KEY_SIZE_MASK)
+
+/* Supported Commands (Byte 21) */
+#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK   0x01
+#define HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF    21
+#define HCI_CREATE_PHYSICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK   0x02
+#define HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF    21
+#define HCI_ACCEPT_PHYSICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK   0x04
+#define HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF    21
+#define HCI_DISCONNECT_PHYSICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_PHYSICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK   0x08
+#define HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF    21
+#define HCI_CREATE_LOGICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_CREATE_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK   0x10
+#define HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF    21
+#define HCI_ACCEPT_LOGICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_ACCEPT_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK   0x20
+#define HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF    21
+#define HCI_DISCONNECT_LOGICAL_LINK_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_OFF] & HCI_SUPP_COMMANDS_DISCONNECT_LOGICAL_LINK_MASK)
+
+#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK   0x40
+#define HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF    21
+#define HCI_LOGICAL_LINK_CANCEL_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_OFF] & HCI_SUPP_COMMANDS_LOGICAL_LINK_CANCEL_MASK)
+
+#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK       0x80
+#define HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF        21
+#define HCI_FLOW_SPEC_MODIFY_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_OFF] & HCI_SUPP_COMMANDS_FLOW_SPEC_MODIFY_MASK)
+
+/* Supported Commands (Byte 22) */
+#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF    22
+#define HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK   0x02
+#define HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF    22
+#define HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK   0x04
+#define HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF    22
+#define HCI_SET_EVENT_MASK_PAGE_2_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_OFF] & HCI_SUPP_COMMANDS_SET_EVENT_MASK_PAGE_2_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK   0x08
+#define HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF    22
+#define HCI_READ_LOCATION_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCATION_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK   0x10
+#define HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF    22
+#define HCI_WRITE_LOCATION_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_OFF] & HCI_SUPP_COMMANDS_WRITE_LOCATION_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK   0x20
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF    22
+#define HCI_READ_LOCAL_AMP_INFO_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_INFO_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK   0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF    22
+#define HCI_READ_LOCAL_AMP_ASSOC_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_AMP_ASSOC_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK   0x80
+#define HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF    22
+#define HCI_WRITE_REMOTE_AMP_ASSOC_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_OFF] & HCI_SUPP_COMMANDS_WRITE_REMOTE_AMP_ASSOC_MASK)
+
+/* Supported Commands (Byte 23) */
+#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF    23
+#define HCI_READ_FLOW_CONTROL_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_READ_FLOW_CONTROL_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK   0x02
+#define HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF    23
+#define HCI_WRITE_FLOW_CONTROL_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_FLOW_CONTROL_MODE_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK   0x04
+#define HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF    23
+#define HCI_READ_DATA_BLOCK_SIZE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_OFF] & HCI_SUPP_COMMANDS_READ_DATA_BLOCK_SIZE_MASK)
+
+#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK   0x20
+#define HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF    23
+#define HCI_ENABLE_AMP_RCVR_REPORTS_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_OFF] & HCI_SUPP_COMMANDS_ENABLE_AMP_RCVR_REPORTS_MASK)
+
+#define HCI_SUPP_COMMANDS_AMP_TEST_END_MASK   0x40
+#define HCI_SUPP_COMMANDS_AMP_TEST_END_OFF    23
+#define HCI_AMP_TEST_END_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_AMP_TEST_END_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_END_MASK)
+
+#define HCI_SUPP_COMMANDS_AMP_TEST_MASK   0x80
+#define HCI_SUPP_COMMANDS_AMP_TEST_OFF    23
+#define HCI_AMP_TEST_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_AMP_TEST_OFF] & HCI_SUPP_COMMANDS_AMP_TEST_MASK)
+
+/* Supported Commands (Byte 24) */
+#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK   0x01
+#define HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF    24
+#define HCI_READ_TRANSMIT_POWER_LEVEL_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_OFF] & HCI_SUPP_COMMANDS_READ_TRANSMIT_POWER_LEVEL_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK   0x04
+#define HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF    24
+#define HCI_READ_BE_FLUSH_TOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_BE_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK   0x08
+#define HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF    24
+#define HCI_WRITE_BE_FLUSH_TOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_BE_FLUSH_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK   0x10
+#define HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF    24
+#define HCI_SHORT_RANGE_MODE_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_OFF] & HCI_SUPP_COMMANDS_SHORT_RANGE_MODE_MASK)
+
+/* LE commands TBD
+** Supported Commands (Byte 24 continued)
+** Supported Commands (Byte 25)
+** Supported Commands (Byte 26)
+** Supported Commands (Byte 27)
+** Supported Commands (Byte 28)
+*/
+
+/*
+Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator
+*/
+#ifdef _WIDCOMM
+
+#define HCI_SET_HCI_TRACE               (0x0001 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_SET_LM_TRACE                (0x0002 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_WRITE_COUNTRY_CODE          (0x0004 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_READ_LM_HISTORY             (0x0005 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_WRITE_BD_ADDR               (0x0006 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DISABLE_ENCRYPTION          (0x0007 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DISABLE_AUTHENTICATION      (0x0008 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_GENERIC_LC_CMD              (0x000A | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_INCR_POWER                  (0x000B | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DECR_POWER                  (0x000C | HCI_GRP_VENDOR_SPECIFIC)
+
+/* Definitions for the local transactions */
+#define LM_DISCONNECT                  (0x00D0 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_AUTHENTICATION_REQUESTED    (0x00D1 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SET_CONN_ENCRYPTION         (0x00D2 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_START_ENCRYPT_KEY_SIZE      (0x00D3 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_START_ENCRYPTION            (0x00D4 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_STOP_ENCRYPTION             (0x00D5 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_CHANGE_CONN_PACKET_TYPE     (0x00D6 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_RMT_NAME_REQUEST            (0x00D7 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_FEATURES           (0x00D8 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_VERSION_INFO       (0x00D9 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_TIMING_INFO        (0x00DA | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_READ_RMT_CLOCK_OFFSET       (0x00DB | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HOLD_MODE                   (0x00DC | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_EXIT_PARK_MODE              (0x00DD | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_SCO_LINK_REQUEST            (0x00E0 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SCO_CHANGE                  (0x00E4 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_SCO_REMOVE                  (0x00E8 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_MAX_SLOTS                   (0x00F1 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_MAX_SLOTS_REQUEST           (0x00F2 | HCI_GRP_VENDOR_SPECIFIC)
+
+#ifdef INCLUDE_OPTIONAL_PAGING_SCHEME
+#define LM_OPTIONAL_PAGE_REQUEST       (0x00F3 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_OPTIONAL_PAGESCAN_REQUEST   (0x00F4 | HCI_GRP_VENDOR_SPECIFIC)
+#endif
+
+#define LM_SETUP_COMPLETE              (0x00FF | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_HIST_SEND_LMP_FRAME         (0x0100 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_RECV_LMP_FRAME         (0x0101 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCIT_ERROR             (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_PER_INQ_TOUT           (0x0103 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_INQ_SCAN_TOUT          (0x0104 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_PAGE_SCAN_TOUT         (0x0105 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_RESET_TOUT             (0x0106 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_MANDAT_PSCAN_TOUT      (0x0107 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_START_TRANS        (0x0108 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_HOST_REPLY         (0x0109 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_TIMEOUT            (0x010A | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_TX_COMP            (0x010B | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_HCID_SUSPENDED     (0x010C | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_ACL_FAILED             (0x010D | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_COMMAND            (0x010E | HCI_GRP_VENDOR_SPECIFIC)
+
+#define LM_HIST_HCI_EVENT              (0x010F | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_UPDATA             (0x0110 | HCI_GRP_VENDOR_SPECIFIC)
+#define LM_HIST_HCI_DNDATA             (0x0111 | HCI_GRP_VENDOR_SPECIFIC)
+
+#define HCI_ENTER_TEST_MODE            (0x0300 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_LMP_TEST_CNTRL             (0x0301 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_CMD_MIN           (0x0300 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_CMD_MAX           (0x03FF | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_DEBUG_LC_COMMAND           HCI_DEBUG_LC_CMD_MAX
+
+#endif
+
+
+/* Broadcom Vendor Specific Event sub-codes */
+#define HCI_BRCM_VSE_SUBCODE_AUTOMATIC_PAIRING_REQUEST              0x01
+#define HCI_BRCM_VSE_SUBCODE_RX_COMPLETE                            0x02
+#define HCI_BRCM_VSE_SUBCODE_LINK_QUALITY_REPORT                    0x03
+#define HCI_BRCM_VSE_SUBCODE_IOP_TEST_RX_1_PACKET_REPORT            0x04
+#define HCI_BRCM_VSE_SUBCODE_IOP_TEST_RX_N_PACKETS_REPORT_SUMMARY   0x05
+#define HCI_BRCM_VSE_SUBCODE_MODULE_XRAM_TEST_REPORT_SUMMARY        0x06
+#define HCI_BRCM_VSE_SUBCODE_CONNECTIONLESS_RX_TEST_STATISTICS      0x07
+#define HCI_BRCM_VSE_SUBCODE_FM_INTERRUPT                           0x08
+#define HCI_BRCM_VSE_SUBCODE_TCA_DEBUG_REPORT                       0x0B
+#define HCI_BRCM_VSE_SUBCODE_RAM_ROM_CLOCK_TEST_STATUS              0x0C
+#define HCI_BRCM_VSE_SUBCODE_DEBUG_OUTPUT_STRING                    0x0D
+#define HCI_BRCM_VSE_SUBCODE_PCM_DATA_DUMP                          0x0E
+#define HCI_BRCM_VSE_SUBCODE_PROTOCOL_MESSAGE_DUMP                  0x0F
+#define HCI_BRCM_VSE_SUBCODE_GPS_DATA                               0x10
+#define HCI_BRCM_VSE_SUBCODE_RESERVED_11                            0x11
+#define HCI_BRCM_VSE_SUBCODE_GPS_SENSOR_EVENT                       0x12
+#define HCI_BRCM_VSE_SUBCODE_GPS_SENSOR_SETUP_EVENT                 0x13
+#define HCI_BRCM_VSE_SUBCODE_MEIF_RX_EVENT                          0x14
+#define HCI_BRCM_VSE_SUBCODE_UNDETECTED_CRC_ERROR_EVENT             0x15
+#define HCI_BRCM_VSE_SUBCODE_BFC_DISCONNECT_EVENT                   0x16
+#define HCI_BRCM_VSE_SUBCODE_CUSTOMER_SPECIFIC_CS_ENERGY_DETECTED_EVENTS 0x17
+#define HCI_BRCM_VSE_SUBCODE_BFC_POLLING_INFO_EVENT                 0x18
+#define HCI_BRCM_VSE_SUBCODE_EEPROM_CHIP_ERASE_BY_MINIDRIVER_STATUS_REPORT 0xCE
+
+/* MIP related Vendor Specific Event */
+#define HCI_BRCM_VSE_SUBCODE_MIP_MODE_CHANGE            0x27
+#define HCI_BRCM_VSE_SUBCODE_MIP_DISCONNECT             0x28
+#define HCI_BRCM_VSE_SUBCODE_MIP_EIR_CMPLT              0x29
+#define HCI_BRCM_VSE_SUBCODE_MIP_ENC_KEY                0x2A
+#define HCI_BRCM_VSE_SUBCODE_MIP_DATA_RECEIVED          0x2E
+
+/* AMP VSE events
+*/
+#define AMP_VSE_CHANSPEC_CHAN_MASK      0x00ff
+
+#define AMP_VSE_CHANSPEC_CTL_SB_MASK    0x0300
+#define AMP_VSE_CHANSPEC_CTL_SB_LOWER   0x0100
+#define AMP_VSE_CHANSPEC_CTL_SB_UPPER   0x0200
+#define AMP_VSE_CHANSPEC_CTL_SB_NONE    0x0300
+
+#define AMP_VSE_CHANSPEC_BW_MASK        0x0C00
+#define AMP_VSE_CHANSPEC_BW_10          0x0400
+#define AMP_VSE_CHANSPEC_BW_20          0x0800
+#define AMP_VSE_CHANSPEC_BW_40          0x0C00
+
+#define AMP_VSE_CHANSPEC_BAND_MASK      0xf000
+#define AMP_VSE_CHANSPEC_BAND_5G        0x1000
+#define AMP_VSE_CHANSPEC_BAND_2G        0x2000
+
+/* PCM2 related */
+#define HCI_BRCM_CUSTOMER_EXT_ARC_LEN   4
+#define LOC_AUDIO_ROUTING_CONTROL       0x88
+#define LOC_ARC_CHANNEL_ID              0xF3
+
+#define ARC_INTERFACE_PCMI2S            0x01
+#define ARC_INTERFACE_FM_I2S            0x02
+#define ARC_INTERFACE_SLB               0x03
+
+#define ARC_MODE_NOT_USED               0x00
+#define ARC_MODE_BT_AUDIO               0x01
+#define ARC_MODE_FMRX                   0x02
+#define ARC_MODE_FMTX                   0x03
+#define ARC_MODE_SHARED_BT_FMRX         0x04
+#define ARC_MODE_SHARED_BT_FMTX         0x05
+
+#define BRCM_PCM2_SETUP_READ_SIZE       0x01
+#define BRCM_PCM2_SETUP_WRITE_SIZE      0x1A
+
+#endif
+
diff --git a/src/include/nfc_target.h b/src/include/nfc_target.h
new file mode 100755
index 0000000..1ec7e57
--- /dev/null
+++ b/src/include/nfc_target.h
@@ -0,0 +1,679 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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 NFC_TARGET_H
+#define NFC_TARGET_H
+
+#include "data_types.h"
+
+#ifdef BUILDCFG
+#include "buildcfg.h"
+#endif
+
+/* Include common GKI definitions used by this platform */
+#include "gki_target.h"
+
+#include "bt_types.h"   /* This must be defined AFTER buildcfg.h */
+#include "dyn_mem.h"    /* defines static and/or dynamic memory for components */
+#ifndef LMP_TEST
+#include "bt_trace.h"
+#endif
+
+
+/* API macros for DLL (needed to export API functions from DLLs) */
+#define NFC_API         EXPORT_API
+#define LLCP_API        EXPORT_API
+
+/******************************************************************************
+**
+** GKI Mail Box and Timer
+**
+******************************************************************************/
+
+/* Mailbox event mask for NFC stack */
+#ifndef NFC_MBOX_EVT_MASK
+#define NFC_MBOX_EVT_MASK           (TASK_MBOX_0_EVT_MASK)
+#endif
+
+/* Mailbox ID for NFC stack */
+#ifndef NFC_MBOX_ID
+#define NFC_MBOX_ID                 (TASK_MBOX_0)
+#endif
+
+/* Mailbox event mask for NFA */
+#ifndef NFA_MBOX_EVT_MASK
+#define NFA_MBOX_EVT_MASK           (TASK_MBOX_2_EVT_MASK)
+#endif
+
+/* Mailbox ID for NFA */
+#ifndef NFA_MBOX_ID
+#define NFA_MBOX_ID                 (TASK_MBOX_2)
+#endif
+
+/* GKI timer id used for protocol timer in NFC stack */
+#ifndef NFC_TIMER_ID
+#define NFC_TIMER_ID                (TIMER_0)
+#endif
+
+/* GKI timer event mask used for protocol timer in NFC stack */
+#ifndef NFC_TIMER_EVT_MASK
+#define NFC_TIMER_EVT_MASK          (TIMER_0_EVT_MASK)
+#endif
+
+/* GKI timer id used for quick timer in NFC stack */
+#ifndef NFC_QUICK_TIMER_ID
+#define NFC_QUICK_TIMER_ID          (TIMER_1)
+#endif
+
+/* GKI timer event mask used for quick timer in NFC stack */
+#ifndef NFC_QUICK_TIMER_EVT_MASK
+#define NFC_QUICK_TIMER_EVT_MASK    (TIMER_1_EVT_MASK)
+#endif
+
+/* GKI timer id used for protocol timer in NFA */
+#ifndef NFA_TIMER_ID
+#define NFA_TIMER_ID                (TIMER_2)
+#endif
+
+/* GKI timer event mask used for protocol timer in NFA */
+#ifndef NFA_TIMER_EVT_MASK
+#define NFA_TIMER_EVT_MASK          (TIMER_2_EVT_MASK)
+#endif
+
+/******************************************************************************
+**
+** GKI Buffer Pools
+**
+******************************************************************************/
+
+/* NCI command/notification/data */
+#ifndef NFC_NCI_POOL_ID
+#define NFC_NCI_POOL_ID             GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_NCI_POOL_BUF_SIZE
+#define NFC_NCI_POOL_BUF_SIZE       GKI_BUF2_SIZE
+#endif
+
+/* Reader/Write commands (NCI data payload) */
+#ifndef NFC_RW_POOL_ID
+#define NFC_RW_POOL_ID             GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_RW_POOL_BUF_SIZE
+#define NFC_RW_POOL_BUF_SIZE       GKI_BUF2_SIZE
+#endif
+
+/* Card Emulation responses (NCI data payload) */
+#ifndef NFC_CE_POOL_ID
+#define NFC_CE_POOL_ID             GKI_POOL_ID_2
+#endif
+
+#ifndef NFC_CE_POOL_BUF_SIZE
+#define NFC_CE_POOL_BUF_SIZE       GKI_BUF2_SIZE
+#endif
+
+
+/******************************************************************************
+**
+** NCI Transport definitions
+**
+******************************************************************************/
+/* offset of the first NCI packet in buffer for outgoing */
+#ifndef NCI_MSG_OFFSET_SIZE
+#define NCI_MSG_OFFSET_SIZE             1
+#endif
+
+/* Restore NFCC baud rate to default on shutdown if NFC_UpdateBaudRate was called */
+#ifndef NFC_RESTORE_BAUD_ON_SHUTDOWN
+#define NFC_RESTORE_BAUD_ON_SHUTDOWN    TRUE
+#endif
+
+/******************************************************************************
+**
+** NCI
+**
+******************************************************************************/
+
+#define NCI_VERSION_0_F             0x0F
+#define NCI_VERSION_1_0             0x10
+
+#ifndef NCI_VERSION
+#define NCI_VERSION                 NCI_VERSION_1_0
+#endif
+
+/* TRUE I2C patch is needed */
+#ifndef NFC_I2C_PATCH_INCLUDED
+#define NFC_I2C_PATCH_INCLUDED          TRUE     /* NFC-Android uses this!!! */
+#endif
+
+/******************************************************************************
+**
+** NFC
+**
+******************************************************************************/
+#ifndef NFC_INCLUDED
+#define NFC_INCLUDED            TRUE
+#endif
+
+/* Define to TRUE to include Broadcom Vendor Specific implementation */
+#ifndef NFC_BRCM_VS_INCLUDED
+#define NFC_BRCM_VS_INCLUDED    TRUE
+#endif
+
+/* Define to TRUE to include not openned Broadcom Vendor Specific implementation */
+#ifndef NFC_BRCM_NOT_OPEN_INCLUDED
+#define NFC_BRCM_NOT_OPEN_INCLUDED  FALSE  //Android requires FALSE
+#endif
+
+/* Define to TRUE if compling for NFC Reader/Writer Only mode */
+#ifndef NFC_RW_ONLY
+#define NFC_RW_ONLY         FALSE
+#endif
+
+/* Define to TRUE to use dynamic memory allocation.
+ * The default is FALSE - to use static memory allocations.
+*/
+#ifndef NFC_DYNAMIC_MEMORY
+#define NFC_DYNAMIC_MEMORY              FALSE
+#endif
+
+/* Timeout for receiving response to NCI command */
+#ifndef NFC_CMD_CMPL_TIMEOUT
+#define NFC_CMD_CMPL_TIMEOUT        2
+#endif
+
+/* Timeout for waiting on data credit/NFC-DEP */
+#ifndef NFC_DEACTIVATE_TIMEOUT
+#define NFC_DEACTIVATE_TIMEOUT      2
+#endif
+
+/* the maximum number of Vendor Specific callback functions allowed to be registered. 1-14 */
+#ifndef NFC_NUM_VS_CBACKS
+#define NFC_NUM_VS_CBACKS       3
+#endif
+
+/* the maximum number of NCI connections allowed. 1-14 */
+#ifndef NCI_MAX_CONN_CBS
+#define NCI_MAX_CONN_CBS        4
+#endif
+
+/* Maximum number of NCI commands that the NFCC accepts without needing to wait for response */
+#ifndef NCI_MAX_CMD_WINDOW
+#define NCI_MAX_CMD_WINDOW      1
+#endif
+
+/* Define to TRUE to include the NFCEE related functionalities */
+#ifndef NFC_NFCEE_INCLUDED
+#define NFC_NFCEE_INCLUDED          TRUE
+#endif
+
+/* the maximum number of NFCEE interface supported */
+#ifndef NFC_MAX_EE_INTERFACE
+#define NFC_MAX_EE_INTERFACE        3
+#endif
+
+/* the maximum number of NFCEE information supported. */
+#ifndef NFC_MAX_EE_INFO
+#define NFC_MAX_EE_INFO        8
+#endif
+
+/* the maximum number of NFCEE TLVs supported */
+#ifndef NFC_MAX_EE_TLVS
+#define NFC_MAX_EE_TLVS        1
+#endif
+
+/* the maximum size of NFCEE TLV list supported */
+#ifndef NFC_MAX_EE_TLV_SIZE
+#define NFC_MAX_EE_TLV_SIZE        150
+#endif
+
+/* Number of times reader/writer should attempt to resend a command on failure */
+#ifndef RW_MAX_RETRIES
+#define RW_MAX_RETRIES              5
+#endif
+
+/* RW NDEF Support */
+#ifndef RW_NDEF_INCLUDED
+#define RW_NDEF_INCLUDED            TRUE
+#endif
+
+/* RW Type 1 Tag timeout for each API call, in ms */
+#ifndef RW_T1T_TOUT_RESP
+#define RW_T1T_TOUT_RESP            100
+#endif
+
+/* CE Type 2 Tag timeout for controller command, in ms */
+#ifndef CE_T2T_TOUT_RESP
+#define CE_T2T_TOUT_RESP            1000
+#endif
+
+/* RW Type 2 Tag timeout for each API call, in ms */
+#ifndef RW_T2T_TOUT_RESP
+#define RW_T2T_TOUT_RESP            100
+#endif
+
+/* RW Type 2 Tag timeout for each API call, in ms */
+#ifndef RW_T2T_SEC_SEL_TOUT_RESP
+#define RW_T2T_SEC_SEL_TOUT_RESP    10
+#endif
+
+/* RW Type 3 Tag timeout for each API call, in ms */
+#ifndef RW_T3T_TOUT_RESP
+#define RW_T3T_TOUT_RESP            100         /* NFC-Android will use 100 instead of 75 for T3t presence-check */
+#endif
+
+/* CE Type 3 Tag maximum response timeout index (for check and update, used in SENSF_RES) */
+#ifndef CE_T3T_MRTI_C
+#define CE_T3T_MRTI_C               0xFF
+#endif
+#ifndef CE_T3T_MRTI_U
+#define CE_T3T_MRTI_U               0xFF
+#endif
+
+/* Default maxblocks for CE_T3T UPDATE/CHECK operations */
+#ifndef CE_T3T_DEFAULT_UPDATE_MAXBLOCKS
+#define CE_T3T_DEFAULT_UPDATE_MAXBLOCKS 3
+#endif
+
+#ifndef CE_T3T_DEFAULT_CHECK_MAXBLOCKS
+#define CE_T3T_DEFAULT_CHECK_MAXBLOCKS  3
+#endif
+
+/* CE Type 4 Tag, Frame Waiting time Integer */
+#ifndef CE_T4T_ISO_DEP_FWI
+#define CE_T4T_ISO_DEP_FWI          7
+#endif
+
+/* RW Type 4 Tag timeout for each API call, in ms */
+#ifndef RW_T4T_TOUT_RESP
+#define RW_T4T_TOUT_RESP            1000
+#endif
+
+/* CE Type 4 Tag timeout for update file, in ms */
+#ifndef CE_T4T_TOUT_UPDATE
+#define CE_T4T_TOUT_UPDATE          1000
+#endif
+
+/* CE Type 4 Tag, mandatory NDEF File ID */
+#ifndef CE_T4T_MANDATORY_NDEF_FILE_ID
+#define CE_T4T_MANDATORY_NDEF_FILE_ID    0x1000
+#endif
+
+/* CE Type 4 Tag, max number of AID supported */
+#ifndef CE_T4T_MAX_REG_AID
+#define CE_T4T_MAX_REG_AID         4
+#endif
+
+/* Sub carrier */
+#ifndef RW_I93_FLAG_SUB_CARRIER
+#define RW_I93_FLAG_SUB_CARRIER     I93_FLAG_SUB_CARRIER_SINGLE
+#endif
+
+/* Data rate for 15693 command/response */
+#ifndef RW_I93_FLAG_DATA_RATE
+#define RW_I93_FLAG_DATA_RATE       I93_FLAG_DATA_RATE_HIGH
+#endif
+
+/* TRUE, to include Card Emulation related test commands */
+#ifndef CE_TEST_INCLUDED
+#define CE_TEST_INCLUDED            FALSE
+#endif
+
+#if (NFC_BRCM_NOT_OPEN_INCLUDED == TRUE)
+/* Power cycle NFCC to move full power mode from CE low power mode */
+#ifndef NFC_LP_POWER_CYCLE_TO_FULL
+#define NFC_LP_POWER_CYCLE_TO_FULL  TRUE
+#endif
+
+/* Parameter for low power mode command    */
+#ifndef NFC_LP_COMMAND_PARAMS
+#define NFC_LP_COMMAND_PARAMS       5
+#endif
+
+/* Primary Threshold for battery monitor   */
+#ifndef NFC_LP_PRIMARY_THRESHOLD
+#define NFC_LP_PRIMARY_THRESHOLD    0
+#endif
+
+/* Secondary Threshold for battery monitor */
+#ifndef NFC_LP_SECONDARY_THRESHOLD
+#define NFC_LP_SECONDARY_THRESHOLD  8
+#endif
+#endif
+
+/* Quick Timer */
+#ifndef QUICK_TIMER_TICKS_PER_SEC
+#define QUICK_TIMER_TICKS_PER_SEC   100       /* 10ms timer */
+#endif
+
+
+/******************************************************************************
+**
+** LLCP
+**
+******************************************************************************/
+
+#ifndef LLCP_TEST_INCLUDED
+#define LLCP_TEST_INCLUDED          FALSE
+#endif
+
+#ifndef LLCP_POOL_ID
+#define LLCP_POOL_ID                GKI_POOL_ID_3
+#endif
+
+#ifndef LLCP_POOL_BUF_SIZE
+#define LLCP_POOL_BUF_SIZE          GKI_BUF3_SIZE
+#endif
+
+/* LLCP Maximum Information Unit (between LLCP_DEFAULT_MIU(128) and LLCP_MAX_MIU (2175)*/
+#ifndef LLCP_MIU
+#define LLCP_MIU                    (LLCP_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - LLCP_PDU_HEADER_SIZE)
+#endif
+
+/* Link Timeout, LTO */
+#ifndef LLCP_LTO_VALUE
+#define LLCP_LTO_VALUE              1000    /* Default is 100ms. It should be sufficiently larger than RWT */
+#endif
+
+/*
+** LTO is max time interval between the last bit received and the first bit sent over the air.
+** Link timeout must be delayed as much as time between the packet sent from LLCP and the last bit transmitted at NFCC.
+**  - 200ms, max OTA transmitting time between the first bit and the last bit at NFCC
+**    Largest MIU(2175bytes) of LLCP must be fragmented and sent on NFC-DEP over the air.
+**    8 * (DEP_REQ/RES+ACK) + DEP_REQ/RES for 2175 MIU at 106kbps bit rate.
+**  - 10ms, processing time
+*/
+#ifndef LLCP_INTERNAL_TX_DELAY
+#define LLCP_INTERNAL_TX_DELAY      210
+#endif
+
+/*
+** LTO is max time interval between the last bit received and the first bit sent over the air.
+** Link timeout must be delayed as much as time between the first bit received at NFCC and the packet received at LLCP.
+**  - 200ms, max OTA transmitting time between the first bit and the last bit at NFCC
+**    LLCP cannot receive data packet until all bit are received and reassembled in NCI.
+**    8 * (DEP_REQ/RES+ACK) + DEP_REQ/RES for 2175 MIU at 106kbps bit rate.
+**  - 10ms, processing time
+*/
+#ifndef LLCP_INTERNAL_RX_DELAY
+#define LLCP_INTERNAL_RX_DELAY      210
+#endif
+
+/* Wait for application layer sending data before sending SYMM */
+#ifndef LLCP_DELAY_RESP_TIME
+#define LLCP_DELAY_RESP_TIME        20      /* in ms */
+#endif
+
+/* LLCP inactivity timeout for initiator */
+#ifndef LLCP_INIT_INACTIVITY_TIMEOUT
+#define LLCP_INIT_INACTIVITY_TIMEOUT            0    /* in ms */
+#endif
+
+/* LLCP inactivity timeout for target */
+#ifndef LLCP_TARGET_INACTIVITY_TIMEOUT
+#define LLCP_TARGET_INACTIVITY_TIMEOUT          0    /* in ms */
+#endif
+
+/* LLCP delay timeout to send the first PDU as initiator */
+#ifndef LLCP_DELAY_TIME_TO_SEND_FIRST_PDU
+#define LLCP_DELAY_TIME_TO_SEND_FIRST_PDU      50    /* in ms */
+#endif
+
+/* Response Waiting Time */
+#ifndef LLCP_WAITING_TIME
+#define LLCP_WAITING_TIME           7       /* its scaled value should be less than LTO */
+#endif
+
+/* Options Parameters */
+#ifndef LLCP_OPT_VALUE
+#define LLCP_OPT_VALUE              LLCP_LSC_3  /* Link Service Class 3 */
+#endif
+
+/* Data link connection timeout */
+#ifndef LLCP_DATA_LINK_CONNECTION_TOUT
+#define LLCP_DATA_LINK_CONNECTION_TOUT      1000
+#endif
+
+/* Max length of service name */
+#ifndef LLCP_MAX_SN_LEN
+#define LLCP_MAX_SN_LEN             255     /* max length of service name */
+#endif
+
+/* Max number of well-known services, at least 2 for LM and SDP and up to 16 */
+#ifndef LLCP_MAX_WKS
+#define LLCP_MAX_WKS                5
+#endif
+
+/* Max number of services advertised by local SDP, up to 16 */
+#ifndef LLCP_MAX_SERVER
+#define LLCP_MAX_SERVER             10
+#endif
+
+/* Max number of services not advertised by local SDP, up to 32 */
+#ifndef LLCP_MAX_CLIENT
+#define LLCP_MAX_CLIENT             20
+#endif
+
+/* Max number of data link connections */
+#ifndef LLCP_MAX_DATA_LINK
+#define LLCP_MAX_DATA_LINK          16
+#endif
+
+/* Max number of outstanding service discovery requests */
+#ifndef LLCP_MAX_SDP_TRANSAC
+#define LLCP_MAX_SDP_TRANSAC        16
+#endif
+
+/* Percentage of LLCP buffer pool for receiving data */
+#ifndef LLCP_RX_BUFF_RATIO
+#define LLCP_RX_BUFF_RATIO                  30
+#endif
+
+/* Rx congestion end threshold as percentage of receiving buffers */
+#ifndef LLCP_RX_CONGEST_END
+#define LLCP_RX_CONGEST_END                 50
+#endif
+
+/* Rx congestion start threshold as percentage of receiving buffers */
+#ifndef LLCP_RX_CONGEST_START
+#define LLCP_RX_CONGEST_START               70
+#endif
+
+/* limitation of rx UI PDU as percentage of receiving buffers */
+#ifndef LLCP_LL_RX_BUFF_LIMIT
+#define LLCP_LL_RX_BUFF_LIMIT               30
+#endif
+
+/* minimum rx congestion threshold (number of rx I PDU in queue) for data link connection */
+#ifndef LLCP_DL_MIN_RX_CONGEST
+#define LLCP_DL_MIN_RX_CONGEST              4
+#endif
+
+/* limitation of tx UI PDU as percentage of transmitting buffers */
+#ifndef LLCP_LL_TX_BUFF_LIMIT
+#define LLCP_LL_TX_BUFF_LIMIT               30
+#endif
+
+/******************************************************************************
+**
+** NFA
+**
+******************************************************************************/
+#ifndef NFA_DYNAMIC_MEMORY
+#define NFA_DYNAMIC_MEMORY          FALSE
+#endif
+
+#ifndef NFA_INCLUDED
+#define NFA_INCLUDED                TRUE
+#endif
+
+#ifndef NFA_P2P_INCLUDED
+#define NFA_P2P_INCLUDED            TRUE
+#endif
+
+/* Timeout for waiting on other host in HCI Network to initialize */
+#ifndef NFA_HCI_NETWK_INIT_TIMEOUT
+#define NFA_HCI_NETWK_INIT_TIMEOUT  400
+#endif
+
+#ifndef NFA_HCI_MAX_HOST_IN_NETWORK
+#define NFA_HCI_MAX_HOST_IN_NETWORK 0x06
+#endif
+
+/* Max number of Application that can be registered to NFA-HCI */
+#ifndef NFA_HCI_MAX_APP_CB
+#define NFA_HCI_MAX_APP_CB          0x05
+#endif
+
+/* Max number of HCI gates that can be created */
+#ifndef NFA_HCI_MAX_GATE_CB
+#define NFA_HCI_MAX_GATE_CB         0x06
+#endif
+
+/* Max number of HCI pipes that can be created for the whole system */
+#ifndef NFA_HCI_MAX_PIPE_CB
+#define NFA_HCI_MAX_PIPE_CB         0x08
+#endif
+
+/* Timeout for waiting for the response to HCP Command packet */
+#ifndef NFA_HCI_CMD_RSP_TIMEOUT
+#define NFA_HCI_CMD_RSP_TIMEOUT    1000
+#endif
+
+/* Default poll duration (may be over-ridden using NFA_SetRfDiscoveryDuration) */
+#ifndef NFA_DM_DISC_DURATION_POLL
+#define NFA_DM_DISC_DURATION_POLL               500  /* Android requires 500 */
+#endif
+
+/* Automatic NDEF detection (when not in exclusive RF mode) */
+#ifndef NFA_DM_AUTO_DETECT_NDEF
+#define NFA_DM_AUTO_DETECT_NDEF      FALSE  /* !!!!! NFC-Android needs FALSE */
+#endif
+
+/* Automatic NDEF read (when not in exclusive RF mode) */
+#ifndef NFA_DM_AUTO_READ_NDEF
+#define NFA_DM_AUTO_READ_NDEF        FALSE  /* !!!!! NFC-Android needs FALSE */
+#endif
+
+/* Automatic NDEF read (when not in exclusive RF mode) */
+#ifndef NFA_DM_AUTO_PRESENCE_CHECK
+#define NFA_DM_AUTO_PRESENCE_CHECK   FALSE  /* Android requires FALSE */
+#endif
+
+/* Time to restart discovery after deactivated */
+#ifndef NFA_DM_DISC_DELAY_DISCOVERY
+#define NFA_DM_DISC_DELAY_DISCOVERY     1000
+#endif
+
+/* Max number of NDEF type handlers that can be registered (including the default handler) */
+#ifndef NFA_NDEF_MAX_HANDLERS
+#define NFA_NDEF_MAX_HANDLERS       8
+#endif
+
+/* Maximum number of listen entries configured/registered with NFA_CeConfigureUiccListenTech, */
+/* NFA_CeRegisterFelicaSystemCodeOnDH, or NFA_CeRegisterT4tAidOnDH                            */
+#ifndef NFA_CE_LISTEN_INFO_MAX
+#define NFA_CE_LISTEN_INFO_MAX        5
+#endif
+
+#ifndef NFA_CHO_INCLUDED
+#define NFA_CHO_INCLUDED            TRUE
+#endif
+
+/* MIU for CHO              */
+#ifndef NFA_CHO_MIU
+#define NFA_CHO_MIU                    499
+#endif
+
+/* Receiving Window for CHO */
+#ifndef NFA_CHO_RW
+#define NFA_CHO_RW                     4
+#endif
+
+/* Max number of alternative carrier information */
+#ifndef NFA_CHO_MAX_AC_INFO
+#define NFA_CHO_MAX_AC_INFO                 2
+#endif
+
+/* Max reference character length, it is up to 255 but it's RECOMMENDED short */
+#ifndef NFA_CHO_MAX_REF_NAME_LEN
+#define NFA_CHO_MAX_REF_NAME_LEN            8
+#endif
+
+/* Max auxiliary data count */
+#ifndef NFA_CHO_MAX_AUX_DATA_COUNT
+#define NFA_CHO_MAX_AUX_DATA_COUNT          2
+#endif
+
+#ifndef NFA_CHO_TEST_INCLUDED
+#define NFA_CHO_TEST_INCLUDED           FALSE
+#endif
+
+#ifndef NFA_SNEP_INCLUDED
+#define NFA_SNEP_INCLUDED               TRUE
+#endif
+
+/* Max acceptable length */
+#ifndef NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE
+#define NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE          500000
+#endif
+
+/* Max number of SNEP server/client and data link connection */
+#ifndef NFA_SNEP_MAX_CONN
+#define NFA_SNEP_MAX_CONN               6
+#endif
+
+/* Max number data link connection of SNEP default server*/
+#ifndef NFA_SNEP_DEFAULT_MAX_CONN
+#define NFA_SNEP_DEFAULT_MAX_CONN       3
+#endif
+
+/* MIU for SNEP              */
+#ifndef NFA_SNEP_MIU
+#define NFA_SNEP_MIU                    1980        /* Modified for NFC-A */
+#endif
+
+/* Receiving Window for SNEP */
+#ifndef NFA_SNEP_RW
+#define NFA_SNEP_RW                     2           /* Modified for NFC-A */
+#endif
+
+/* Max number of NFCEE supported */
+#ifndef NFA_EE_MAX_EE_SUPPORTED
+#define NFA_EE_MAX_EE_SUPPORTED         3
+#endif
+
+/* Maximum number of AID entries per target_handle  */
+#ifndef NFA_EE_MAX_AID_ENTRIES
+#define NFA_EE_MAX_AID_ENTRIES      (10)
+#endif
+
+/* Maximum number of callback functions can be registered through NFA_EeRegister() */
+#ifndef NFA_EE_MAX_CBACKS
+#define NFA_EE_MAX_CBACKS           (3)
+#endif
+
+#ifndef NFA_DTA_INCLUDED
+#define NFA_DTA_INCLUDED            TRUE
+#endif
+
+#endif /* NFC_TARGET_H */
+
+
+
diff --git a/src/include/nfccext.h b/src/include/nfccext.h
new file mode 100644
index 0000000..8f5f006
--- /dev/null
+++ b/src/include/nfccext.h
@@ -0,0 +1,106 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+/****************************************************************************/
+/*  NFCC global definitions                                                 */
+/****************************************************************************/
+
+#ifndef NFCC_EXT_H
+#define NFCC_EXT_H
+
+#include "bt_target.h"
+#include "nci_cmsgs.h"
+#include "nci_defs.h"
+
+extern void    nfcc_init (void);
+extern void * nfcc_find_conn_cb_by_conn_id(UINT8 conn_id);
+extern void     nfcc_proc_nfcee_discover(void);
+extern void     nfcc_proc_nfcee_uicc_vse_test(UINT8 ee_handle, UINT8 mode);
+extern void    lm_process_nfc (BT_HDR *p_msg);
+
+/*
+** Definitions for events sent from NFCC to LMP
+*/
+#define NFCC_EVENT_START_DISCOVER       1    /* forward Start Discover cmd to peer NFCC */
+#define NFCC_EVENT_DISCOVER_RESP        2    /* A response to a Discover cmd       */
+#define NFCC_EVENT_DATA                 3    /* A response to a Discover cmd       */
+#define NFCC_EVENT_DISCOVER_SELECT      4    /* forward Start Discover cmd to peer NFCC */
+#define NFCC_EVENT_DEACTIVATE           5    /* forward deactivate cmd to peer NFCC */
+
+
+#define NFCC_MAX_DISCOVER_PARAMS        7
+
+/* this does not work if more than 329 */
+#define NFCC_MAX_PARAM_TLV_LEN          328
+
+/* Discovery Type Masks - not in spec; for convenience/based on NCI_DISCOVERY_TYPE* */
+#define NCI_DISCOVERY_MASK_POLL_A       0x0001
+#define NCI_DISCOVERY_MASK_POLL_B       0x0002
+#define NCI_DISCOVERY_MASK_POLL_F       0x0004
+#define NCI_DISCOVERY_MASK_LISTEN_A     0x0100
+#define NCI_DISCOVERY_MASK_LISTEN_B     0x0200
+#define NCI_DISCOVERY_MASK_LISTEN_F     0x0400
+#define NCI_DISCOVERY_MASK_MAX          0x070F
+
+typedef UINT16 tNCI_DISCOVERY_MASK;
+
+#define NFCC_NUM_NFCEE      3
+/*
+** Define a buffer that is used for data descriptors from HCID to LC
+*/
+typedef struct
+{
+    BT_HDR                  hdr;        /* Standard BT header               */
+    tNCI_DISCOVERY_MASK     mask;       /* sender is looking for anything in this mask */
+    UINT8                   num_params;
+    tNCI_DISCOVER_PARAMS    params[NFCC_MAX_DISCOVER_PARAMS];
+    UINT8                   param_tlv[NFCC_MAX_PARAM_TLV_LEN];
+    UINT16                  param_tlv_len;
+} tNFCC_START_DISCOVER;
+
+typedef struct
+{
+    BT_HDR                  hdr;        /* Standard BT header               */
+    tNCI_DISCOVERY_MASK     mask;       /* sender is looking for anything in this mask */
+    UINT8                   num_params;
+    tNCI_DISCOVER_PARAMS    params[NFCC_MAX_DISCOVER_PARAMS];
+    UINT8                   param_tlv[NFCC_MAX_PARAM_TLV_LEN];
+    UINT16                  param_tlv_len;
+} tNFCC_DISCOVER_RESP;
+
+typedef struct
+{
+    BT_HDR                  hdr;        /* Standard BT header               */
+    UINT8                   target_handle;
+    UINT8                   protocol;
+} tNFCC_DISCOVER_SELECT;
+
+/********************************************************************************
+**
+** Structures used for NFCC Simulation to communicate with peer NFCC Simulation
+*/
+typedef union
+{
+    BT_HDR                  hdr;
+    tNFCC_START_DISCOVER    start_discover;
+    tNFCC_DISCOVER_RESP     discover_resp;
+    tNFCC_DISCOVER_SELECT   discover_select;
+} tNFCC_TO_PEER;
+
+
+#endif
+
diff --git a/src/include/trace_api.h b/src/include/trace_api.h
new file mode 100644
index 0000000..f55de66
--- /dev/null
+++ b/src/include/trace_api.h
@@ -0,0 +1,107 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Contains API for BTE Test Tool trace related functions.
+ *
+ ******************************************************************************/
+
+
+#ifndef TRACE_API_H
+#define TRACE_API_H
+
+#include "bt_target.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Trace API Function External Declarations */
+BT_API extern void DispAMPFrame (BT_HDR *p_buf, BOOLEAN is_recv, BD_ADDR bd_addr);
+BT_API extern void DispRFCOMMFrame (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispL2CCmd(BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispSdp (BT_HDR *p_msg, BOOLEAN is_rcv, BOOLEAN is_segment);
+BT_API extern void DispSdpFullList (UINT8 *p, UINT16 list_len, BOOLEAN is_rcv);
+BT_API extern void DispTcsMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispHciEvt (BT_HDR *p_buf);
+BT_API extern void DispHciAclData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void DispHciScoData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void DispHciCmd (BT_HDR *p_buf);
+BT_API extern void DispBnep (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispAvdtMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispAvct (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispMca (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispObxMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispLMDiagEvent (BT_HDR *p_buf);
+BT_API extern void DispHidFrame (BT_HDR *p_buf, BOOLEAN is_recv, BOOLEAN is_control);
+BT_API extern void DispRawFrame(UINT8 *p, UINT16 len, BOOLEAN is_rcv);
+BT_API extern void DispSlipPacket(UINT8 *p, UINT16 len, BOOLEAN is_rcv, BOOLEAN oof_flow_ctrl);
+BT_API extern void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+BT_API extern void DispHcp (UINT8 *p, UINT16 len, BOOLEAN is_recv, BOOLEAN is_first_seg);
+BT_API extern void DispNDEFRecord (UINT8 *pRec, INT8 *pDescr);
+BT_API extern void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv);
+BT_API extern void DispSmpMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispAttMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void DispLLCP (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void DispSNEP (UINT8 local_sap, UINT8 remote_sap, UINT8 *p_data, UINT16 length, BOOLEAN is_rx);
+BT_API extern void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx);
+BT_API extern void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx);
+BT_API extern void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond);
+
+BT_API extern void RPC_DispAMPFrame (BT_HDR *p_buf, BOOLEAN is_recv, BD_ADDR bd_addr);
+BT_API extern void RPC_DispRFCOMMFrame (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispL2CCmd(BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispSdp (BT_HDR *p_msg, BOOLEAN is_rcv, BOOLEAN is_segment);
+BT_API extern void RPC_DispSdpFullList (UINT8 *p, UINT16 list_len, BOOLEAN is_rcv);
+BT_API extern void RPC_DispTcsMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispHciEvt (BT_HDR *p_buf);
+BT_API extern void RPC_DispHciAclData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void RPC_DispHciScoData (BT_HDR *p_buf, BOOLEAN is_rcvd);
+BT_API extern void RPC_DispHciCmd (BT_HDR *p_buf);
+BT_API extern void RPC_DispLMDiagEvent (BT_HDR *p_buf);
+BT_API extern void RPC_DispBnep (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispAvdtMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispAvct (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispMca (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispObxMsg (BT_HDR *p_buf, BOOLEAN is_recv);
+BT_API extern void RPC_DispLMDiagEvent (BT_HDR *p_buf);
+BT_API extern void RPC_DispHidFrame (BT_HDR *p_buf, BOOLEAN is_recv, BOOLEAN is_control);
+BT_API extern void RPC_DispSmpMsg (BT_HDR *p_msg, BOOLEAN is_rcv);
+BT_API extern void RPC_DispAttMsg (BT_HDR *p_msg, BOOLEAN is_rcv);
+BT_API extern void RPC_DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+BT_API extern void RPC_DispHcp (UINT8 *p, UINT16 len, BOOLEAN is_recv, BOOLEAN is_first_seg);
+BT_API extern void RPC_DispNDEFRecord (UINT8 *pRec, INT8 *pDescr);
+BT_API extern void RPC_DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv);
+BT_API extern void RPC_DispLLCP (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void RPC_DispSNEP (UINT8 local_sap, UINT8 remote_sap, UINT8 *p_data, UINT16 length, BOOLEAN is_rx);
+BT_API extern void RPC_DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx);
+BT_API extern void RPC_DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx);
+BT_API extern void RPC_DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void RPC_DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+BT_API extern void RPC_DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond);
+
+EXPORT_API extern void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TRACE_API_H */
diff --git a/src/libnfc.conf b/src/libnfc.conf
new file mode 100644
index 0000000..907fac6
--- /dev/null
+++ b/src/libnfc.conf
@@ -0,0 +1,95 @@
+## this file is used by NFC stack (external/libnfc-nci/src)
+## and NFC Service Java Native Interface (packages/apps/Nfc/nci/jni)
+
+###############################################################################
+# Application options
+APPL_TRACE_LEVEL=0xFF
+PROTOCOL_TRACE_LEVEL=0xFFFFFFFF
+
+###############################################################################
+# File used for NFA storage
+NFA_STORAGE="/data/nfc"
+
+###############################################################################
+# Force tag polling for the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B |
+#            NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_ISO15693 |
+#            NFA_TECHNOLOGY_MASK_B_PRIME | NFA_TECHNOLOGY_MASK_A_ACTIVE |
+#            NFA_TECHNOLOGY_MASK_F_ACTIVE.
+#
+# Notable bits:
+#   NFA_TECHNOLOGY_MASK_KOVIO       0x20
+#   NFA_TECHNOLOGY_MASK_A_ACTIVE    0x40
+#   NFA_TECHNOLOGY_MASK_F_ACTIVE    0x80
+#POLLING_TECH_MASK=0xDF
+
+###############################################################################
+# Force P2P to only listen for the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F |
+#            NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE
+P2P_LISTEN_TECH_MASK=0x45
+
+###############################################################################
+# This setting allows you to disable registering the T4t Virtual SE that causes
+# the NFCC to send PPSE requests to the DH.
+# The default setting is enabled (i.e. T4t Virtual SE is registered).
+#REGISTER_VIRTUAL_SE=1
+
+###############################################################################
+# Use Nexus S NXP RC work to allow our stack/firmware to work with a retail
+# Nexus S that causes IOP issues.  Note, this will not pass conformance and
+# should be removed for production.
+USE_NXP_P2P_RC_WORKAROUND=1
+
+###############################################################################
+# When screen is turned off, specify the desired power state of the controller.
+# 0: power-off-sleep state; DEFAULT
+# 1: full-power state
+# 2: screen-off card-emulation (CE4/CE3/CE1 modes are used)
+#SCREEN_OFF_POWER_STATE=0
+
+###############################################################################
+# Configure the default Destination Gate used by HCI (the default is 4, which
+# is the ETSI loopback gate.
+#NFA_HCI_DEFAULT_DEST_GATE=4
+
+###############################################################################
+# Configure the single default SE to use.  The default is to use the first
+# SE that is detected by the stack.  This value might be used when the phone
+# supports multiple SE (e.g. 0xF3 and 0xF4) but you want to force it to use
+# one of them (e.g. 0xF4).
+#ACTIVE_SE=0xF3
+
+###############################################################################
+# Configure the NFC Extras to open and use a static pipe.  If the value is
+# not set or set to 0, then the default is use a dynamic pipe based on a
+# destination gate (see NFA_HCI_DEFAULT_DEST_GATE).  Note there is a value
+# for each UICC (where F3="UICC0" and F4="UICC1")
+#NFA_HCI_STATIC_PIPE_ID_F3=0x70
+#NFA_HCI_STATIC_PIPE_ID_F4=0x71
+
+###############################################################################
+# Force UICC to only listen to the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B.
+#UICC_LISTEN_TECH_MASK=0x03
+
+###############################################################################
+# When disconnecting from Oberthur secure element, perform a warm-reset of
+# the secure element to deselect the applet.
+# The default hex value of the command is 0x3.  If this variable is undefined, then
+# this feature is not used.
+#OBERTHUR_WARM_RESET_COMMAND=3
+
+###############################################################################
+# Default poll duration (in ms)
+#  The defualt is 500ms if not set (see nfc_target.h)
+NFA_DM_DISC_DURATION_POLL=333
+
+###############################################################################
+# AID for Empty Select command
+# If specified, this AID will be substituted when an Empty SELECT command is
+# detected.  The first byte is the length of the AID.  Maximum length is 16.
+AID_FOR_EMPTY_SELECT={08:A0:00:00:01:51:00:00:00}
diff --git a/src/nfa/ce/nfa_ce_act.c b/src/nfa/ce/nfa_ce_act.c
new file mode 100644
index 0000000..f06f9f4
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_act.c
@@ -0,0 +1,1405 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions the NFA_CE state machine.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_ce_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_mem_co.h"
+#include "ndef_utils.h"
+#include "ce_api.h"
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#include "nfa_ee_int.h"
+#endif
+
+/*****************************************************************************
+* Protocol-specific event handlers
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_ce_handle_t3t_evt
+**
+** Description      Handler for Type-3 tag card emulation events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t3t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt: event 0x%x", event);
+
+    switch (event)
+    {
+    case CE_T3T_NDEF_UPDATE_START_EVT:
+        /* Notify app using callback associated with the active ndef */
+        if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
+        {
+            conn_evt.status = NFA_STATUS_OK;
+            (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_START_EVT, but no active NDEF");
+        }
+        break;
+
+    case CE_T3T_NDEF_UPDATE_CPLT_EVT:
+        /* Notify app using callback associated with the active ndef */
+        if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
+        {
+            conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
+            conn_evt.ndef_write_cplt.len    = p_ce_data->update_info.length;
+            conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
+            (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_ce_handle_t3t_evt: got CE_T3T_UPDATE_CPLT_EVT, but no active NDEF");
+        }
+        break;
+
+    case CE_T3T_RAW_FRAME_EVT:
+        if (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
+        {
+            conn_evt.data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
+            conn_evt.data.len    = p_ce_data->raw_frame.p_data->len;
+            (*p_cb->p_active_conn_cback) (NFA_DATA_EVT, &conn_evt);
+        }
+        else
+        {
+            conn_evt.ce_data.handle = (NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active));
+            conn_evt.ce_data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
+            conn_evt.ce_data.len    = p_ce_data->raw_frame.p_data->len;
+            (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
+        }
+        GKI_freebuf (p_ce_data->raw_frame.p_data);
+        break;
+
+    default:
+        NFA_TRACE_DEBUG1 ("nfa_ce_handle_t3t_evt unhandled event=0x%02x", event);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_handle_t4t_evt
+**
+** Description      Handler for Type-4 tag card emulation events (for NDEF case)
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t4t_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt: event 0x%x", event);
+
+    /* AID for NDEF selected. we had notified the app of activation. */
+    p_cb->idx_cur_active = NFA_CE_LISTEN_INFO_IDX_NDEF;
+    if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
+    {
+        p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+    }
+
+    switch (event)
+    {
+    case CE_T4T_NDEF_UPDATE_START_EVT:
+        conn_evt.status = NFA_STATUS_OK;
+        (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_START_EVT, &conn_evt);
+        break;
+
+    case CE_T4T_NDEF_UPDATE_CPLT_EVT:
+        conn_evt.ndef_write_cplt.len    = p_ce_data->update_info.length;
+        conn_evt.ndef_write_cplt.p_data = p_ce_data->update_info.p_data;
+
+        if (NDEF_MsgValidate (p_ce_data->update_info.p_data, p_ce_data->update_info.length, TRUE) != NDEF_OK)
+            conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
+        else
+            conn_evt.ndef_write_cplt.status = NFA_STATUS_OK;
+
+        (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+        break;
+
+    case CE_T4T_NDEF_UPDATE_ABORT_EVT:
+        conn_evt.ndef_write_cplt.len    = 0;
+        conn_evt.ndef_write_cplt.status = NFA_STATUS_FAILED;
+        conn_evt.ndef_write_cplt.p_data = NULL;
+        (*p_cb->p_active_conn_cback) (NFA_CE_NDEF_WRITE_CPLT_EVT, &conn_evt);
+        break;
+
+    default:
+        /* CE_T4T_RAW_FRAME_EVT is not used in NFA CE */
+        NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_evt unhandled event=0x%02x", event);
+        break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ce_handle_t4t_aid_evt
+**
+** Description      Handler for Type-4 tag AID events (for AIDs registered using
+**                  NFA_CeRegisterT4tAidOnDH)
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_handle_t4t_aid_evt (tCE_EVENT event, tCE_DATA *p_ce_data)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    UINT8 listen_info_idx;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG1 ("nfa_ce_handle_t4t_aid_evt: event 0x%x", event);
+
+    /* Get listen_info for this aid callback */
+    for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
+    {
+        if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+            (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID) &&
+            (p_cb->listen_info[listen_info_idx].t4t_aid_handle == p_ce_data->raw_frame.aid_handle))
+        {
+            p_cb->idx_cur_active      = listen_info_idx;
+            p_cb->p_active_conn_cback = p_cb->listen_info[p_cb->idx_cur_active].p_conn_cback;
+            break;
+        }
+    }
+
+    if (event == CE_T4T_RAW_FRAME_EVT)
+    {
+        if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
+        {
+            /* Found listen_info entry */
+            conn_evt.ce_activated.handle =   NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE) p_cb->idx_cur_active);
+
+            /* If we have not notified the app of activation, do so now */
+            if (p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND)
+            {
+                p_cb->listen_info[p_cb->idx_cur_active].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+                memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
+                conn_evt.ce_activated.status = NFA_STATUS_OK;
+                (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
+            }
+
+            /* Notify app of AID data */
+            conn_evt.ce_data.handle =   NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
+            conn_evt.ce_data.p_data = (UINT8 *) (p_ce_data->raw_frame.p_data + 1) + p_ce_data->raw_frame.p_data->offset;
+            conn_evt.ce_data.len    = p_ce_data->raw_frame.p_data->len;
+            (*p_cb->p_active_conn_cback) (NFA_CE_DATA_EVT, &conn_evt);
+        }
+        else
+        {
+            NFA_TRACE_ERROR1 ("nfa_ce_handle_t4t_aid_evt: unable to find listen_info for aid hdl %i", p_ce_data->raw_frame.aid_handle)
+        }
+
+        GKI_freebuf (p_ce_data->raw_frame.p_data);
+    }
+}
+
+/*****************************************************************************
+* Discovery configuration and discovery event handlers
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_ce_discovery_cback
+**
+** Description      Processing event from discovery callback
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ce_discovery_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
+{
+    tNFA_CE_MSG ce_msg;
+    NFA_TRACE_DEBUG1 ("nfa_ce_discovery_cback(): event:0x%02X", event);
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISC_START_EVT:
+        NFA_TRACE_DEBUG1 ("nfa_ce_handle_disc_start (status=0x%x)", p_data->start);
+        break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+        ce_msg.activate_ntf.hdr.event = NFA_CE_ACTIVATE_NTF_EVT;
+        ce_msg.activate_ntf.p_activation_params = &p_data->activate;
+        nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
+        break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+        ce_msg.hdr.event = NFA_CE_DEACTIVATE_NTF_EVT;
+        ce_msg.hdr.layer_specific = p_data->deactivate.type;
+        nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
+        break;
+
+    case NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT:
+        /* DH initiated deactivation in NFA_DM_RFST_LISTEN_SLEEP */
+        ce_msg.hdr.event = NFA_CE_DEACTIVATE_NTF_EVT;
+        ce_msg.hdr.layer_specific = NFA_DEACTIVATE_TYPE_IDLE;
+        nfa_ce_hdl_event ((BT_HDR *) &ce_msg);
+        break;
+
+    default:
+        NFA_TRACE_ERROR0 ("Unexpected event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ce_t3t_set_listen_params
+**
+** Description      Set t3t listening parameters
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfc_ce_t3t_set_listen_params (void)
+{
+    UINT8 i;
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    UINT8 tlv[32], *p_params;
+    UINT8 tlv_size;
+    UINT16 t3t_flags2_mask = 0xFFFF;        /* Mask of which T3T_IDs are disabled */
+    UINT8 t3t_idx = 0;
+
+    /* Point to start of tlv buffer */
+    p_params = tlv;
+
+    /* Set system code and NFCID2 */
+    for (i=0; i<NFA_CE_LISTEN_INFO_MAX; i++)
+    {
+        if ((p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE) &&
+            (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
+        {
+            /* Set tag's system code and NFCID2 */
+            UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_ID1+t3t_idx);                 /* type */
+            UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_ID);                     /* length */
+            UINT16_TO_BE_STREAM (p_params, p_cb->listen_info[i].t3t_system_code);    /* System Code */
+            ARRAY_TO_BE_STREAM (p_params,  p_cb->listen_info[i].t3t_nfcid2, NCI_RF_F_UID_LEN);
+
+            /* Set mask for this ID */
+            t3t_flags2_mask &= ~((UINT16) (1<<t3t_idx));
+            t3t_idx++;
+        }
+    }
+
+    /* For NCI draft 22+, the polarity of NFC_PMID_LF_T3T_FLAGS2 is flipped */
+    t3t_flags2_mask = ~t3t_flags2_mask;
+
+    UINT8_TO_STREAM (p_params, NFC_PMID_LF_T3T_FLAGS2);      /* type */
+    UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_FLAGS2); /* length */
+    UINT16_TO_STREAM (p_params, t3t_flags2_mask);            /* Mask of IDs to disable listening */
+
+    tlv_size = (UINT8) (p_params-tlv);
+    nfa_dm_check_set_config (tlv_size, (UINT8 *)tlv, FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_t3t_generate_rand_nfcid
+**
+** Description      Generate a random NFCID2 for Type-3 tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_t3t_generate_rand_nfcid (UINT8 nfcid2[NCI_RF_F_UID_LEN])
+{
+    UINT32 rand_seed = GKI_get_tick_count ();
+
+    /* For Type-3 tag, nfcid2 starts witn 02:fe */
+    nfcid2[0] = 0x02;
+    nfcid2[1] = 0xFE;
+
+    /* The remaining 6 bytes are random */
+    nfcid2[2] = (UINT8) (rand_seed & 0xFF);
+    nfcid2[3] = (UINT8) (rand_seed>>8 & 0xFF);
+    rand_seed>>=(rand_seed&3);
+    nfcid2[4] = (UINT8) (rand_seed & 0xFF);
+    nfcid2[5] = (UINT8) (rand_seed>>8 & 0xFF);
+    rand_seed>>=(rand_seed&3);
+    nfcid2[6] = (UINT8) (rand_seed & 0xFF);
+    nfcid2[7] = (UINT8) (rand_seed>>8 & 0xFF);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_start_listening
+**
+** Description      Start listening
+**
+** Returns          NFA_STATUS_OK if successful
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_start_listening (void)
+{
+    tNFA_DM_DISC_TECH_PROTO_MASK listen_mask;
+    tNFA_CE_CB    *p_cb = &nfa_ce_cb;
+    tNFA_HANDLE   disc_handle;
+    UINT8         listen_info_idx;
+
+    /*************************************************************************/
+    /* Construct protocol preference list to listen for */
+
+    /* First, get protocol preference for active NDEF (if any) */
+    if (  (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
+        &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle == NFA_HANDLE_INVALID))
+    {
+        listen_mask = 0;
+
+        if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_T3T)
+        {
+            /* set T3T config params */
+            nfc_ce_t3t_set_listen_params ();
+
+            listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
+        }
+
+        if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
+        {
+            listen_mask |= nfa_ce_cb.isodep_disc_mask;
+        }
+
+        disc_handle = nfa_dm_add_rf_discover (listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_ce_discovery_cback);
+
+        if (disc_handle == NFA_HANDLE_INVALID)
+            return (NFA_STATUS_FAILED);
+        else
+            p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = disc_handle;
+    }
+
+    /* Next, add protocols from non-NDEF, if any */
+    for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
+    {
+        /* add RF discovery to DM only if it is not added yet */
+        if (  (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+            &&(p_cb->listen_info[listen_info_idx].rf_disc_handle == NFA_HANDLE_INVALID))
+        {
+            if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
+            {
+                /* set T3T config params */
+                nfc_ce_t3t_set_listen_params ();
+
+                disc_handle = nfa_dm_add_rf_discover (NFA_DM_DISC_MASK_LF_T3T,
+                                                      NFA_DM_DISC_HOST_ID_DH,
+                                                      nfa_ce_discovery_cback);
+
+                if (disc_handle == NFA_HANDLE_INVALID)
+                    return (NFA_STATUS_FAILED);
+                else
+                    p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+            }
+            else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
+            {
+                disc_handle = nfa_dm_add_rf_discover (nfa_ce_cb.isodep_disc_mask,
+                                                       NFA_DM_DISC_HOST_ID_DH,
+                                                       nfa_ce_discovery_cback);
+
+                if (disc_handle == NFA_HANDLE_INVALID)
+                    return (NFA_STATUS_FAILED);
+                else
+                    p_cb->listen_info[listen_info_idx].rf_disc_handle = disc_handle;
+            }
+#if (NFC_NFCEE_INCLUDED == TRUE)
+            else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
+            {
+                listen_mask = 0;
+                if (nfa_ee_is_active (p_cb->listen_info[listen_info_idx].ee_handle))
+                {
+                    if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_A)
+                    {
+                        listen_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
+                    }
+                    if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_B)
+                    {
+                        listen_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+                    }
+                    if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_F)
+                    {
+                        listen_mask |= NFA_DM_DISC_MASK_LF_T3T;
+                    }
+                    if (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
+                    {
+                        listen_mask |= NFA_DM_DISC_MASK_L_B_PRIME;
+                    }
+                }
+
+                if (listen_mask)
+                {
+                    /* Start listening for requested technologies */
+                    /* register discovery callback to NFA DM */
+                    disc_handle = nfa_dm_add_rf_discover (listen_mask,
+                                                          (tNFA_DM_DISC_HOST_ID) (p_cb->listen_info[listen_info_idx].ee_handle &0x00FF),
+                                                          nfa_ce_discovery_cback);
+
+                    if (disc_handle == NFA_HANDLE_INVALID)
+                        return (NFA_STATUS_FAILED);
+                    else
+                    {
+                        p_cb->listen_info[listen_info_idx].rf_disc_handle  = disc_handle;
+                        p_cb->listen_info[listen_info_idx].tech_proto_mask = listen_mask;
+                    }
+                }
+                else
+                {
+                    NFA_TRACE_ERROR1 ("UICC[0x%x] is not activated",
+                                       p_cb->listen_info[listen_info_idx].ee_handle);
+                }
+            }
+#endif
+        }
+    }
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_restart_listen_check
+**
+** Description      Called on deactivation. Check if any active listen_info entries to listen for
+**
+** Returns          TRUE if listening is restarted.
+**                  FALSE if listening not restarted
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_restart_listen_check (void)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    UINT8 listen_info_idx;
+
+    /* Check if any active entries in listen_info table */
+    for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
+    {
+        if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+            break;
+    }
+
+    /* Restart listening if there are any active listen_info entries */
+    if (listen_info_idx != NFA_CE_LISTEN_INFO_IDX_INVALID)
+    {
+        /* restart listening */
+        nfa_ce_start_listening ();
+    }
+    else
+    {
+        /* No active listen_info entries */
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_remove_listen_info_entry
+**
+** Description      Remove entry from listen_info table. (when API deregister is called or listen_start failed)
+**
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_remove_listen_info_entry (UINT8 listen_info_idx, BOOLEAN notify_app)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG1 ("NFA_CE: removing listen_info entry %i", listen_info_idx);
+
+    /* Notify app that listening has stopped  if requested (for API deregister) */
+    /* For LISTEN_START failures, app has already notified of NFA_LISTEN_START_EVT failure */
+    if (notify_app)
+    {
+        if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
+        {
+            conn_evt.status = NFA_STATUS_OK;
+            (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+        }
+#if (NFC_NFCEE_INCLUDED == TRUE)
+        else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
+        {
+            conn_evt.status = NFA_STATUS_OK;
+            (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+        }
+#endif
+        else
+        {
+            conn_evt.ce_deregistered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
+            (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_DEREGISTERED_EVT, &conn_evt);
+        }
+    }
+
+
+    /* Handle NDEF stopping */
+    if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF)
+    {
+        /* clear NDEF contents */
+        CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+        CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+
+        if (p_cb->listen_info[listen_info_idx].protocol_mask & NFA_PROTOCOL_MASK_T3T)
+        {
+            p_cb->listen_info[listen_info_idx].protocol_mask = 0;
+
+            /* clear T3T Flags for NDEF */
+            nfc_ce_t3t_set_listen_params ();
+        }
+
+        /* Free scratch buffer for this NDEF, if one was allocated */
+        nfa_ce_free_scratch_buf ();
+    }
+    /* If stopping listening Felica system code, then clear T3T Flags for this */
+    else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_FELICA)
+    {
+        p_cb->listen_info[listen_info_idx].protocol_mask = 0;
+
+        /* clear T3T Flags for registered Felica system code */
+        nfc_ce_t3t_set_listen_params ();
+    }
+    /* If stopping listening T4T AID, then deregister this AID from CE_T4T */
+    else if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_T4T_AID)
+    {
+        /* Free t4t_aid_cback used by this AID */
+        CE_T4tDeregisterAID (p_cb->listen_info[listen_info_idx].t4t_aid_handle);
+    }
+
+    if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID )
+    {
+        nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
+        p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+    }
+
+    /* Remove entry from listen_info table */
+    p_cb->listen_info[listen_info_idx].flags = 0;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_free_scratch_buf
+**
+** Description      free scratch buffer (if one is allocated)
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_ce_free_scratch_buf (void)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    if (p_cb->p_scratch_buf)
+    {
+        nfa_mem_co_free (p_cb->p_scratch_buf);
+        p_cb->p_scratch_buf = NULL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_realloc_scratch_buffer
+**
+** Description      Set scratch buffer if necessary (for writable NDEF messages)
+**
+** Returns          NFA_STATUS_OK if successful
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_realloc_scratch_buffer (void)
+{
+    tNFA_STATUS result = NFA_STATUS_OK;
+
+    /* If current NDEF message is read-only, then we do not need a scratch buffer */
+    if (nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF)
+    {
+        /* Free existing scratch buffer, if one was allocated */
+        nfa_ce_free_scratch_buf ();
+    }
+    else
+    {
+        /* If no scratch buffer allocated yet, or if current scratch buffer size is different from current ndef size, */
+        /* then allocate a new scratch buffer. */
+        if ((nfa_ce_cb.p_scratch_buf == NULL) ||
+            (nfa_ce_cb.scratch_buf_size != nfa_ce_cb.ndef_max_size))
+        {
+            /* Free existing scratch buffer, if one was allocated */
+            nfa_ce_free_scratch_buf ();
+
+            if ((nfa_ce_cb.p_scratch_buf = (UINT8 *) nfa_mem_co_alloc (nfa_ce_cb.ndef_max_size)) != NULL)
+            {
+                nfa_ce_cb.scratch_buf_size = nfa_ce_cb.ndef_max_size;
+            }
+            else
+            {
+                NFA_TRACE_ERROR1 ("Unable to allocate scratch buffer for writable NDEF message (%i bytes)", nfa_ce_cb.ndef_max_size);
+                result=NFA_STATUS_FAILED;
+            }
+        }
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_set_content
+**
+** Description      Set NDEF contents
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFC_STATUS nfa_ce_set_content (void)
+{
+    tNFC_STATUS status;
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_PROTOCOL_MASK ndef_protocol_mask;
+    BOOLEAN readonly;
+
+    /* Check if listening for NDEF */
+    if (!(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE))
+    {
+        /* Not listening for NDEF */
+        return (NFA_STATUS_OK);
+    }
+
+    NFA_TRACE_DEBUG0 ("Setting NDEF contents");
+
+    readonly = (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFC_CE_LISTEN_INFO_READONLY_NDEF) ? TRUE : FALSE;
+    ndef_protocol_mask = p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask;
+
+    /* Allocate a scratch buffer if needed (for handling write-requests) */
+    if ((status = nfa_ce_realloc_scratch_buffer ()) == NFA_STATUS_OK)
+    {
+        if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_T3T) && (status == NFA_STATUS_OK))
+        {
+            /* Type3Tag    - NFC-F */
+            status = CE_T3tSetLocalNDEFMsg (readonly,
+                                            p_cb->ndef_max_size,
+                                            p_cb->ndef_cur_size,
+                                            p_cb->p_ndef_data,
+                                            p_cb->p_scratch_buf);
+        }
+
+        if ((ndef_protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP) && (status == NFA_STATUS_OK))
+        {
+            /* ISODEP/4A,4B- NFC-A or NFC-B */
+            status = CE_T4tSetLocalNDEFMsg (readonly,
+                                            p_cb->ndef_max_size,
+                                            p_cb->ndef_cur_size,
+                                            p_cb->p_ndef_data,
+                                            p_cb->p_scratch_buf);
+        }
+    }
+
+    if (status != NFA_STATUS_OK)
+    {
+        /* clear NDEF contents */
+        CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+        CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+
+        NFA_TRACE_ERROR1 ("Unable to set contents (error %02x)", status);
+    }
+
+    return (status);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ce_activate_ntf
+**
+** Description      Action when activation has occured (NFA_CE_ACTIVATE_NTF_EVT)
+**
+**                  - Find the listen_info entry assocated with this activation
+**                      - get the app callback that registered for this listen
+**                      - call CE_SetActivatedTagType with activation parameters
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_activate_ntf (tNFA_CE_MSG *p_ce_msg)
+{
+    tNFC_ACTIVATE_DEVT *p_activation_params = p_ce_msg->activate_ntf.p_activation_params;
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+    tCE_CBACK *p_ce_cback = NULL;
+    UINT16 t3t_system_code = 0xFFFF;
+    UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
+    UINT8 *p_nfcid2 = NULL;
+    UINT8 i;
+    BOOLEAN t4t_activate_pending = FALSE;
+
+    NFA_TRACE_DEBUG1 ("nfa_ce_activate_ntf () protocol=%d", p_ce_msg->activate_ntf.p_activation_params->protocol);
+
+    /* Tag is in listen active state */
+    p_cb->flags |= NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
+
+    /* Store activation parameters */
+    memcpy (&p_cb->activation_params, p_activation_params, sizeof (tNFC_ACTIVATE_DEVT));
+
+    /* Find the listen_info entry corresponding to this activation */
+    if (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
+    {
+        /* Look for T3T entries in listen_info table that match activated system code and NFCID2 */
+        for (listen_info_idx=0; listen_info_idx<NFA_CE_LISTEN_INFO_IDX_INVALID; listen_info_idx++)
+        {
+            /* Look for entries with NFA_PROTOCOL_MASK_T3T */
+            if (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+            {
+                if (p_cb->listen_info[listen_info_idx].protocol_mask & NFA_PROTOCOL_MASK_T3T)
+                {
+                    /* Check if system_code and nfcid2 that matches activation params */
+                    p_nfcid2 = p_cb->listen_info[listen_info_idx].t3t_nfcid2;
+                    t3t_system_code = p_cb->listen_info[listen_info_idx].t3t_system_code;
+
+                    /* Compare NFCID2 (note: NFCC currently does not return system code in activation parameters) */
+                    if ((memcmp (p_nfcid2, p_cb->activation_params.rf_tech_param.param.lf.nfcid2, NCI_RF_F_UID_LEN)==0)
+                         /* && (t3t_system_code == p_ce_msg->activation.p_activate_info->rf_tech_param.param.lf.system_code) */)
+                    {
+                        /* Found listen_info corresponding to this activation */
+                        break;
+                    }
+                }
+
+                /* Check if entry is for T3T UICC */
+                if ((p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC) &&
+                    (p_cb->listen_info[listen_info_idx].tech_mask & NFA_TECHNOLOGY_MASK_F))
+                {
+                    break;
+                }
+            }
+        }
+
+        p_ce_cback = nfa_ce_handle_t3t_evt;
+    }
+    else if (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
+    {
+        p_ce_cback = nfa_ce_handle_t4t_evt;
+
+        /* For T4T, we do not know which AID will be selected yet */
+
+
+        /* For all T4T entries in listen_info, set T4T_ACTIVATE_NOTIFY_PENDING flag */
+        for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
+        {
+            if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
+            {
+                if (p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP)
+                {
+                    /* Found listen_info table entry for T4T raw listen */
+                    p_cb->listen_info[i].flags |= NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+                    /* If entry if for NDEF, select it, so application gets nofitifed of ACTIVATE_EVT now */
+                    if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
+                    {
+                        listen_info_idx = NFA_CE_LISTEN_INFO_IDX_NDEF;
+                    }
+
+                    t4t_activate_pending = TRUE;
+                }
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+                /* Check if entry is for ISO_DEP UICC */
+                if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
+                {
+                    if (  (  (p_cb->activation_params.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A)
+                           &&(p_cb->listen_info[i].tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)  )
+                                                       ||
+                          (  (p_cb->activation_params.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B)
+                           &&(p_cb->listen_info[i].tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)  )  )
+                    {
+                        listen_info_idx = i;
+                    }
+                }
+#endif
+            }
+        }
+
+        /* If listening for ISO_DEP, but not NDEF nor UICC, then notify CE module now and wait for reader/writer to SELECT an AID */
+        if (t4t_activate_pending && (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID))
+        {
+            CE_SetActivatedTagType (&p_cb->activation_params, 0, p_ce_cback);
+            return TRUE;
+        }
+    }
+    else if (p_cb->activation_params.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
+    {
+        /* search any entry listening UICC */
+        for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
+        {
+            if (  (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
+                &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC))
+            {
+                listen_info_idx = i;
+                break;
+            }
+        }
+    }
+
+    /* Check if valid listen_info entry was found */
+    if (  (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
+        ||((listen_info_idx == NFA_CE_LISTEN_INFO_IDX_NDEF) && !(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)))
+    {
+        NFA_TRACE_DEBUG1 ("No listen_info found for this activation. listen_info_idx=%d", listen_info_idx);
+        return (TRUE);
+    }
+
+    p_cb->listen_info[listen_info_idx].flags &= ~NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND;
+
+    /* Get CONN_CBACK for this activation */
+    p_cb->p_active_conn_cback = p_cb->listen_info[listen_info_idx].p_conn_cback;
+    p_cb->idx_cur_active = listen_info_idx;
+
+    if (  (p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)
+        ||(p_cb->listen_info[p_cb->idx_cur_active].flags & NFA_CE_LISTEN_INFO_UICC))
+    {
+        memcpy (&(conn_evt.activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
+
+        (*p_cb->p_active_conn_cback) (NFA_ACTIVATED_EVT, &conn_evt);
+    }
+    else
+    {
+        conn_evt.ce_activated.handle =   NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)p_cb->idx_cur_active);
+        memcpy (&(conn_evt.ce_activated.activate_ntf), &p_cb->activation_params, sizeof (tNFC_ACTIVATE_DEVT));
+        conn_evt.ce_activated.status = NFA_STATUS_OK;
+
+        (*p_cb->p_active_conn_cback) (NFA_CE_ACTIVATED_EVT, &conn_evt);
+    }
+
+    /* we don't need any CE subsystem in case of NFCEE direct RF interface */
+    if (p_ce_cback)
+    {
+        /* Notify CE subsystem */
+        CE_SetActivatedTagType (&p_cb->activation_params, t3t_system_code, p_ce_cback);
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_deactivate_ntf
+**
+** Description      Action when deactivate occurs. (NFA_CE_DEACTIVATE_NTF_EVT)
+**
+**                  - If deactivate due to API deregister, then remove its entry from
+**                      listen_info table
+**
+**                  - If NDEF was modified while activated, then restore
+**                      original NDEF contents
+**
+**                  - Restart listening (if any active entries in listen table)
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_deactivate_ntf (tNFA_CE_MSG *p_ce_msg)
+{
+    tNFC_DEACT_TYPE deact_type = (tNFC_DEACT_TYPE) p_ce_msg->hdr.layer_specific;
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+    UINT8 i;
+
+    NFA_TRACE_DEBUG1 ("nfa_ce_deactivate_ntf () deact_type=%d", deact_type);
+
+    /* Check if deactivating to SLEEP mode */
+    if (  (deact_type == NFC_DEACTIVATE_TYPE_SLEEP)
+        ||(deact_type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
+    {
+        /* notify deactivated as sleep and wait for reactivation or deactivation to idle */
+        conn_evt.deactivated.type =  deact_type;
+
+        /* if T4T AID application has not been selected then p_active_conn_cback could be NULL */
+        if (p_cb->p_active_conn_cback)
+            (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
+
+        return TRUE;
+    }
+    else
+    {
+        deact_type = NFC_DEACTIVATE_TYPE_IDLE;
+    }
+
+    /* Tag is in idle state */
+    p_cb->flags &= ~NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP;
+
+    /* First, notify app of deactivation */
+    for (i=0; i<NFA_CE_LISTEN_INFO_IDX_INVALID; i++)
+    {
+        if (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
+        {
+            if (  (p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
+                &&(i == p_cb->idx_cur_active)  )
+            {
+                conn_evt.deactivated.type =  deact_type;
+                (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
+            }
+            else if (  (p_cb->activation_params.protocol == NFA_PROTOCOL_ISO_DEP)
+                     &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_ISO_DEP))
+            {
+                /* Don't send NFA_DEACTIVATED_EVT if NFA_ACTIVATED_EVT wasn't sent */
+                if (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND))
+                {
+                    if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
+                    {
+                        conn_evt.deactivated.type =  deact_type;
+                        (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
+                    }
+                    else
+                    {
+                        conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
+                        conn_evt.ce_deactivated.type   = deact_type;
+                        (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
+                    }
+                }
+            }
+            else if (  (p_cb->activation_params.protocol == NFA_PROTOCOL_T3T)
+                     &&(p_cb->listen_info[i].protocol_mask & NFA_PROTOCOL_MASK_T3T))
+            {
+                if (i == NFA_CE_LISTEN_INFO_IDX_NDEF)
+                {
+                    conn_evt.deactivated.type = deact_type;
+                    (*p_cb->p_active_conn_cback) (NFA_DEACTIVATED_EVT, &conn_evt);
+                }
+                else
+                {
+                    conn_evt.ce_deactivated.handle = NFA_HANDLE_GROUP_CE | ((tNFA_HANDLE)i);
+                    conn_evt.ce_deactivated.type   = deact_type;
+                    (*p_cb->p_active_conn_cback) (NFA_CE_DEACTIVATED_EVT, &conn_evt);
+                }
+            }
+        }
+    }
+
+    /* Check if app initiated the deactivation (due to API deregister). If so, remove entry from listen_info table. */
+    if (p_cb->flags & NFA_CE_FLAGS_APP_INIT_DEACTIVATION)
+    {
+        p_cb->flags &= ~NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+        nfa_ce_remove_listen_info_entry (p_cb->idx_cur_active, TRUE);
+    }
+
+    p_cb->p_active_conn_cback = NULL;
+    p_cb->idx_cur_active      = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+    /* Restart listening (if any listen_info entries are still active) */
+    nfa_ce_restart_listen_check ();
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_disable_local_tag
+**
+** Description      Disable local NDEF tag
+**                      - clean up control block
+**                      - remove NDEF discovery configuration
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_ce_disable_local_tag (void)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG0 ("Disabling local NDEF tag");
+
+    /* If local NDEF tag is in use, then disable it */
+    if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
+    {
+        /* NDEF Tag is in not idle state */
+        if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
+            &&(p_cb->idx_cur_active == NFA_CE_LISTEN_INFO_IDX_NDEF)  )
+        {
+            /* wait for deactivation */
+            p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        else
+        {
+            /* Notify DM to stop listening for ndef  */
+            if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
+            {
+                nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
+                p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
+            }
+            nfa_ce_remove_listen_info_entry (NFA_CE_LISTEN_INFO_IDX_NDEF, TRUE);
+        }
+    }
+    else
+    {
+        /* Notify application */
+        evt_data.status = NFA_STATUS_OK;
+        nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_cfg_local_tag
+**
+** Description      Configure local NDEF tag
+**                      - store ndef attributes in to control block
+**                      - update discovery configuration
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    /* Check if disabling local tag */
+    if (p_ce_msg->local_tag.protocol_mask == 0)
+    {
+        nfa_ce_disable_local_tag ();
+        return TRUE;
+    }
+
+    NFA_TRACE_DEBUG5 ("Configuring local NDEF tag: protocol_mask=%01x cur_size=%i, max_size=%i, readonly=%i",
+            p_ce_msg->local_tag.protocol_mask,
+            p_ce_msg->local_tag.ndef_cur_size,
+            p_ce_msg->local_tag.ndef_max_size,
+            p_ce_msg->local_tag.read_only,
+            p_ce_msg->local_tag.uid_len);
+
+    /* If local tag was already set, then check if NFA_CeConfigureLocalTag called to change protocol mask  */
+    if (  (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags & NFA_CE_LISTEN_INFO_IN_USE)
+        &&(p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle != NFA_HANDLE_INVALID)
+        &&((p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
+            != (p_ce_msg->local_tag.protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP)))  )
+    {
+        /* Listening for different tag protocols. Stop discovery */
+        nfa_dm_delete_rf_discover (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle);
+        p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
+
+        /* clear NDEF contents */
+        CE_T3tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+        CE_T4tSetLocalNDEFMsg (TRUE, 0, 0, NULL, NULL);
+    }
+
+    /* Store NDEF info to control block */
+    p_cb->p_ndef_data   = p_ce_msg->local_tag.p_ndef_data;
+    p_cb->ndef_cur_size = p_ce_msg->local_tag.ndef_cur_size;
+    p_cb->ndef_max_size = p_ce_msg->local_tag.ndef_max_size;
+
+    /* Fill in LISTEN_INFO entry for NDEF */
+    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags = NFA_CE_LISTEN_INFO_IN_USE;
+    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask = p_ce_msg->local_tag.protocol_mask;
+    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].p_conn_cback = nfa_dm_conn_cback_event_notify;
+    if (p_ce_msg->local_tag.read_only)
+        p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].flags |= NFC_CE_LISTEN_INFO_READONLY_NDEF;
+    p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_system_code = T3T_SYSTEM_CODE_NDEF;
+
+    /* Set NDEF contents */
+    conn_evt.status = NFA_STATUS_FAILED;
+
+    if (p_cb->listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].protocol_mask & (NFA_PROTOCOL_MASK_T3T | NFA_PROTOCOL_MASK_ISO_DEP))
+    {
+        /* Ok to set contents now */
+        if (nfa_ce_set_content () != NFA_STATUS_OK)
+        {
+            NFA_TRACE_ERROR0 ("nfa_ce_api_cfg_local_tag: could not set contents");
+            nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+            return TRUE;
+        }
+
+        /* Start listening and notify app of status */
+        conn_evt.status = nfa_ce_start_listening ();
+        nfa_dm_conn_cback_event_notify (NFA_CE_LOCAL_TAG_CONFIGURED_EVT, &conn_evt);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_reg_listen
+**
+** Description      Register listen params for Felica system code, T4T AID,
+**                  or UICC
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    tNFA_CONN_EVT_DATA conn_evt;
+    UINT8 i;
+    UINT8 listen_info_idx = NFA_CE_LISTEN_INFO_IDX_INVALID;
+
+    NFA_TRACE_DEBUG1 ("Registering UICC/Felica/Type-4 tag listener. Type=%i", p_ce_msg->reg_listen.listen_type);
+
+    /* Look for available entry in listen_info table                                        */
+    /* - If registering UICC listen, make sure there isn't another entry for the ee_handle  */
+    /* - Skip over entry 0 (reserved for local NDEF tag)                                    */
+    for (i=1; i<NFA_CE_LISTEN_INFO_MAX; i++)
+    {
+        if (  (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
+            &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE)
+            &&(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_UICC)
+            &&(p_cb->listen_info[i].ee_handle == p_ce_msg->reg_listen.ee_handle)  )
+        {
+
+            NFA_TRACE_ERROR1 ("UICC (0x%x) listening already specified", p_ce_msg->reg_listen.ee_handle);
+            conn_evt.status = NFA_STATUS_FAILED;
+            nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+            return TRUE;
+        }
+        /* If this is a free entry, and we haven't found one yet, remember it */
+        else if (  (!(p_cb->listen_info[i].flags & NFA_CE_LISTEN_INFO_IN_USE))
+                 &&(listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)  )
+        {
+            listen_info_idx = i;
+        }
+    }
+
+    /* Add new entry to listen_info table */
+    if (listen_info_idx == NFA_CE_LISTEN_INFO_IDX_INVALID)
+    {
+        NFA_TRACE_ERROR1 ("Maximum listen callbacks exceeded (%i)", NFA_CE_LISTEN_INFO_MAX);
+
+        if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
+        {
+            conn_evt.status = NFA_STATUS_FAILED;
+            nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+        }
+        else
+        {
+            /* Notify application */
+            conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
+            conn_evt.ce_registered.status = NFA_STATUS_FAILED;
+            (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
+        }
+        return TRUE;
+    }
+    else
+    {
+        NFA_TRACE_DEBUG1 ("NFA_CE: adding listen_info entry %i", listen_info_idx);
+
+        /* Store common parameters */
+        /* Mark entry as 'in-use', and NFA_CE_LISTEN_INFO_START_NTF_PND */
+        /* (LISTEN_START_EVT will be notified when discovery successfully starts */
+        p_cb->listen_info[listen_info_idx].flags = NFA_CE_LISTEN_INFO_IN_USE | NFA_CE_LISTEN_INFO_START_NTF_PND;
+        p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+        p_cb->listen_info[listen_info_idx].protocol_mask = 0;
+
+        /* Store type-specific parameters */
+        switch (p_ce_msg->reg_listen.listen_type)
+        {
+        case NFA_CE_REG_TYPE_ISO_DEP:
+            p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_ISO_DEP;
+            p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_T4T_AID;
+            p_cb->listen_info[listen_info_idx].p_conn_cback =p_ce_msg->reg_listen.p_conn_cback;
+
+            /* Register this AID with CE_T4T */
+            if ((p_cb->listen_info[listen_info_idx].t4t_aid_handle = CE_T4tRegisterAID (p_ce_msg->reg_listen.aid_len,
+                                                                                        p_ce_msg->reg_listen.aid,
+                                                                                        nfa_ce_handle_t4t_aid_evt)) == 0xFF)
+            {
+                NFA_TRACE_ERROR0 ("Unable to register AID");
+                p_cb->listen_info[listen_info_idx].flags = 0;
+
+                /* Notify application */
+                conn_evt.ce_registered.handle = NFA_HANDLE_INVALID;
+                conn_evt.ce_registered.status = NFA_STATUS_FAILED;
+                (*p_ce_msg->reg_listen.p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
+
+                return TRUE;
+            }
+            break;
+
+        case NFA_CE_REG_TYPE_FELICA:
+            p_cb->listen_info[listen_info_idx].protocol_mask = NFA_PROTOCOL_MASK_T3T;
+            p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_FELICA;
+            p_cb->listen_info[listen_info_idx].p_conn_cback = p_ce_msg->reg_listen.p_conn_cback;
+
+            /* Store system code and nfcid2 */
+            p_cb->listen_info[listen_info_idx].t3t_system_code = p_ce_msg->reg_listen.system_code;
+            memcpy (p_cb->listen_info[listen_info_idx].t3t_nfcid2, p_ce_msg->reg_listen.nfcid2, NCI_RF_F_UID_LEN);
+            break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+        case NFA_CE_REG_TYPE_UICC:
+            p_cb->listen_info[listen_info_idx].flags |= NFA_CE_LISTEN_INFO_UICC;
+            p_cb->listen_info[listen_info_idx].p_conn_cback = &nfa_dm_conn_cback_event_notify;
+
+            /* Store EE handle and Tech */
+            p_cb->listen_info[listen_info_idx].ee_handle = p_ce_msg->reg_listen.ee_handle;
+            p_cb->listen_info[listen_info_idx].tech_mask = p_ce_msg->reg_listen.tech_mask;
+            break;
+#endif
+        }
+    }
+
+    /* Start listening */
+    if ((conn_evt.status = nfa_ce_start_listening ()) != NFA_STATUS_OK)
+    {
+        NFA_TRACE_ERROR0 ("nfa_ce_api_reg_listen: unable to register new listen params with DM");
+        p_cb->listen_info[listen_info_idx].flags = 0;
+    }
+
+    /* Nofitify app of status */
+    if (p_ce_msg->reg_listen.listen_type == NFA_CE_REG_TYPE_UICC)
+    {
+        (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+    }
+    else
+    {
+        conn_evt.ce_registered.handle = NFA_HANDLE_GROUP_CE | listen_info_idx;
+        NFA_TRACE_DEBUG1 ("nfa_ce_api_reg_listen: registered handle 0x%04X", conn_evt.ce_registered.handle);
+        (*p_cb->listen_info[listen_info_idx].p_conn_cback) (NFA_CE_REGISTERED_EVT, &conn_evt);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_dereg_listen
+**
+** Description      Deregister listen params
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg)
+{
+    tNFA_CE_CB *p_cb = &nfa_ce_cb;
+    UINT8 listen_info_idx;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+    /* Check if deregistering UICC , or virtual secure element listen */
+    if (p_ce_msg->dereg_listen.listen_info == NFA_CE_LISTEN_INFO_UICC)
+    {
+        /* Deregistering UICC listen. Look for listen_info for this UICC ee handle */
+        for (listen_info_idx = 0; listen_info_idx < NFA_CE_LISTEN_INFO_MAX; listen_info_idx++)
+        {
+            if (  (p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE)
+                &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_UICC)
+                &&(p_cb->listen_info[listen_info_idx].ee_handle == p_ce_msg->dereg_listen.handle)  )
+            {
+                /* UICC is in not idle state */
+                if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
+                    &&(p_cb->idx_cur_active == listen_info_idx)  )
+                {
+                    /* wait for deactivation */
+                    p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+                    nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+                }
+                else
+                {
+                    /* Stop listening */
+                    if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
+                    {
+                        nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
+                        p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+                    }
+
+                    /* Remove entry and notify application */
+                    nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
+                }
+                break;
+            }
+        }
+
+        if (listen_info_idx == NFA_CE_LISTEN_INFO_MAX)
+        {
+            NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for UICC");
+            conn_evt.status = NFA_STATUS_INVALID_PARAM;
+            nfa_dm_conn_cback_event_notify (NFA_CE_UICC_LISTEN_CONFIGURED_EVT, &conn_evt);
+        }
+    }
+    else
+#endif
+    {
+        /* Deregistering virtual secure element listen */
+        listen_info_idx = p_ce_msg->dereg_listen.handle & NFA_HANDLE_MASK;
+
+        if (  (listen_info_idx < NFA_CE_LISTEN_INFO_MAX)
+            &&(p_cb->listen_info[listen_info_idx].flags & NFA_CE_LISTEN_INFO_IN_USE))
+        {
+            /* virtual secure element is in not idle state */
+            if (  (p_cb->flags & NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP)
+                &&(p_cb->idx_cur_active == listen_info_idx)  )
+            {
+                /* wait for deactivation */
+                p_cb->flags |= NFA_CE_FLAGS_APP_INIT_DEACTIVATION;
+                nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+            }
+            else
+            {
+                /* Stop listening */
+                if (p_cb->listen_info[listen_info_idx].rf_disc_handle != NFA_HANDLE_INVALID)
+                {
+                    nfa_dm_delete_rf_discover (p_cb->listen_info[listen_info_idx].rf_disc_handle);
+                    p_cb->listen_info[listen_info_idx].rf_disc_handle = NFA_HANDLE_INVALID;
+                }
+
+                /* Remove entry and notify application */
+                nfa_ce_remove_listen_info_entry (listen_info_idx, TRUE);
+            }
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_ce_api_dereg_listen (): cannot find listen_info for Felica/T4tAID");
+            conn_evt.status = NFA_STATUS_INVALID_PARAM;
+            nfa_dm_conn_cback_event_notify (NFA_CE_DEREGISTERED_EVT, &conn_evt);
+        }
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_cfg_isodep_tech
+**
+** Description      Configure the technologies (NFC-A and/or NFC-B) to listen for
+**                  ISO-DEP
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg)
+{
+    nfa_ce_cb.isodep_disc_mask  = 0;
+    if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_A)
+        nfa_ce_cb.isodep_disc_mask  = NFA_DM_DISC_MASK_LA_ISO_DEP;
+
+    if (p_ce_msg->hdr.layer_specific & NFA_TECHNOLOGY_MASK_B)
+        nfa_ce_cb.isodep_disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+    return TRUE;
+}
+
diff --git a/src/nfa/ce/nfa_ce_api.c b/src/nfa/ce/nfa_ce_api.c
new file mode 100644
index 0000000..08be523
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_api.c
@@ -0,0 +1,448 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for card emulation
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_ce_int.h"
+#include "nfa_sys_int.h"
+
+
+/*******************************************************************************
+**
+** Function         nfa_ce_api_deregister_listen
+**
+** Description      Internal function called by listening for Felica system
+**                  code, ISO-DEP AID, or UICC technology
+**
+** Returns:
+**                  NFA_STATUS_OK,            if command accepted
+**                  NFA_STATUS_BAD_HANDLE     invalid handle
+**                  NFA_STATUS_FAILED:        otherwise
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ce_api_deregister_listen (tNFA_HANDLE handle, UINT32 listen_info)
+{
+    tNFA_CE_MSG      *p_ce_msg;
+
+    /* Validate handle */
+    if (  (listen_info != NFA_CE_LISTEN_INFO_UICC)
+        &&((handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_CE)  )
+    {
+        NFA_TRACE_ERROR0 ("nfa_ce_api_reregister_listen: Invalid handle");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_ce_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) (sizeof (tNFA_CE_MSG)))) != NULL)
+    {
+        p_ce_msg->hdr.event                     = NFA_CE_API_DEREG_LISTEN_EVT;
+        p_ce_msg->dereg_listen.handle           = handle;
+        p_ce_msg->dereg_listen.listen_info      = listen_info;
+
+        nfa_sys_sendmsg (p_ce_msg);
+
+        return (NFA_STATUS_OK);
+    }
+    else
+    {
+        NFA_TRACE_ERROR0 ("nfa_ce_api_reregister_listen: Out of buffers");
+        return (NFA_STATUS_FAILED);
+    }
+}
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureLocalTag
+**
+** Description      Configure local NDEF tag.
+**
+**                  Tag events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of the
+**                  operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+**                  If a write-request is received to update the tag memory,
+**                  an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application, along
+**                  with a buffer containing the updated contents.
+**
+**                  To disable the local NDEF tag, set protocol_mask=0
+**
+**                  The NDEF data provided by p_ndef_data must be persistent
+**                  as long as the local NDEF tag is enabled.
+**
+**                  UID of the tag can be set only for Type 1 and Type 2 tag.
+**                  UID Length should be 4/7 bytes in case of Type 1 tag and
+**                  UID Length should be 4/10 bytes in case of Type 2 tag.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK,            if command accepted
+**                  NFA_STATUS_INVALID_PARAM,
+**                      if protocol_maks is not 0 and p_ndef_data is NULL
+**                  (or)if p_uid is NULL and uid_len is not 0
+**                  (or)if protocol mask is set for both Type 1 and Type 2
+**                  (or)if uid_len is not 0 and protocol mask is not set for Type 1/2
+**                  (or)if protocol mask is set for Type 1 and uid_len is not 4/7
+**                  (or)if protocol mask is set for Type 2 and uid_len is not 4/10
+**
+**                  NFA_STATUS_FAILED:        otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeConfigureLocalTag (tNFA_PROTOCOL_MASK protocol_mask,
+                                     UINT8     *p_ndef_data,
+                                     UINT16    ndef_cur_size,
+                                     UINT16    ndef_max_size,
+                                     BOOLEAN   read_only,
+                                     UINT8     uid_len,
+                                     UINT8     *p_uid)
+
+{
+    tNFA_CE_MSG *p_msg;
+
+    NFA_TRACE_API0 ("NFA_CeConfigureLocalTag ()");
+
+    if (protocol_mask)
+    {
+        /* If any protocols are specified, then NDEF buffer pointer must be non-NULL */
+        if (p_ndef_data == NULL)
+        {
+            NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: NULL ndef data pointer");
+            return (NFA_STATUS_INVALID_PARAM);
+        }
+
+        if ((protocol_mask & NFA_PROTOCOL_MASK_T1T) && (protocol_mask & NFA_PROTOCOL_MASK_T2T))
+        {
+            NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: Cannot emulate both Type 1 and Type 2 tag simultaneously");
+            return (NFA_STATUS_INVALID_PARAM);
+        }
+
+        if ((uid_len) && !(protocol_mask & NFA_PROTOCOL_MASK_T1T) && !(protocol_mask & NFA_PROTOCOL_MASK_T2T))
+        {
+            NFA_TRACE_ERROR1 ("NFA_CeConfigureLocalTag: Cannot Set UID for Protocol_mask: 0x%x", protocol_mask);
+            return (NFA_STATUS_INVALID_PARAM);
+        }
+
+        if ((uid_len) && (protocol_mask & NFA_PROTOCOL_MASK_T1T) && (uid_len != NFA_T1T_UID_LEN) && (uid_len != NFA_T1T_CMD_UID_LEN))
+        {
+            NFA_TRACE_ERROR1 ("NFA_CeConfigureLocalTag: Invalid UID Length for Type 1: 0x%x", uid_len);
+            return (NFA_STATUS_INVALID_PARAM);
+        }
+
+        if ((uid_len) && (protocol_mask & NFA_PROTOCOL_MASK_T2T) && (uid_len != NFA_T2T_UID_LEN) && (uid_len != NFA_MAX_UID_LEN))
+        {
+            NFA_TRACE_ERROR1 ("NFA_CeConfigureLocalTag: Invalid UID Length for Type 2: 0x%x", uid_len);
+            return (NFA_STATUS_INVALID_PARAM);
+        }
+
+        if ((uid_len) && (p_uid == NULL))
+        {
+            NFA_TRACE_ERROR0 ("NFA_CeConfigureLocalTag: Invlaid UID Length/NULL uid pointer");
+            return (NFA_STATUS_INVALID_PARAM);
+        }
+    }
+    if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+    {
+        p_msg->local_tag.hdr.event = NFA_CE_API_CFG_LOCAL_TAG_EVT;
+
+        /* Copy ndef info */
+        p_msg->local_tag.protocol_mask  = protocol_mask;
+        p_msg->local_tag.p_ndef_data    = p_ndef_data;
+        p_msg->local_tag.ndef_cur_size  = ndef_cur_size;
+        p_msg->local_tag.ndef_max_size  = ndef_max_size;
+        p_msg->local_tag.read_only      = read_only;
+        p_msg->local_tag.uid_len        = uid_len;
+
+        if (uid_len)
+            memcpy (p_msg->local_tag.uid, p_uid, uid_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureUiccListenTech
+**
+** Description      Configure listening for the UICC, using the specified
+**                  technologies.
+**
+**                  Events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of the
+**                  operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeConfigureUiccListenTech (tNFA_HANDLE ee_handle,
+                                           tNFA_TECHNOLOGY_MASK tech_mask)
+{
+#if (NFC_NFCEE_INCLUDED == TRUE)
+    tNFA_CE_MSG *p_msg;
+
+    NFA_TRACE_API1 ("NFA_CeConfigureUiccListenTech () ee_handle = 0x%x", ee_handle);
+
+    /* If tech_mask is zero, then app is disabling listening for specified uicc */
+    if (tech_mask == 0)
+    {
+        return (nfa_ce_api_deregister_listen (ee_handle, NFA_CE_LISTEN_INFO_UICC));
+    }
+
+    /* Otherwise then app is configuring uicc listen for the specificed technologies */
+    if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+    {
+        p_msg->reg_listen.hdr.event   = NFA_CE_API_REG_LISTEN_EVT;
+        p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_UICC;
+
+        p_msg->reg_listen.ee_handle   = ee_handle;
+        p_msg->reg_listen.tech_mask   = tech_mask;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+#else
+    NFA_TRACE_ERROR0 ("NFA_CeConfigureUiccListenTech () NFCEE related functions are not enabled!");
+#endif
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterFelicaSystemCodeOnDH
+**
+** Description      Register listening callback for Felica system code
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH (UINT16 system_code,
+                                                UINT8 nfcid2[NCI_RF_F_UID_LEN],
+                                                tNFA_CONN_CBACK *p_conn_cback)
+{
+    tNFA_CE_MSG *p_msg;
+
+    NFA_TRACE_API0 ("NFA_CeRegisterFelicaSystemCodeOnDH ()");
+
+    /* Validate parameters */
+    if (p_conn_cback==NULL)
+        return (NFA_STATUS_INVALID_PARAM);
+
+    if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+    {
+        p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+        p_msg->reg_listen.p_conn_cback = p_conn_cback;
+        p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_FELICA;
+
+        /* Listen info */
+        memcpy (p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN);
+        p_msg->reg_listen.system_code = system_code;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterFelicaSystemCodeOnDH
+**
+** Description      Deregister listening callback for Felica
+**                  (previously registered using NFA_CeRegisterFelicaSystemCodeOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH (tNFA_HANDLE handle)
+{
+    NFA_TRACE_API1 ("NFA_CeDeregisterFelicaSystemCodeOnDH (): handle:0x%X", handle);
+    return (nfa_ce_api_deregister_listen (handle, NFA_CE_LISTEN_INFO_FELICA));
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterAidOnDH
+**
+** Description      Register listening callback for the specified ISODEP AID
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+**                  If no AID is specified (aid_len=0), then p_conn_cback will
+**                  will get notifications for any AIDs routed to the DH. This
+**                  over-rides callbacks registered for specific AIDs.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeRegisterAidOnDH (UINT8 aid[NFC_MAX_AID_LEN],
+                                         UINT8           aid_len,
+                                         tNFA_CONN_CBACK *p_conn_cback)
+{
+    tNFA_CE_MSG *p_msg;
+
+    NFA_TRACE_API0 ("NFA_CeRegisterAidOnDH ()");
+
+    /* Validate parameters */
+    if (p_conn_cback==NULL)
+        return (NFA_STATUS_INVALID_PARAM);
+
+    if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+    {
+        p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
+        p_msg->reg_listen.p_conn_cback = p_conn_cback;
+        p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ISO_DEP;
+
+        /* Listen info */
+        memcpy (p_msg->reg_listen.aid, aid, aid_len);
+        p_msg->reg_listen.aid_len = aid_len;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterAidOnDH
+**
+** Description      Deregister listening callback for ISODEP AID
+**                  (previously registered using NFA_CeRegisterAidOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeDeregisterAidOnDH (tNFA_HANDLE handle)
+{
+    NFA_TRACE_API1 ("NFA_CeDeregisterAidOnDH (): handle:0x%X", handle);
+    return (nfa_ce_api_deregister_listen (handle, NFA_CE_LISTEN_INFO_T4T_AID));
+}
+
+/*******************************************************************************
+**
+** Function         NFA_CeSetIsoDepListenTech
+**
+** Description      Set the technologies (NFC-A and/or NFC-B) to listen for when
+**                  NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are called.
+**
+**                  By default (if this API is not called), NFA will listen
+**                  for both NFC-A and NFC-B for ISODEP.
+**
+** Note:            If listening for ISODEP on UICC, the DH listen callbacks
+**                  may still get activate notifications for ISODEP if the reader/
+**                  writer selects an AID that is not routed to the UICC (regardless
+**                  of whether A or B was disabled using NFA_CeSetIsoDepListenTech)
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_CeSetIsoDepListenTech (tNFA_TECHNOLOGY_MASK tech_mask)
+{
+    tNFA_CE_MSG *p_msg;
+    tNFA_TECHNOLOGY_MASK    use_mask = (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B);
+
+    NFA_TRACE_API1 ("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask);
+    if (((tech_mask & use_mask) == 0) ||
+        ((tech_mask & ~use_mask) != 0) )
+    {
+        NFA_TRACE_ERROR0 ("NFA_CeSetIsoDepListenTech: Invalid technology mask");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_CE_MSG *) GKI_getbuf ((UINT16) sizeof(tNFA_CE_MSG))) != NULL)
+    {
+        p_msg->hdr.event            = NFA_CE_API_CFG_ISODEP_TECH_EVT;
+        p_msg->hdr.layer_specific   = tech_mask;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
diff --git a/src/nfa/ce/nfa_ce_main.c b/src/nfa/ce/nfa_ce_main.c
new file mode 100644
index 0000000..9ec56d8
--- /dev/null
+++ b/src/nfa/ce/nfa_ce_main.c
@@ -0,0 +1,194 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA_CE
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_ce_api.h"
+#include "nfa_sys.h"
+#include "nfa_ce_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+
+/* NFA_CE control block */
+tNFA_CE_CB nfa_ce_cb;
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+#define NFA_CE_DEFAULT_ISODEP_DISC_MASK (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP)
+
+static const tNFA_SYS_REG nfa_ce_sys_reg =
+{
+    NULL,
+    nfa_ce_hdl_event,
+    nfa_ce_sys_disable,
+    NULL
+};
+
+/* NFA_CE actions */
+const tNFA_CE_ACTION nfa_ce_action_tbl[] =
+{
+    nfa_ce_api_cfg_local_tag,   /* NFA_CE_API_CFG_LOCAL_TAG_EVT */
+    nfa_ce_api_reg_listen,      /* NFA_CE_API_REG_LISTEN_EVT    */
+    nfa_ce_api_dereg_listen,    /* NFA_CE_API_DEREG_LISTEN_EVT  */
+    nfa_ce_api_cfg_isodep_tech, /* NFA_CE_API_CFG_ISODEP_TECH_EVT*/
+    nfa_ce_activate_ntf,        /* NFA_CE_ACTIVATE_NTF_EVT      */
+    nfa_ce_deactivate_ntf,      /* NFA_CE_DEACTIVATE_NTF_EVT    */
+};
+#define NFA_CE_ACTION_TBL_SIZE  (sizeof (nfa_ce_action_tbl) / sizeof (tNFA_CE_ACTION))
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_ce_evt_2_str (UINT16 event);
+#endif
+
+
+/*******************************************************************************
+**
+** Function         nfa_ce_init
+**
+** Description      Initialize NFA CE
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ce_init (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_ce_init ()");
+
+    /* initialize control block */
+    memset (&nfa_ce_cb, 0, sizeof (tNFA_CE_CB));
+
+    /* Generate a random NFCID for Type-3 NDEF emulation (Type-3 tag NFCID2 must start with 02:FE) */
+    nfa_ce_t3t_generate_rand_nfcid (nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].t3t_nfcid2);
+    nfa_ce_cb.listen_info[NFA_CE_LISTEN_INFO_IDX_NDEF].rf_disc_handle = NFA_HANDLE_INVALID;
+    nfa_ce_cb.isodep_disc_mask  = NFA_CE_DEFAULT_ISODEP_DISC_MASK;
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register ( NFA_ID_CE,  &nfa_ce_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_sys_disable
+**
+** Description      Clean up ce sub-system
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ce_sys_disable (void)
+{
+    tNFA_CE_LISTEN_INFO *p_info;
+    UINT8 xx;
+
+    NFC_SetStaticRfCback (NULL);
+
+    /* Free scratch buf if any */
+    nfa_ce_free_scratch_buf ();
+
+    /* Delete discovery handles */
+    for (xx = 0, p_info = nfa_ce_cb.listen_info; xx < NFA_CE_LISTEN_INFO_MAX; xx++, p_info++)
+    {
+        if ((p_info->flags & NFA_CE_LISTEN_INFO_IN_USE) && (p_info->rf_disc_handle != NFA_HANDLE_INVALID))
+        {
+            nfa_dm_delete_rf_discover (p_info->rf_disc_handle);
+            p_info->rf_disc_handle = NFA_HANDLE_INVALID;
+        }
+    }
+
+    nfa_sys_deregister (NFA_ID_CE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ce_hdl_event
+**
+** Description      nfa rw main event handling function.
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN nfa_ce_hdl_event (BT_HDR *p_msg)
+{
+    UINT16 act_idx;
+    BOOLEAN freebuf = TRUE;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_EVENT3 ("nfa_ce_handle_event event: %s (0x%02x), flags: %08x", nfa_ce_evt_2_str (p_msg->event), p_msg->event, nfa_ce_cb.flags);
+#else
+    NFA_TRACE_EVENT2 ("nfa_ce_handle_event event: 0x%x, flags: %08x",p_msg->event, nfa_ce_cb.flags);
+#endif
+
+    /* Get NFA_RW sub-event */
+    if ((act_idx = (p_msg->event & 0x00FF)) < NFA_CE_ACTION_TBL_SIZE)
+    {
+        freebuf = (*nfa_ce_action_tbl[act_idx]) ((tNFA_CE_MSG*) p_msg);
+    }
+
+    /* if vendor specific event handler is registered */
+    if (nfa_ce_cb.p_vs_evt_hdlr)
+    {
+        (*nfa_ce_cb.p_vs_evt_hdlr) (p_msg);
+    }
+
+    return freebuf;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_ce_evt_2_str
+**
+** Description      convert nfc evt to string
+**
+*******************************************************************************/
+static char *nfa_ce_evt_2_str (UINT16 event)
+{
+    switch (event)
+    {
+    case NFA_CE_API_CFG_LOCAL_TAG_EVT:
+        return "NFA_CE_API_CFG_LOCAL_TAG_EVT";
+
+    case NFA_CE_API_REG_LISTEN_EVT:
+        return "NFA_CE_API_REG_LISTEN_EVT";
+
+    case NFA_CE_API_DEREG_LISTEN_EVT:
+        return "NFA_CE_API_DEREG_LISTEN_EVT";
+
+    case NFA_CE_API_CFG_ISODEP_TECH_EVT:
+        return "NFA_CE_API_CFG_ISODEP_TECH_EVT";
+
+    case NFA_CE_ACTIVATE_NTF_EVT:
+        return "NFA_CE_ACTIVATE_NTF_EVT";
+
+    case NFA_CE_DEACTIVATE_NTF_EVT:
+        return "NFA_CE_DEACTIVATE_NTF_EVT";
+
+    default:
+        return "Unknown";
+    }
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/cho/nfa_cho_api.c b/src/nfa/cho/nfa_cho_api.c
new file mode 100644
index 0000000..13122ce
--- /dev/null
+++ b/src/nfa/cho/nfa_cho_api.c
@@ -0,0 +1,457 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for connection handover
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_p2p_api.h"
+#include "nfa_cho_api.h"
+#include "nfa_cho_int.h"
+#include "nfa_mem_co.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_ChoRegister
+**
+** Description      This function is called to register callback function to receive
+**                  connection handover events.
+**
+**                  On this registration, "urn:nfc:sn:handover" server will be
+**                  registered on LLCP if enable_server is TRUE.
+**
+**                  The result of the registration is reported with NFA_CHO_REG_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoRegister (BOOLEAN        enable_server,
+                             tNFA_CHO_CBACK *p_cback)
+{
+    tNFA_CHO_API_REG *p_msg;
+
+    CHO_TRACE_API1 ("NFA_ChoRegister (): enable_server=%d", enable_server);
+
+    if (  (nfa_cho_cb.state != NFA_CHO_ST_DISABLED)
+        ||(nfa_cho_cb.p_cback != NULL)  )
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoRegister (): Already registered or callback is not provided");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_CHO_API_REG *) GKI_getbuf (sizeof (tNFA_CHO_API_REG))) != NULL)
+    {
+        p_msg->hdr.event = NFA_CHO_API_REG_EVT;
+
+        p_msg->enable_server = enable_server;
+        p_msg->p_cback       = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoDeregister
+**
+** Description      This function is called to deregister callback function from NFA
+**                  Connection Handover Application.
+**
+**                  If this is the valid deregistration, NFA Connection Handover
+**                  Application will close the service with "urn:nfc:sn:handover"
+**                  on LLCP and deregister NDEF type handler if any.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoDeregister (void)
+{
+    tNFA_CHO_API_DEREG *p_msg;
+
+    CHO_TRACE_API0 ("NFA_ChoDeregister ()");
+
+    if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoDeregister (): Not registered");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_CHO_API_DEREG *) GKI_getbuf (sizeof (tNFA_CHO_API_DEREG))) != NULL)
+    {
+        p_msg->event = NFA_CHO_API_DEREG_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoConnect
+**
+** Description      This function is called to create data link connection to
+**                  Connection Handover server on peer device.
+**
+**                  It must be called after receiving NFA_CHO_ACTIVATED_EVT.
+**                  NFA_CHO_CONNECTED_EVT will be returned if successful.
+**                  Otherwise, NFA_CHO_DISCONNECTED_EVT will be returned.
+**
+**                  If NFA_CHO_ROLE_REQUESTER is returned in NFA_CHO_CONNECTED_EVT,
+**                  Handover Request Message can be sent.
+**                  If NFA_CHO_ROLE_SELECTOR is returned in NFA_CHO_CONNECTED_EVT
+**                  because of collision, application must wait for Handover
+**                  Request Message.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoConnect (void)
+{
+    tNFA_CHO_API_CONNECT *p_msg;
+
+    CHO_TRACE_API0 ("NFA_ChoConnect ()");
+
+    if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoConnect (): Not registered");
+        return (NFA_STATUS_FAILED);
+    }
+    else if (nfa_cho_cb.state == NFA_CHO_ST_CONNECTED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoConnect (): Already connected");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_CHO_API_CONNECT *) GKI_getbuf (sizeof (tNFA_CHO_API_CONNECT))) != NULL)
+    {
+        p_msg->event = NFA_CHO_API_CONNECT_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoDisconnect
+**
+** Description      This function is called to disconnect data link connection with
+**                  Connection Handover server on peer device.
+**
+**                  NFA_CHO_DISCONNECTED_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoDisconnect (void)
+{
+    tNFA_CHO_API_DISCONNECT *p_msg;
+
+    CHO_TRACE_API0 ("NFA_ChoDisconnect ()");
+
+    if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoDisconnect (): Not registered");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_CHO_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_CHO_API_DISCONNECT))) != NULL)
+    {
+        p_msg->event = NFA_CHO_API_DISCONNECT_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSendHr
+**
+** Description      This function is called to send Handover Request Message with
+**                  Handover Carrier records or Alternative Carrier records.
+**
+**                  It must be called after receiving NFA_CHO_CONNECTED_EVT.
+**
+**                  NDEF may include one or more Handover Carrier records or Alternative
+**                  Carrier records with auxiliary data.
+**                  The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
+**                  Payload ID must be unique and Payload ID length must be less than
+**                  or equal to NFA_CHO_MAX_REF_NAME_LEN.
+**
+**                  The alternative carrier information of Handover Select record
+**                  will be sent to application by NFA_CHO_SELECT_EVT. Application
+**                  may receive NFA_CHO_REQUEST_EVT because of handover collision.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoSendHr (UINT8             num_ac_info,
+                           tNFA_CHO_AC_INFO *p_ac_info,
+                           UINT8            *p_ndef,
+                           UINT32            ndef_len)
+{
+    tNFA_CHO_API_SEND_HR *p_msg;
+    UINT16               msg_size;
+    UINT8                *p_ndef_buf;
+
+    CHO_TRACE_API2 ("NFA_ChoSendHr (): num_ac_info=%d, ndef_len=%d", num_ac_info, ndef_len);
+
+    if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Not connected");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (num_ac_info > NFA_CHO_MAX_AC_INFO)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Too many AC information");
+        return (NFA_STATUS_FAILED);
+    }
+
+    p_ndef_buf = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (!p_ndef_buf)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Failed to allocate buffer for NDEF");
+        return NFA_STATUS_FAILED;
+    }
+    else if (ndef_len > LLCP_POOL_BUF_SIZE)
+    {
+        CHO_TRACE_ERROR1 ("NFA_ChoSendHr (): Failed to allocate buffer for %d bytes", ndef_len);
+        GKI_freebuf (p_ndef_buf);
+        return NFA_STATUS_FAILED;
+    }
+
+    msg_size = sizeof (tNFA_CHO_API_SEND_HR) + num_ac_info * sizeof (tNFA_CHO_AC_INFO);
+
+    if ((p_msg = (tNFA_CHO_API_SEND_HR *) GKI_getbuf (msg_size)) != NULL)
+    {
+        p_msg->hdr.event = NFA_CHO_API_SEND_HR_EVT;
+
+        memcpy (p_ndef_buf, p_ndef, ndef_len);
+        p_msg->p_ndef        = p_ndef_buf;
+        p_msg->max_ndef_size = LLCP_POOL_BUF_SIZE;
+        p_msg->cur_ndef_size = ndef_len;
+
+        p_msg->num_ac_info   = num_ac_info;
+        p_msg->p_ac_info     = (tNFA_CHO_AC_INFO *) (p_msg + 1);
+        memcpy (p_msg->p_ac_info, p_ac_info, num_ac_info * sizeof (tNFA_CHO_AC_INFO));
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    else
+    {
+        GKI_freebuf (p_ndef_buf);
+        return (NFA_STATUS_FAILED);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSendHs
+**
+** Description      This function is called to send Handover Select message with
+**                  Alternative Carrier records as response to Handover Request
+**                  message.
+**
+**                  NDEF may include one or more Alternative Carrier records with
+**                  auxiliary data.
+**                  The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
+**                  Payload ID must be unique and Payload ID length must be less than
+**                  or equal to NFA_CHO_MAX_REF_NAME_LEN.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoSendHs (UINT8             num_ac_info,
+                           tNFA_CHO_AC_INFO *p_ac_info,
+                           UINT8            *p_ndef,
+                           UINT32            ndef_len)
+{
+    tNFA_CHO_API_SEND_HS *p_msg;
+    UINT16               msg_size;
+    UINT8                *p_ndef_buf;
+
+    CHO_TRACE_API2 ("NFA_ChoSendHs(): num_ac_info=%d, ndef_len=%d",
+                    num_ac_info, ndef_len);
+
+    if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Not connected");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (num_ac_info > NFA_CHO_MAX_AC_INFO)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Too many AC information");
+        return (NFA_STATUS_FAILED);
+    }
+
+    p_ndef_buf = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+    if (!p_ndef_buf)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Failed to allocate buffer for NDEF");
+        return NFA_STATUS_FAILED;
+    }
+    else if (ndef_len > LLCP_POOL_BUF_SIZE)
+    {
+        CHO_TRACE_ERROR1 ("NFA_ChoSendHs (): Failed to allocate buffer for %d bytes", ndef_len);
+        GKI_freebuf (p_ndef_buf);
+        return NFA_STATUS_FAILED;
+    }
+
+    msg_size = sizeof (tNFA_CHO_API_SEND_HS) + num_ac_info * sizeof (tNFA_CHO_AC_INFO);
+
+    if ((p_msg = (tNFA_CHO_API_SEND_HS *) GKI_getbuf (msg_size)) != NULL)
+    {
+        p_msg->hdr.event = NFA_CHO_API_SEND_HS_EVT;
+
+        memcpy (p_ndef_buf, p_ndef, ndef_len);
+        p_msg->p_ndef        = p_ndef_buf;
+        p_msg->max_ndef_size = LLCP_POOL_BUF_SIZE;
+        p_msg->cur_ndef_size = ndef_len;
+
+        p_msg->num_ac_info   = num_ac_info;
+        p_msg->p_ac_info     = (tNFA_CHO_AC_INFO *) (p_msg + 1);
+        memcpy (p_msg->p_ac_info, p_ac_info, num_ac_info * sizeof (tNFA_CHO_AC_INFO));
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    else
+    {
+        GKI_freebuf (p_ndef_buf);
+        return (NFA_STATUS_FAILED);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSendSelectError
+**
+** Description      This function is called to send Error record to indicate failure
+**                  to process the most recently received Handover Request message.
+**
+**                  error_reason : NFA_CHO_ERROR_TEMP_MEM
+**                                 NFA_CHO_ERROR_PERM_MEM
+**                                 NFA_CHO_ERROR_CARRIER
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ChoSendSelectError (UINT8  error_reason,
+                                    UINT32 error_data)
+{
+    tNFA_CHO_API_SEL_ERR *p_msg;
+
+    CHO_TRACE_API2 ("NFA_ChoSendSelectError (): error_reason=0x%x, error_data=0x%x",
+                     error_reason, error_data);
+
+    if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED)
+    {
+        CHO_TRACE_ERROR0 ("NFA_ChoSendSelectError (): Not registered");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_CHO_API_SEL_ERR *) GKI_getbuf (sizeof (tNFA_CHO_API_SEL_ERR))) != NULL)
+    {
+        p_msg->hdr.event = NFA_CHO_API_SEL_ERR_EVT;
+
+        p_msg->error_reason = error_reason;
+        p_msg->error_data   = error_data;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSetTraceLevel
+**
+** Description      This function sets the trace level for CHO.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFA_ChoSetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        nfa_cho_cb.trace_level = new_level;
+
+    return (nfa_cho_cb.trace_level);
+}
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function         NFA_ChoSetTestParam
+**
+** Description      This function is called to set test parameters.
+**
+*******************************************************************************/
+void NFA_ChoSetTestParam (UINT8        test_enable,
+                          UINT8        test_version,
+                          UINT16       test_random_number)
+{
+    nfa_cho_cb.test_enabled         = test_enable;
+    nfa_cho_cb.test_version         = test_version;
+    nfa_cho_cb.test_random_number   = test_random_number;
+}
+#endif
diff --git a/src/nfa/cho/nfa_cho_main.c b/src/nfa/cho/nfa_cho_main.c
new file mode 100644
index 0000000..373eced
--- /dev/null
+++ b/src/nfa/cho/nfa_cho_main.c
@@ -0,0 +1,153 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA Connection Handover.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_cho_api.h"
+#include "nfa_cho_int.h"
+#include "trace_api.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_CHO_CB nfa_cho_cb;
+#endif
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static BOOLEAN nfa_cho_evt_hdlr (BT_HDR *p_msg);
+
+/* disable function type */
+static void nfa_cho_sys_disable (void);
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_cho_sys_reg =
+{
+    NULL,
+    nfa_cho_evt_hdlr,
+    nfa_cho_sys_disable,
+    NULL
+};
+
+/*******************************************************************************
+**
+** Function         nfa_cho_timer_cback
+**
+** Description      Process timeout event when timer expires
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_timer_cback (void *p_tle)
+{
+    nfa_cho_sm_execute (NFA_CHO_TIMEOUT_EVT, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_init
+**
+** Description      Initialize NFA Connection Handover
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_init (void)
+{
+    CHO_TRACE_DEBUG0 ("nfa_cho_init ()");
+
+    /* initialize control block */
+    memset (&nfa_cho_cb, 0, sizeof (tNFA_CHO_CB));
+
+    nfa_cho_cb.server_sap = LLCP_INVALID_SAP;
+    nfa_cho_cb.client_sap = LLCP_INVALID_SAP;
+    nfa_cho_cb.remote_sap = LLCP_INVALID_SAP;
+
+    nfa_cho_cb.hs_ndef_type_handle   = NFA_HANDLE_INVALID;
+    nfa_cho_cb.bt_ndef_type_handle   = NFA_HANDLE_INVALID;
+    nfa_cho_cb.wifi_ndef_type_handle = NFA_HANDLE_INVALID;
+
+    nfa_cho_cb.trace_level    = APPL_INITIAL_TRACE_LEVEL;
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register ( NFA_ID_CHO,  &nfa_cho_sys_reg);
+
+    /* initialize timer callback */
+    nfa_cho_cb.timer.p_cback = nfa_cho_timer_cback;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_sys_disable
+**
+** Description      Deregister NFA Connection Handover from NFA SYS/DM
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_sys_disable (void)
+{
+    CHO_TRACE_DEBUG0 ("nfa_cho_sys_disable ()");
+
+    /* clean up if application is still registered */
+    if (nfa_cho_cb.p_cback)
+    {
+        nfa_cho_proc_api_dereg ();
+    }
+
+    /* deregister message handler on NFA SYS */
+    nfa_sys_deregister (NFA_ID_CHO);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_evt_hdlr
+**
+** Description      Processing event for NFA Connection Handover
+**
+**
+** Returns          TRUE if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static BOOLEAN nfa_cho_evt_hdlr (BT_HDR *p_msg)
+{
+    tNFA_CHO_INT_EVENT_DATA *p_data = (tNFA_CHO_INT_EVENT_DATA *) p_msg;
+
+    nfa_cho_sm_execute (p_data->hdr.event, p_data);
+
+    return TRUE;
+}
+
+
diff --git a/src/nfa/cho/nfa_cho_sm.c b/src/nfa/cho/nfa_cho_sm.c
new file mode 100644
index 0000000..d0c8308
--- /dev/null
+++ b/src/nfa/cho/nfa_cho_sm.c
@@ -0,0 +1,1022 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the state implementation file for the NFA Connection Handover.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "llcp_api.h"
+#include "llcp_defs.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_cho_api.h"
+#include "nfa_cho_int.h"
+#include "nfa_mem_co.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+static void nfa_cho_sm_disabled (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data);
+static void nfa_cho_sm_idle (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data);
+static void nfa_cho_sm_w4_cc (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data);
+static void nfa_cho_sm_connected (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data);
+static void nfa_cho_proc_rx_handover_msg (void);
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_cho_state_code (tNFA_CHO_STATE state_code);
+static char *nfa_cho_evt_code (tNFA_CHO_INT_EVT evt_code);
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_cho_sm_llcp_cback
+**
+** Description      Processing event from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_sm_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data)
+{
+    tNFA_CHO_RX_NDEF_STATUS rx_status;
+
+    CHO_TRACE_DEBUG2 ("nfa_cho_sm_llcp_cback (): event:0x%02X, local_sap:0x%02X",
+                       p_data->hdr.event, p_data->hdr.local_sap);
+
+    switch (p_data->hdr.event)
+    {
+    case LLCP_SAP_EVT_DATA_IND:
+        /* check if we received complete Handover Message */
+        rx_status = nfa_cho_reassemble_ho_msg (p_data->data_ind.local_sap,
+                                               p_data->data_ind.remote_sap);
+
+        if (rx_status == NFA_CHO_RX_NDEF_COMPLETE)
+        {
+            nfa_cho_sm_execute (NFA_CHO_RX_HANDOVER_MSG_EVT, NULL);
+        }
+        break;
+
+    case LLCP_SAP_EVT_CONNECT_IND:
+        nfa_cho_sm_execute (NFA_CHO_LLCP_CONNECT_IND_EVT, (tNFA_CHO_INT_EVENT_DATA *) p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONNECT_RESP:
+        nfa_cho_sm_execute (NFA_CHO_LLCP_CONNECT_RESP_EVT, (tNFA_CHO_INT_EVENT_DATA *) p_data);
+        break;
+
+    case LLCP_SAP_EVT_DISCONNECT_IND:
+        nfa_cho_sm_execute (NFA_CHO_LLCP_DISCONNECT_IND_EVT, (tNFA_CHO_INT_EVENT_DATA *) p_data);
+        break;
+
+    case LLCP_SAP_EVT_DISCONNECT_RESP:
+        nfa_cho_sm_execute (NFA_CHO_LLCP_DISCONNECT_RESP_EVT, (tNFA_CHO_INT_EVENT_DATA *) p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONGEST:
+        nfa_cho_sm_execute (NFA_CHO_LLCP_CONGEST_EVT, (tNFA_CHO_INT_EVENT_DATA *) p_data);
+        break;
+
+    case LLCP_SAP_EVT_LINK_STATUS:
+        nfa_cho_sm_execute (NFA_CHO_LLCP_LINK_STATUS_EVT, (tNFA_CHO_INT_EVENT_DATA *) p_data);
+        break;
+
+    default:
+        CHO_TRACE_ERROR1 ("Unknown event:0x%02X", p_data->hdr.event);
+        return;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_sm_disabled
+**
+** Description      Process event in disabled state
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_sm_disabled (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data)
+{
+    tNFA_CHO_EVT_DATA evt_data;
+    UINT16            remote_link_miu;
+
+    switch (event)
+    {
+    case NFA_CHO_API_REG_EVT:
+
+        evt_data.status = nfa_cho_proc_api_reg (p_data);
+
+        if (evt_data.status == NFA_STATUS_OK)
+        {
+            nfa_cho_cb.state = NFA_CHO_ST_IDLE;
+        }
+        p_data->api_reg.p_cback (NFA_CHO_REG_EVT, &evt_data);
+
+        if (evt_data.status == NFA_STATUS_OK)
+        {
+            /* check if LLCP is already activated */
+            LLCP_GetLinkMIU (&nfa_cho_cb.local_link_miu, &remote_link_miu);
+
+            if (nfa_cho_cb.local_link_miu > 0)
+            {
+                nfa_cho_cb.flags |= NFA_CHO_FLAGS_LLCP_ACTIVATED;
+
+                /* Notify application LLCP link activated */
+                evt_data.activated.is_initiator = FALSE;
+                nfa_cho_cb.p_cback (NFA_CHO_ACTIVATED_EVT, &evt_data);
+            }
+        }
+        break;
+
+    default:
+        CHO_TRACE_ERROR0 ("Unknown event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_sm_idle
+**
+** Description      Process event in idle state
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_sm_idle (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data)
+{
+    UINT16                  remote_link_miu;
+    tNFA_CHO_EVT_DATA       evt_data;
+    tLLCP_CONNECTION_PARAMS params;
+
+    switch (event)
+    {
+    case NFA_CHO_API_REG_EVT:
+        evt_data.status = NFA_STATUS_FAILED;
+        p_data->api_reg.p_cback (NFA_CHO_REG_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_API_DEREG_EVT:
+        nfa_cho_proc_api_dereg ();
+        nfa_cho_cb.state = NFA_CHO_ST_DISABLED;
+        break;
+
+    case NFA_CHO_API_CONNECT_EVT:
+        /* if LLCP activated then create data link connection */
+        if (nfa_cho_cb.flags & NFA_CHO_FLAGS_LLCP_ACTIVATED)
+        {
+            if (nfa_cho_create_connection () == NFA_STATUS_OK)
+            {
+                /* waiting for connection confirm */
+                nfa_cho_cb.state = NFA_CHO_ST_W4_CC;
+            }
+            else
+            {
+                evt_data.disconnected.reason = NFA_CHO_DISC_REASON_CONNECTION_FAIL;
+                nfa_cho_cb.p_cback (NFA_CHO_DISCONNECTED_EVT, &evt_data);
+            }
+        }
+        else
+        {
+            evt_data.disconnected.reason = NFA_CHO_DISC_REASON_LINK_DEACTIVATED;
+            nfa_cho_cb.p_cback (NFA_CHO_DISCONNECTED_EVT, &evt_data);
+        }
+        break;
+
+    case NFA_CHO_API_DISCONNECT_EVT:
+        /* Nothing to disconnect */
+        nfa_cho_process_disconnection (NFA_CHO_DISC_REASON_API_REQUEST);
+        break;
+
+    case NFA_CHO_LLCP_CONNECT_IND_EVT:
+
+        /* accept connection request */
+        params.miu = (UINT16) (nfa_cho_cb.local_link_miu >= NFA_CHO_MIU ? NFA_CHO_MIU : nfa_cho_cb.local_link_miu);
+        params.rw  = NFA_CHO_RW;
+        params.sn[0] = 0;
+
+        LLCP_ConnectCfm (p_data->llcp_cback_data.connect_ind.local_sap,
+                         p_data->llcp_cback_data.connect_ind.remote_sap,
+                         &params);
+
+        nfa_cho_cb.remote_miu = p_data->llcp_cback_data.connect_ind.miu;
+        nfa_cho_cb.remote_sap = p_data->llcp_cback_data.connect_ind.remote_sap;
+        nfa_cho_cb.local_sap  = p_data->llcp_cback_data.connect_ind.local_sap;
+
+        nfa_cho_cb.substate  = NFA_CHO_SUBSTATE_W4_REMOTE_HR;
+        nfa_cho_cb.state     = NFA_CHO_ST_CONNECTED;
+        nfa_cho_cb.congested = FALSE;
+
+        evt_data.connected.initial_role = NFA_CHO_ROLE_SELECTOR;
+        nfa_cho_cb.p_cback (NFA_CHO_CONNECTED_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_LLCP_LINK_STATUS_EVT:
+        /*
+        **  LLCP sends NFA_CHO_LLCP_DISCONNECT_IND_EVT for all data link connection
+        **  before sending NFA_CHO_LLCP_LINK_STATUS_EVT for deactivation.
+        **  This event can be received only in this state.
+        */
+
+        if (p_data->llcp_cback_data.link_status.is_activated == TRUE)
+        {
+            nfa_cho_cb.flags |= NFA_CHO_FLAGS_LLCP_ACTIVATED;
+
+            /* store local link MIU to decide MIU of data link connection later */
+            LLCP_GetLinkMIU (&nfa_cho_cb.local_link_miu, &remote_link_miu);
+
+            /* Notify application LLCP link activated */
+            evt_data.activated.is_initiator = p_data->llcp_cback_data.link_status.is_initiator;
+            nfa_cho_cb.p_cback (NFA_CHO_ACTIVATED_EVT, &evt_data);
+        }
+        else
+        {
+            /* the other flags had been cleared by NFA_CHO_LLCP_DISCONNECT_IND_EVT */
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_LLCP_ACTIVATED;
+
+            /* Notify application LLCP link deactivated */
+            evt_data.status = NFA_STATUS_OK;
+            nfa_cho_cb.p_cback (NFA_CHO_DEACTIVATED_EVT, &evt_data);
+        }
+        break;
+
+    case NFA_CHO_API_SEND_HR_EVT:
+        GKI_freebuf (p_data->api_send_hr.p_ndef);
+        break;
+
+    case NFA_CHO_API_SEND_HS_EVT:
+        GKI_freebuf (p_data->api_send_hs.p_ndef);
+        break;
+
+    case NFA_CHO_NDEF_TYPE_HANDLER_EVT:
+        nfa_cho_proc_ndef_type_handler_evt (p_data);
+        break;
+
+    default:
+        CHO_TRACE_ERROR0 ("Unknown event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_sm_w4_cc
+**
+** Description      Process event in waiting for connection confirm state
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_sm_w4_cc (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data)
+{
+    tNFA_CHO_EVT_DATA       evt_data;
+    tLLCP_CONNECTION_PARAMS params;
+
+    switch (event)
+    {
+    case NFA_CHO_API_REG_EVT:
+        evt_data.status = NFA_STATUS_FAILED;
+        p_data->api_reg.p_cback (NFA_CHO_REG_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_API_DEREG_EVT:
+        nfa_cho_proc_api_dereg ();
+        nfa_cho_cb.state = NFA_CHO_ST_DISABLED;
+        break;
+
+    case NFA_CHO_API_CONNECT_EVT:
+        evt_data.disconnected.reason = NFA_CHO_DISC_REASON_ALEADY_CONNECTED;
+        nfa_cho_cb.p_cback (NFA_CHO_DISCONNECTED_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_API_DISCONNECT_EVT:
+        /* disconnect collision connection accepted by local device */
+        if (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+        {
+            LLCP_DisconnectReq (nfa_cho_cb.collision_local_sap,
+                                nfa_cho_cb.collision_remote_sap,
+                                FALSE);
+
+            /* clear collision flag */
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+        }
+
+        nfa_cho_cb.state = NFA_CHO_ST_IDLE;
+
+        /* we cannot send DISC because we don't know remote SAP */
+        nfa_cho_process_disconnection (NFA_CHO_DISC_REASON_API_REQUEST);
+        break;
+
+    case NFA_CHO_LLCP_CONNECT_RESP_EVT:
+        /* peer accepted connection request */
+        nfa_cho_cb.state     = NFA_CHO_ST_CONNECTED;
+        nfa_cho_cb.substate  = NFA_CHO_SUBSTATE_W4_LOCAL_HR;
+        nfa_cho_cb.congested = FALSE;
+
+        /* store data link connection parameters */
+        nfa_cho_cb.remote_miu = p_data->llcp_cback_data.connect_resp.miu;
+        nfa_cho_cb.remote_sap = p_data->llcp_cback_data.connect_resp.remote_sap;
+        nfa_cho_cb.local_sap  = nfa_cho_cb.client_sap;
+
+        evt_data.connected.initial_role = NFA_CHO_ROLE_REQUESTER;
+        nfa_cho_cb.p_cback (NFA_CHO_CONNECTED_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_LLCP_CONNECT_IND_EVT:
+        /* if already collision of connection */
+        if (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+        {
+            LLCP_ConnectReject (p_data->llcp_cback_data.connect_ind.local_sap,
+                                p_data->llcp_cback_data.connect_ind.remote_sap,
+                                LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
+        }
+        else
+        {
+            /*
+            ** accept connection request and set collision flag
+            ** wait for accepting connection request from peer or Hr message
+            */
+            params.miu = (UINT16) (nfa_cho_cb.local_link_miu >= NFA_CHO_MIU ? NFA_CHO_MIU : nfa_cho_cb.local_link_miu);
+            params.rw  = NFA_CHO_RW;
+            params.sn[0] = 0;
+
+            LLCP_ConnectCfm (p_data->llcp_cback_data.connect_ind.local_sap,
+                             p_data->llcp_cback_data.connect_ind.remote_sap,
+                             &params);
+
+            nfa_cho_cb.flags |= NFA_CHO_FLAGS_CONN_COLLISION;
+
+            nfa_cho_cb.collision_remote_miu = p_data->llcp_cback_data.connect_ind.miu;
+            nfa_cho_cb.collision_remote_sap = p_data->llcp_cback_data.connect_ind.remote_sap;
+            nfa_cho_cb.collision_local_sap  = p_data->llcp_cback_data.connect_ind.local_sap;
+            nfa_cho_cb.collision_congested  = FALSE;
+        }
+        break;
+
+    case NFA_CHO_RX_HANDOVER_MSG_EVT:
+        /* peer device sent handover message before accepting connection */
+        /* clear collision flag */
+        nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+
+        nfa_cho_cb.remote_miu = nfa_cho_cb.collision_remote_miu;
+        nfa_cho_cb.remote_sap = nfa_cho_cb.collision_remote_sap;
+        nfa_cho_cb.local_sap  = nfa_cho_cb.collision_local_sap;
+        nfa_cho_cb.congested  = nfa_cho_cb.collision_congested;
+
+        nfa_cho_cb.substate  = NFA_CHO_SUBSTATE_W4_REMOTE_HR;
+        nfa_cho_cb.state     = NFA_CHO_ST_CONNECTED;
+
+        evt_data.connected.initial_role = NFA_CHO_ROLE_SELECTOR;
+        nfa_cho_cb.p_cback (NFA_CHO_CONNECTED_EVT, &evt_data);
+
+        /* process handover message in nfa_cho_cb.p_rx_ndef_msg */
+        nfa_cho_proc_rx_handover_msg ();
+        break;
+
+    case NFA_CHO_LLCP_DISCONNECT_RESP_EVT:
+        /*
+        ** if peer rejected our connection request or there is no handover service in peer
+        ** but we already accepted connection from peer
+        */
+        if (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+        {
+            /* clear collision flag */
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+
+            nfa_cho_cb.remote_miu = nfa_cho_cb.collision_remote_miu;
+            nfa_cho_cb.remote_sap = nfa_cho_cb.collision_remote_sap;
+            nfa_cho_cb.local_sap  = nfa_cho_cb.collision_local_sap;
+            nfa_cho_cb.congested  = nfa_cho_cb.collision_congested;
+
+            nfa_cho_cb.substate  = NFA_CHO_SUBSTATE_W4_REMOTE_HR;
+            nfa_cho_cb.state     = NFA_CHO_ST_CONNECTED;
+
+            evt_data.connected.initial_role = NFA_CHO_ROLE_SELECTOR;
+            nfa_cho_cb.p_cback (NFA_CHO_CONNECTED_EVT, &evt_data);
+        }
+        else
+        {
+            nfa_cho_cb.state = NFA_CHO_ST_IDLE;
+            nfa_cho_process_disconnection (NFA_CHO_DISC_REASON_CONNECTION_FAIL);
+        }
+        break;
+
+    case NFA_CHO_LLCP_DISCONNECT_IND_EVT:
+        /* if peer disconnects collision connection */
+        if (  (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+            &&(p_data->llcp_cback_data.disconnect_ind.local_sap == nfa_cho_cb.collision_local_sap)
+            &&(p_data->llcp_cback_data.disconnect_ind.remote_sap == nfa_cho_cb.collision_remote_sap)  )
+        {
+            /* clear collision flag */
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+        }
+        else    /* Link failure before peer accepts or rejects connection request */
+        {
+            nfa_cho_cb.state = NFA_CHO_ST_IDLE;
+            nfa_cho_process_disconnection (NFA_CHO_DISC_REASON_CONNECTION_FAIL);
+        }
+        break;
+
+    case NFA_CHO_LLCP_CONGEST_EVT:
+        /* if collision connection is congested */
+        if (  (p_data->llcp_cback_data.congest.link_type == LLCP_LINK_TYPE_DATA_LINK_CONNECTION)
+            &&(nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION))
+        {
+            nfa_cho_cb.collision_congested = p_data->llcp_cback_data.congest.is_congested;
+        }
+        break;
+
+    case NFA_CHO_API_SEND_HR_EVT:
+        GKI_freebuf (p_data->api_send_hr.p_ndef);
+        break;
+
+    case NFA_CHO_API_SEND_HS_EVT:
+        GKI_freebuf (p_data->api_send_hs.p_ndef);
+        break;
+
+    case NFA_CHO_NDEF_TYPE_HANDLER_EVT:
+        nfa_cho_proc_ndef_type_handler_evt (p_data);
+        break;
+
+    default:
+        CHO_TRACE_ERROR0 ("Unknown event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_sm_connected
+**
+** Description      Process event in connected state
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_sm_connected (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data)
+{
+    tNFA_CHO_EVT_DATA evt_data;
+    tNFA_STATUS       status;
+
+    switch (event)
+    {
+    case NFA_CHO_API_REG_EVT:
+        evt_data.status = NFA_STATUS_FAILED;
+        p_data->api_reg.p_cback (NFA_CHO_REG_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_API_DEREG_EVT:
+        nfa_cho_proc_api_dereg ();
+        nfa_cho_cb.state = NFA_CHO_ST_DISABLED;
+        break;
+
+    case NFA_CHO_API_CONNECT_EVT:
+        /* it could be race condition, let app know outgoing connection failed */
+        evt_data.disconnected.reason = NFA_CHO_DISC_REASON_ALEADY_CONNECTED;
+        nfa_cho_cb.p_cback (NFA_CHO_DISCONNECTED_EVT, &evt_data);
+        break;
+
+    case NFA_CHO_API_DISCONNECT_EVT:
+        /* disconnect collision connection accepted by local device */
+        if (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+        {
+            LLCP_DisconnectReq (nfa_cho_cb.collision_local_sap,
+                                nfa_cho_cb.collision_remote_sap,
+                                FALSE);
+
+            /* clear collision flag */
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+        }
+
+        LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                            nfa_cho_cb.remote_sap,
+                            FALSE);
+
+        /* store disconnect reason */
+        nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_API_REQUEST;
+        break;
+
+    case NFA_CHO_API_SEND_HR_EVT:
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_LOCAL_HR)
+        {
+            /* Send Handover Request Message */
+            status = nfa_cho_send_hr (&p_data->api_send_hr);
+
+            if (status == NFA_STATUS_OK)
+            {
+                nfa_cho_cb.substate = NFA_CHO_SUBSTATE_W4_REMOTE_HS;
+                /* start timer for Handover Select Message */
+                nfa_sys_start_timer (&nfa_cho_cb.timer, 0, NFA_CHO_TIMEOUT_FOR_HS);
+            }
+            else
+            {
+                CHO_TRACE_ERROR0 ("NFA CHO failed to send Hr");
+                nfa_cho_notify_tx_fail_evt (status);
+            }
+        }
+        else
+        {
+            CHO_TRACE_ERROR0 ("NFA CHO got unexpected NFA_CHO_API_SEND_HR_EVT");
+            nfa_cho_notify_tx_fail_evt (NFA_STATUS_SEMANTIC_ERROR);
+        }
+        GKI_freebuf (p_data->api_send_hr.p_ndef);
+        break;
+
+    case NFA_CHO_API_SEND_HS_EVT:
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_LOCAL_HS)
+        {
+            /* send Handover Select Message */
+            status = nfa_cho_send_hs (&p_data->api_send_hs);
+            if (status == NFA_STATUS_OK)
+            {
+                nfa_cho_cb.substate = NFA_CHO_SUBSTATE_W4_REMOTE_HR;
+            }
+            else
+            {
+                CHO_TRACE_ERROR0 ("NFA CHO failed to send Hs");
+                nfa_cho_notify_tx_fail_evt (status);
+            }
+        }
+        else
+        {
+            CHO_TRACE_ERROR0 ("NFA CHO got unexpected NFA_CHO_API_SEND_HS_EVT");
+            nfa_cho_notify_tx_fail_evt (NFA_STATUS_SEMANTIC_ERROR);
+        }
+        GKI_freebuf (p_data->api_send_hs.p_ndef);
+        break;
+
+    case NFA_CHO_API_SEL_ERR_EVT:
+        /* application detected error */
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_LOCAL_HS)
+        {
+            /* Send Handover Select Error record */
+            status = nfa_cho_send_hs_error (p_data->api_sel_err.error_reason,
+                                            p_data->api_sel_err.error_data);
+            if (status == NFA_STATUS_OK)
+            {
+                nfa_cho_cb.substate = NFA_CHO_SUBSTATE_W4_REMOTE_HR;
+            }
+            else
+            {
+                CHO_TRACE_ERROR0 ("Failed to send Hs Error record");
+                nfa_cho_notify_tx_fail_evt (status);
+            }
+        }
+        else
+        {
+            CHO_TRACE_ERROR0 ("NFA CHO got unexpected NFA_CHO_API_SEL_ERR_EVT");
+            nfa_cho_notify_tx_fail_evt (NFA_STATUS_SEMANTIC_ERROR);
+        }
+        break;
+
+    case NFA_CHO_LLCP_CONNECT_RESP_EVT:
+        /* peer accepted connection after we accepted and received Hr */
+        /* disconnect data link connection created by local device    */
+        LLCP_DisconnectReq (p_data->llcp_cback_data.connect_resp.local_sap,
+                            p_data->llcp_cback_data.connect_resp.remote_sap,
+                            FALSE);
+        break;
+
+    case NFA_CHO_LLCP_CONNECT_IND_EVT:
+        LLCP_ConnectReject (p_data->llcp_cback_data.connect_ind.local_sap,
+                            p_data->llcp_cback_data.connect_ind.remote_sap,
+                            LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
+        break;
+
+    case NFA_CHO_RX_HANDOVER_MSG_EVT:
+        /* process handover message in nfa_cho_cb.p_rx_ndef_msg */
+        nfa_cho_proc_rx_handover_msg ();
+        break;
+
+    case NFA_CHO_LLCP_DISCONNECT_IND_EVT:
+        if (  (p_data->llcp_cback_data.disconnect_ind.local_sap  == nfa_cho_cb.local_sap)
+            &&(p_data->llcp_cback_data.disconnect_ind.remote_sap == nfa_cho_cb.remote_sap)  )
+        {
+            nfa_cho_cb.state = NFA_CHO_ST_IDLE;
+            nfa_cho_process_disconnection (NFA_CHO_DISC_REASON_PEER_REQUEST);
+        }
+        else  /* if disconnection of collision conneciton */
+        {
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+        }
+        break;
+
+    case NFA_CHO_LLCP_DISCONNECT_RESP_EVT:
+        if (  (p_data->llcp_cback_data.disconnect_ind.local_sap  == nfa_cho_cb.local_sap)
+            &&(p_data->llcp_cback_data.disconnect_ind.remote_sap == nfa_cho_cb.remote_sap)  )
+        {
+            nfa_cho_cb.state = NFA_CHO_ST_IDLE;
+            nfa_cho_process_disconnection (nfa_cho_cb.disc_reason);
+        }
+        else  /* if disconnection of collision conneciton */
+        {
+            nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+        }
+        break;
+
+    case NFA_CHO_LLCP_CONGEST_EVT:
+        /* if data link connection is congested */
+        if ( (p_data->llcp_cback_data.congest.link_type  == LLCP_LINK_TYPE_DATA_LINK_CONNECTION)
+           &&(p_data->llcp_cback_data.congest.local_sap  == nfa_cho_cb.local_sap)
+           &&(p_data->llcp_cback_data.congest.remote_sap == nfa_cho_cb.remote_sap)  )
+        {
+            nfa_cho_cb.congested = p_data->llcp_cback_data.congest.is_congested;
+
+            if (!nfa_cho_cb.congested)
+            {
+                /* send remaining message if any */
+                if (  (nfa_cho_cb.p_tx_ndef_msg)
+                    &&(nfa_cho_cb.tx_ndef_sent_size < nfa_cho_cb.tx_ndef_cur_size)  )
+                {
+                    nfa_cho_send_handover_msg ();
+                }
+            }
+        }
+        break;
+
+    case NFA_CHO_TIMEOUT_EVT:
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HS)
+        {
+            CHO_TRACE_ERROR0 ("Failed to receive Hs message");
+        }
+        else if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR)
+        {
+            /* we didn't get complete Hr, don't need to notify application */
+            CHO_TRACE_ERROR0 ("Failed to receive Hr message");
+        }
+
+        /* store disconnect reason and disconnect */
+        nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_TIMEOUT;
+        LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                            nfa_cho_cb.remote_sap,
+                            FALSE);
+        break;
+
+    case NFA_CHO_NDEF_TYPE_HANDLER_EVT:
+        nfa_cho_proc_ndef_type_handler_evt (p_data);
+        break;
+
+    default:
+        CHO_TRACE_ERROR0 ("Unknown event");
+        break;
+    }
+}
+/*******************************************************************************
+**
+** Function         nfa_cho_sm_execute
+**
+** Description      Process event in state machine
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_sm_execute (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_data)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+    CHO_TRACE_DEBUG2 ("nfa_cho_sm_execute (): State[%s], Event[%s]",
+                       nfa_cho_state_code (nfa_cho_cb.state),
+                       nfa_cho_evt_code (event));
+#else
+    CHO_TRACE_DEBUG2 ("nfa_cho_sm_execute (): State[%d], Event[%d]",
+                       nfa_cho_cb.state, event);
+#endif
+
+
+    switch (nfa_cho_cb.state)
+    {
+    case NFA_CHO_ST_DISABLED:
+        nfa_cho_sm_disabled (event, p_data);
+        break;
+
+    case NFA_CHO_ST_IDLE:
+        nfa_cho_sm_idle (event, p_data);
+        break;
+
+    case NFA_CHO_ST_W4_CC:
+        nfa_cho_sm_w4_cc (event, p_data);
+        break;
+
+    case NFA_CHO_ST_CONNECTED:
+        nfa_cho_sm_connected (event, p_data);
+        break;
+
+    default:
+        CHO_TRACE_ERROR0 ("Unknown state");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_resolve_collision
+**
+** Description      Resolve collision by random number in Hr
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_resolve_collision (BOOLEAN *p_free_hr)
+{
+    tNFA_CHO_ROLE_TYPE role;
+    tNFA_STATUS        status;
+
+    /* resolve collistion by random number */
+    role = nfa_cho_get_local_device_role (nfa_cho_cb.rx_ndef_cur_size,
+                                          nfa_cho_cb.p_rx_ndef_msg);
+
+    /* if local device becomes selector */
+    if (role == NFA_CHO_ROLE_SELECTOR)
+    {
+        /* peer device is winner so clean up any collision */
+        if (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+        {
+            /* disconnect data link connection created by local device */
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                                nfa_cho_cb.remote_sap,
+                                FALSE);
+
+            nfa_cho_cb.remote_miu = nfa_cho_cb.collision_remote_miu;
+            nfa_cho_cb.remote_sap = nfa_cho_cb.collision_remote_sap;
+            nfa_cho_cb.local_sap  = nfa_cho_cb.collision_local_sap;
+            nfa_cho_cb.congested  = nfa_cho_cb.collision_congested;
+        }
+
+        nfa_cho_cb.substate = NFA_CHO_SUBSTATE_W4_LOCAL_HS;
+
+        nfa_cho_proc_hr (nfa_cho_cb.rx_ndef_cur_size,
+                         nfa_cho_cb.p_rx_ndef_msg);
+
+        *p_free_hr = TRUE;
+    }
+    /* if both random numbers are equal */
+    else if (role == NFA_CHO_ROLE_UNDECIDED)
+    {
+        /* send Hr with new random number */
+        if (nfa_cho_cb.p_tx_ndef_msg)
+        {
+            status = nfa_cho_update_random_number (nfa_cho_cb.p_tx_ndef_msg);
+
+            if (status == NFA_STATUS_OK)
+            {
+                nfa_cho_cb.tx_ndef_sent_size = 0;
+                status = nfa_cho_send_handover_msg ();
+            }
+        }
+        else
+        {
+            status = NFA_STATUS_FAILED;
+        }
+
+        if (status == NFA_STATUS_FAILED)
+        {
+            CHO_TRACE_ERROR0 ("Failed to send Hr record with new random number");
+
+            nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INTERNAL_ERROR;
+
+            /* disconnect and notify application */
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                                nfa_cho_cb.remote_sap,
+                                FALSE);
+        }
+        else
+        {
+            /* restart timer */
+            nfa_sys_start_timer (&nfa_cho_cb.timer, 0, NFA_CHO_TIMEOUT_FOR_HS);
+
+            /* Don't free previous tx NDEF message because we are reusing it */
+            *p_free_hr = FALSE;
+        }
+    }
+    else /* if (role == NFA_CHO_ROLE_REQUESTER) */
+    {
+        /* wait for "Hs" record */
+        *p_free_hr = TRUE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_check_disconnect_collision
+**
+** Description      Disconnect any collision connection
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_check_disconnect_collision (void)
+{
+    if (nfa_cho_cb.flags & NFA_CHO_FLAGS_CONN_COLLISION)
+    {
+        /* disconnect collision connection */
+        LLCP_DisconnectReq (nfa_cho_cb.collision_local_sap,
+                            nfa_cho_cb.collision_remote_sap,
+                            FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_rx_handover_msg
+**
+** Description      Process received Handover Message
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_proc_rx_handover_msg (void)
+{
+    tNFA_CHO_MSG_TYPE msg_type;
+    BOOLEAN           free_tx_ndef_msg = TRUE;
+
+    /* get message type before processing to check collision */
+    msg_type = nfa_cho_get_msg_type (nfa_cho_cb.rx_ndef_cur_size,
+                                     nfa_cho_cb.p_rx_ndef_msg);
+
+    if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HS)
+    {
+        /* if we sent "Hr" but received "Hr", collision */
+        if (msg_type == NFA_CHO_MSG_HR)
+        {
+            nfa_cho_resolve_collision (&free_tx_ndef_msg);
+        }
+        else if (msg_type == NFA_CHO_MSG_HS)
+        {
+            /* parse and report application */
+            nfa_cho_proc_hs (nfa_cho_cb.rx_ndef_cur_size,
+                             nfa_cho_cb.p_rx_ndef_msg);
+
+            nfa_cho_cb.substate = NFA_CHO_SUBSTATE_W4_LOCAL_HR;
+        }
+        else
+        {
+            CHO_TRACE_ERROR0 ("nfa_cho_proc_rx_handover_msg (): Unknown Message Type");
+
+            nfa_cho_check_disconnect_collision ();
+
+            nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_UNKNOWN_MSG;
+
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                                nfa_cho_cb.remote_sap,
+                                FALSE);
+        }
+    }
+    else if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR)
+    {
+        if (msg_type == NFA_CHO_MSG_HR)
+        {
+            /* parse and notify NFA_CHO_REQ_EVT to application */
+            nfa_cho_proc_hr (nfa_cho_cb.rx_ndef_cur_size,
+                             nfa_cho_cb.p_rx_ndef_msg);
+
+            /* In case of parsing error, let peer got timeout (1 sec) */
+
+            /* wait for application selection */
+            nfa_cho_cb.substate = NFA_CHO_SUBSTATE_W4_LOCAL_HS;
+        }
+        else
+        {
+            CHO_TRACE_ERROR0 ("nfa_cho_proc_rx_handover_msg (): Expecting Handover Request");
+
+            nfa_cho_check_disconnect_collision ();
+
+            nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_SEMANTIC_ERROR;
+
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                                nfa_cho_cb.remote_sap,
+                                FALSE);
+        }
+    }
+    else
+    {
+        CHO_TRACE_ERROR1 ("nfa_cho_proc_rx_handover_msg (): Unexpected data in substate (0x%x)", nfa_cho_cb.substate);
+
+        nfa_cho_check_disconnect_collision ();
+
+        nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_SEMANTIC_ERROR;
+
+        LLCP_DisconnectReq (nfa_cho_cb.local_sap,
+                            nfa_cho_cb.remote_sap,
+                            FALSE);
+    }
+
+    if ((free_tx_ndef_msg) && (nfa_cho_cb.p_tx_ndef_msg))
+    {
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+    }
+
+    /* processing rx message is done, free buffer for rx handover message */
+    if (nfa_cho_cb.p_rx_ndef_msg)
+    {
+        GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg);
+        nfa_cho_cb.p_rx_ndef_msg = NULL;
+    }
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_cho_state_code
+**
+** Description
+**
+** Returns          string of state
+**
+*******************************************************************************/
+static char *nfa_cho_state_code (tNFA_CHO_STATE state_code)
+{
+    switch (state_code)
+    {
+    case NFA_CHO_ST_DISABLED:
+        return "DISABLED";
+    case NFA_CHO_ST_IDLE:
+        return "IDLE";
+    case NFA_CHO_ST_CONNECTED:
+        return "CONNECTED";
+    default:
+        return "unknown state";
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_evt_code
+**
+** Description
+**
+** Returns          string of event
+**
+*******************************************************************************/
+char *nfa_cho_evt_code (tNFA_CHO_INT_EVT evt_code)
+{
+    switch (evt_code)
+    {
+    case NFA_CHO_API_REG_EVT:
+        return "API_REG";
+    case NFA_CHO_API_DEREG_EVT:
+        return "API_DEREG";
+    case NFA_CHO_API_CONNECT_EVT:
+        return "API_CONNECT";
+    case NFA_CHO_API_DISCONNECT_EVT:
+        return "API_DISCONNECT";
+    case NFA_CHO_API_SEND_HR_EVT:
+        return "API_SEND_HR";
+    case NFA_CHO_API_SEND_HS_EVT:
+        return "API_SEND_HS";
+    case NFA_CHO_API_SEL_ERR_EVT:
+        return "API_SEL_ERR";
+
+    case NFA_CHO_RX_HANDOVER_MSG_EVT:
+        return "RX_HANDOVER_MSG";
+
+    case NFA_CHO_LLCP_CONNECT_IND_EVT:
+        return "LLCP_CONNECT_IND";
+    case NFA_CHO_LLCP_CONNECT_RESP_EVT:
+        return "LLCP_CONNECT_RESP";
+    case NFA_CHO_LLCP_DISCONNECT_IND_EVT:
+        return "LLCP_DISCONNECT_IND";
+    case NFA_CHO_LLCP_DISCONNECT_RESP_EVT:
+        return "LLCP_DISCONNECT_RESP";
+    case NFA_CHO_LLCP_CONGEST_EVT:
+        return "LLCP_CONGEST";
+    case NFA_CHO_LLCP_LINK_STATUS_EVT:
+        return "LLCP_LINK_STATUS";
+
+    case NFA_CHO_NDEF_TYPE_HANDLER_EVT:
+        return "NDEF_TYPE_HANDLER";
+    case NFA_CHO_TIMEOUT_EVT:
+        return "TIMEOUT";
+
+    default:
+        return "unknown event";
+    }
+}
+#endif  /* Debug Functions */
diff --git a/src/nfa/cho/nfa_cho_util.c b/src/nfa/cho/nfa_cho_util.c
new file mode 100644
index 0000000..90eb947
--- /dev/null
+++ b/src/nfa/cho/nfa_cho_util.c
@@ -0,0 +1,2005 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the utilities implementation file for the NFA Connection
+ *  Handover.
+ *
+ ******************************************************************************/
+
+#include "string.h"
+#include "nfa_sys.h"
+#include "llcp_api.h"
+#include "llcp_defs.h"
+#include "nfa_p2p_int.h"
+#include "nfa_cho_api.h"
+#include "nfa_cho_int.h"
+#include "trace_api.h"
+#include "nfa_mem_co.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+/* Handover server name on LLCP */
+static char *p_cho_service_name = "urn:nfc:sn:handover";
+
+/* Handover Request Record Type */
+static UINT8 hr_rec_type[HR_REC_TYPE_LEN] = { 0x48, 0x72 }; /* "Hr" */
+
+/* Handover Select Record Type */
+static UINT8 hs_rec_type[HS_REC_TYPE_LEN] = { 0x48, 0x73 }; /* "Hs" */
+
+/* Handover Carrier recrod Type */
+/* static UINT8 hc_rec_type[HC_REC_TYPE_LEN] = { 0x48, 0x63 }; "Hc" */
+
+/* Collision Resolution Record Type */
+static UINT8 cr_rec_type[CR_REC_TYPE_LEN] = { 0x63, 0x72 }; /* "cr" */
+
+/* Alternative Carrier Record Type */
+static UINT8 ac_rec_type[AC_REC_TYPE_LEN] = { 0x61, 0x63 }; /* "ac" */
+
+/* Error Record Type */
+static UINT8 err_rec_type[ERR_REC_TYPE_LEN] = { 0x65, 0x72, 0x72 }; /* "err" */
+
+/* Bluetooth OOB Data Type */
+static UINT8 *p_bt_oob_rec_type = (UINT8 *) "application/vnd.bluetooth.ep.oob";
+
+/* WiFi Data Type */
+static UINT8 *p_wifi_rec_type = (UINT8 *) "application/vnd.wfa.wsc";
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+static void nfa_cho_ndef_cback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *p_data);
+
+/*******************************************************************************
+**
+** Function         nfa_cho_ndef_cback
+**
+** Description      callback function from NDEF handler
+**                  Post NDEF handler callback event to NFA Connection Handover module
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_cho_ndef_cback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *p_data)
+{
+    tNFA_CHO_NDEF_TYPE_HDLR_EVT *p_msg;
+    tNFA_CHO_MSG_TYPE           msg_type;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_ndef_cback () event=%d", event);
+
+    if ((p_msg = (tNFA_CHO_NDEF_TYPE_HDLR_EVT *) GKI_getbuf (sizeof (tNFA_CHO_NDEF_TYPE_HDLR_EVT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_CHO_NDEF_TYPE_HANDLER_EVT;
+
+        /* copy NDEF handler callback event and data */
+        p_msg->event = event;
+        memcpy (&(p_msg->data), p_data, sizeof (tNFA_NDEF_EVT_DATA));
+
+        /* if it has NDEF message */
+        if (event == NFA_NDEF_DATA_EVT)
+        {
+            if (p_data->ndef_data.ndef_type_handle == nfa_cho_cb.bt_ndef_type_handle )
+            {
+                msg_type = nfa_cho_get_msg_type (p_data->ndef_data.len,
+                                                 p_data->ndef_data.p_data);
+                if (msg_type != NFA_CHO_MSG_BT_OOB)
+                {
+                    /* This is not simplified BT OOB Message. It contains BT OOB Message. */
+                    GKI_freebuf (p_msg);
+                    return;
+                }
+            }
+            else if (p_data->ndef_data.ndef_type_handle == nfa_cho_cb.wifi_ndef_type_handle )
+            {
+                msg_type = nfa_cho_get_msg_type (p_data->ndef_data.len,
+                                                 p_data->ndef_data.p_data);
+                if (msg_type != NFA_CHO_MSG_WIFI)
+                {
+                    /* This is not simplified WiFi Message. It contains WiFi Message. */
+                    GKI_freebuf (p_msg);
+                    return;
+                }
+            }
+
+            /*
+            ** NDEF message could be bigger than max GKI buffer
+            ** so allocate memory from platform.
+            */
+            p_msg->data.ndef_data.p_data = (UINT8 *) nfa_mem_co_alloc (p_msg->data.ndef_data.len);
+
+            if (p_msg->data.ndef_data.p_data)
+            {
+                memcpy (p_msg->data.ndef_data.p_data,
+                        p_data->ndef_data.p_data,
+                        p_msg->data.ndef_data.len);
+            }
+            else
+            {
+                CHO_TRACE_ERROR1 ("Failed nfa_mem_co_alloc () for %d bytes", p_msg->data.ndef_data.len);
+                GKI_freebuf (p_msg);
+                return;
+            }
+        }
+
+        nfa_sys_sendmsg (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_ndef_type_handler_evt
+**
+** Description      Process events (registration and NDEF data) from NFA NDEF
+**                  Type Handler
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+void nfa_cho_proc_ndef_type_handler_evt (tNFA_CHO_INT_EVENT_DATA *p_evt_data)
+{
+    tNFA_CHO_MSG_TYPE msg_type;
+
+    if (p_evt_data->ndef_type_hdlr.event == NFA_NDEF_REGISTER_EVT)
+    {
+        if (p_evt_data->ndef_type_hdlr.data.ndef_reg.status == NFA_STATUS_OK)
+        {
+            /* store handle for deregistration */
+            if (nfa_cho_cb.hs_ndef_type_handle == NFA_HANDLE_INVALID)
+            {
+                nfa_cho_cb.hs_ndef_type_handle = p_evt_data->ndef_type_hdlr.data.ndef_reg.ndef_type_handle;
+            }
+            else if (nfa_cho_cb.bt_ndef_type_handle == NFA_HANDLE_INVALID)
+            {
+                nfa_cho_cb.bt_ndef_type_handle = p_evt_data->ndef_type_hdlr.data.ndef_reg.ndef_type_handle;
+            }
+            else if (nfa_cho_cb.wifi_ndef_type_handle == NFA_HANDLE_INVALID)
+            {
+                nfa_cho_cb.wifi_ndef_type_handle = p_evt_data->ndef_type_hdlr.data.ndef_reg.ndef_type_handle;
+            }
+        }
+    }
+    else if (p_evt_data->ndef_type_hdlr.event == NFA_NDEF_DATA_EVT)
+    {
+        /* if negotiated handover is on going, then ignore static handover */
+        if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED)
+        {
+#if (BT_TRACE_PROTOCOL == TRUE)
+            DispNDEFMsg (p_evt_data->ndef_type_hdlr.data.ndef_data.p_data,
+                         p_evt_data->ndef_type_hdlr.data.ndef_data.len, TRUE);
+#endif
+            msg_type = nfa_cho_get_msg_type (p_evt_data->ndef_type_hdlr.data.ndef_data.len,
+                                             p_evt_data->ndef_type_hdlr.data.ndef_data.p_data);
+
+            if (msg_type == NFA_CHO_MSG_HS)
+            {
+                nfa_cho_proc_hs (p_evt_data->ndef_type_hdlr.data.ndef_data.len,
+                                 p_evt_data->ndef_type_hdlr.data.ndef_data.p_data);
+            }
+            else if (  (msg_type == NFA_CHO_MSG_BT_OOB)
+                     ||(msg_type == NFA_CHO_MSG_WIFI)  )
+            {
+                /* simplified BT OOB/Wifi Message */
+                nfa_cho_proc_simplified_format (p_evt_data->ndef_type_hdlr.data.ndef_data.len,
+                                                p_evt_data->ndef_type_hdlr.data.ndef_data.p_data);
+            }
+            else
+            {
+                CHO_TRACE_ERROR0 ("Unexpected CHO Message Type");
+            }
+        }
+
+        nfa_mem_co_free (p_evt_data->ndef_type_hdlr.data.ndef_data.p_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_api_reg
+**
+** Description      Process registeration request from application
+**                  Register Handover server on LLCP for negotiated handover
+**                  Register handover select records on NDEF handler for static handover
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_proc_api_reg (tNFA_CHO_INT_EVENT_DATA *p_evt_data)
+{
+    CHO_TRACE_DEBUG1 ("nfa_cho_proc_api_reg (): enable_server=%d",
+                      p_evt_data->api_reg.enable_server);
+
+    if (p_evt_data->api_reg.enable_server == TRUE)
+    {
+        /* Register Handover server on LLCP for negotiated handover */
+        nfa_cho_cb.server_sap = LLCP_RegisterServer (LLCP_INVALID_SAP,
+                                                     LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
+                                                     p_cho_service_name,
+                                                     nfa_cho_sm_llcp_cback);
+        if (nfa_cho_cb.server_sap == LLCP_INVALID_SAP)
+        {
+            CHO_TRACE_ERROR0 ("Cannot register CHO server");
+            return NFA_STATUS_FAILED;
+        }
+        else
+        {
+            nfa_p2p_enable_listening (NFA_ID_CHO, FALSE);
+        }
+    }
+    else
+    {
+        /*
+        ** Register Handover client on LLCP for negotiated handover
+        ** LLCP will notify link status through callback
+        */
+        nfa_cho_cb.client_sap = LLCP_RegisterClient (LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
+                                                     nfa_cho_sm_llcp_cback);
+
+        if (nfa_cho_cb.client_sap == LLCP_INVALID_SAP)
+        {
+            CHO_TRACE_ERROR0 ("Cannot register CHO client");
+            return NFA_STATUS_FAILED;
+        }
+
+        /* set flag not to deregister client when disconnected */
+        nfa_cho_cb.flags |= NFA_CHO_FLAGS_CLIENT_ONLY;
+    }
+
+    /* Register handover select record on NDEF handler for static handover */
+    if (nfa_cho_cb.hs_ndef_type_handle == NFA_HANDLE_INVALID)
+    {
+        NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN,
+                                     nfa_cho_ndef_cback);
+    }
+    if (nfa_cho_cb.bt_ndef_type_handle == NFA_HANDLE_INVALID)
+    {
+        NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_RFC2046_MEDIA,
+                                     p_bt_oob_rec_type, (UINT8) strlen ((char *) p_bt_oob_rec_type),
+                                     nfa_cho_ndef_cback);
+    }
+    if (nfa_cho_cb.wifi_ndef_type_handle == NFA_HANDLE_INVALID)
+    {
+        NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_RFC2046_MEDIA,
+                                     p_wifi_rec_type, (UINT8) strlen ((char *) p_wifi_rec_type),
+                                     nfa_cho_ndef_cback);
+    }
+
+    nfa_cho_cb.p_cback = p_evt_data->api_reg.p_cback;
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_api_dereg
+**
+** Description      Process deregisteration request from application
+**                  Disconnect LLCP connection if any
+**                  Deregister callback from NDEF handler and NFA P2P
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_proc_api_dereg (void)
+{
+    CHO_TRACE_DEBUG0 ("nfa_cho_proc_api_dereg ()");
+
+    /* Deregister outgoing connection, data link will be disconnected if any */
+    if (nfa_cho_cb.client_sap != LLCP_INVALID_SAP)
+    {
+        LLCP_Deregister (nfa_cho_cb.client_sap);
+        nfa_cho_cb.client_sap = LLCP_INVALID_SAP;
+    }
+
+    /* Close Connection Handover server in LLCP, data link will be disconnected if any */
+    if (nfa_cho_cb.server_sap != LLCP_INVALID_SAP)
+    {
+        LLCP_Deregister (nfa_cho_cb.server_sap);
+        nfa_cho_cb.server_sap = LLCP_INVALID_SAP;
+    }
+
+    /* Deregister type handler if any */
+    if (nfa_cho_cb.hs_ndef_type_handle != NFA_HANDLE_INVALID)
+    {
+        NFA_DeregisterNDefTypeHandler (nfa_cho_cb.hs_ndef_type_handle);
+        nfa_cho_cb.hs_ndef_type_handle = NFA_HANDLE_INVALID;
+    }
+
+    if (nfa_cho_cb.bt_ndef_type_handle != NFA_HANDLE_INVALID)
+    {
+        NFA_DeregisterNDefTypeHandler (nfa_cho_cb.bt_ndef_type_handle);
+        nfa_cho_cb.bt_ndef_type_handle = NFA_HANDLE_INVALID;
+    }
+
+    if (nfa_cho_cb.wifi_ndef_type_handle != NFA_HANDLE_INVALID)
+    {
+        NFA_DeregisterNDefTypeHandler (nfa_cho_cb.wifi_ndef_type_handle);
+        nfa_cho_cb.wifi_ndef_type_handle = NFA_HANDLE_INVALID;
+    }
+
+    nfa_sys_stop_timer (&nfa_cho_cb.timer);
+    nfa_cho_cb.p_cback = NULL;
+    nfa_cho_cb.flags   = 0;
+
+    nfa_p2p_disable_listening (NFA_ID_CHO, FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_create_connection
+**
+** Description      Create data link connection with handover server in remote
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_create_connection (void)
+{
+    tLLCP_CONNECTION_PARAMS conn_params;
+    tNFA_STATUS             status = NFA_STATUS_FAILED;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_create_connection ()");
+
+    if (nfa_cho_cb.client_sap == LLCP_INVALID_SAP)
+    {
+        nfa_cho_cb.client_sap = LLCP_RegisterClient (LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
+                                                     nfa_cho_sm_llcp_cback);
+    }
+
+    if (nfa_cho_cb.client_sap == LLCP_INVALID_SAP)
+    {
+        CHO_TRACE_ERROR0 ("Cannot register CHO client");
+    }
+    else
+    {
+        /* create data link connection with server name */
+        conn_params.miu = (UINT16) (nfa_cho_cb.local_link_miu >= NFA_CHO_MIU ? NFA_CHO_MIU : nfa_cho_cb.local_link_miu);
+        conn_params.rw  = NFA_CHO_RW;
+        BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn),
+                       p_cho_service_name, LLCP_MAX_SN_LEN);
+        conn_params.sn[LLCP_MAX_SN_LEN] = 0;
+
+        if (LLCP_ConnectReq (nfa_cho_cb.client_sap, LLCP_SAP_SDP, &conn_params) == LLCP_STATUS_SUCCESS)
+            status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_process_disconnection
+**
+** Description      Clean up buffers and notify disconnection to application
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_process_disconnection (tNFA_CHO_DISC_REASON disc_reason)
+{
+    tNFA_CHO_EVT_DATA evt_data;
+
+    nfa_sys_stop_timer (&nfa_cho_cb.timer);
+
+    /* free buffer for Tx/Rx NDEF message */
+    if (nfa_cho_cb.p_tx_ndef_msg)
+    {
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+    }
+    if (nfa_cho_cb.p_rx_ndef_msg)
+    {
+        GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg);
+        nfa_cho_cb.p_rx_ndef_msg = NULL;
+    }
+
+    /* if no server is registered on LLCP, do not deregister client to get link statue from LLCP */
+    if (!(nfa_cho_cb.flags & NFA_CHO_FLAGS_CLIENT_ONLY))
+    {
+        if (nfa_cho_cb.client_sap != LLCP_INVALID_SAP)
+        {
+            LLCP_Deregister (nfa_cho_cb.client_sap);
+            nfa_cho_cb.client_sap = LLCP_INVALID_SAP;
+        }
+    }
+
+    nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION;
+
+    evt_data.disconnected.reason = disc_reason;
+    nfa_cho_cb.p_cback (NFA_CHO_DISCONNECTED_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_notify_tx_fail_evt
+**
+** Description      Notify application of NFA_CHO_TX_FAIL_EVT
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_notify_tx_fail_evt (tNFA_STATUS status)
+{
+    tNFA_CHO_EVT_DATA evt_data;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_notify_tx_fail_evt ()");
+
+    evt_data.status = status;
+
+    if (nfa_cho_cb.p_cback)
+        nfa_cho_cb.p_cback (NFA_CHO_TX_FAIL_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_reassemble_ho_msg
+**
+** Description      Reassemble received data for handover message
+**
+**
+** Returns          tNFA_CHO_RX_NDEF_STATUS
+**
+*******************************************************************************/
+tNFA_CHO_RX_NDEF_STATUS nfa_cho_reassemble_ho_msg (UINT8 local_sap, UINT8 remote_sap)
+{
+    tNFA_CHO_RX_NDEF_STATUS rx_status;
+
+    nfa_sys_stop_timer (&nfa_cho_cb.timer);
+
+    /*
+    ** allocate memory for NDEF message for the first segment
+    ** validate NDEF message to check if received complete message
+    */
+    rx_status = nfa_cho_read_ndef_msg (local_sap, remote_sap);
+
+    /* if Temporary Memory Constraint */
+    if (rx_status == NFA_CHO_RX_NDEF_TEMP_MEM)
+    {
+        CHO_TRACE_ERROR0 ("Failed due to Temporary Memory Constraint");
+
+        /* if we are expecting Hr then send Hs Error record */
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR)
+        {
+            /* ask retry later, handover request will disconnect */
+            nfa_cho_send_hs_error (NFA_CHO_ERROR_TEMP_MEM, NFA_CHO_TIMEOUT_FOR_RETRY);
+        }
+        else
+        {
+            /* we cannot send error record, so disconnect */
+            nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INTERNAL_ERROR;
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, FALSE);
+        }
+    }
+    /* Permanent Memory Constraint */
+    else if (rx_status == NFA_CHO_RX_NDEF_PERM_MEM)
+    {
+        CHO_TRACE_ERROR0 ("Failed due to Permanent Memory Constraint");
+
+        /* if we are expecting Hr then send Hs Error record */
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR)
+        {
+            /*
+            ** notify our buffer size and ask retry with modified message later
+            ** handover request will disconnect
+            */
+            nfa_cho_send_hs_error (NFA_CHO_ERROR_PERM_MEM, nfa_cho_cb.rx_ndef_buf_size);
+        }
+        else
+        {
+            /* we cannot send error record, so disconnect */
+            nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INTERNAL_ERROR;
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, FALSE);
+        }
+    }
+    /* Invalid NDEF message */
+    else if (rx_status == NFA_CHO_RX_NDEF_INVALID)
+    {
+        CHO_TRACE_ERROR0 ("Failed due to invalid NDEF message");
+
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR)
+        {
+            /* let Handover Requester got timeout */
+        }
+        else
+        {
+            /* we cannot send error record, so disconnect */
+            nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INVALID_MSG;
+            LLCP_DisconnectReq (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, FALSE);
+        }
+    }
+    /* need more segment */
+    else if (rx_status == NFA_CHO_RX_NDEF_INCOMPLTE)
+    {
+        /* wait for next segment */
+        if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR)
+        {
+            nfa_sys_start_timer (&nfa_cho_cb.timer, 0, NFA_CHO_TIMEOUT_SEGMENTED_HR);
+        }
+        /* don't update running timer if we are waiting Hs */
+    }
+    else /* NFA_CHO_RX_NDEF_COMPLETE */
+    {
+        /* Received complete NDEF message */
+    }
+
+    return rx_status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_send_handover_msg
+**
+** Description      Send segmented or whole Handover Message on LLCP
+**                  if congested then wait for uncongested event from LLCP
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_send_handover_msg (void)
+{
+    tNFA_STATUS  status = NFA_STATUS_FAILED;
+    tLLCP_STATUS llcp_status;
+    UINT16       tx_size;
+    BT_HDR       *p_msg;
+    UINT8        *p_src, *p_dst;
+
+    CHO_TRACE_DEBUG2 ("nfa_cho_send_handover_msg () size=%d, sent=%d",
+                      nfa_cho_cb.tx_ndef_cur_size, nfa_cho_cb.tx_ndef_sent_size);
+
+    /* while data link connection is not congested */
+    while ((!nfa_cho_cb.congested) && (nfa_cho_cb.tx_ndef_sent_size < nfa_cho_cb.tx_ndef_cur_size))
+    {
+        /* select segment size as min (MIU of remote, remaining NDEF size) */
+        if (nfa_cho_cb.tx_ndef_cur_size - nfa_cho_cb.tx_ndef_sent_size > nfa_cho_cb.remote_miu)
+        {
+            tx_size = nfa_cho_cb.remote_miu;
+        }
+        else
+        {
+            tx_size = (UINT16) (nfa_cho_cb.tx_ndef_cur_size - nfa_cho_cb.tx_ndef_sent_size);
+        }
+
+        /* transmit a segment on LLCP */
+        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+        {
+            p_msg->len    = (UINT16) tx_size;
+            p_msg->offset = LLCP_MIN_OFFSET;
+
+            p_dst = (UINT8*) (p_msg + 1) + p_msg->offset;
+            p_src = nfa_cho_cb.p_tx_ndef_msg + nfa_cho_cb.tx_ndef_sent_size;
+
+            memcpy (p_dst, p_src, tx_size);
+
+            llcp_status = LLCP_SendData (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, p_msg);
+
+            nfa_cho_cb.tx_ndef_sent_size += tx_size;
+        }
+        else
+        {
+            llcp_status = LLCP_STATUS_FAIL;
+        }
+
+        if (llcp_status == LLCP_STATUS_SUCCESS)
+        {
+            status = NFA_STATUS_OK;
+        }
+        else if (llcp_status == LLCP_STATUS_CONGESTED)
+        {
+            status = NFA_STATUS_CONGESTED;
+            CHO_TRACE_DEBUG0 ("Data link connection is congested");
+            /* wait for uncongested event */
+            nfa_cho_cb.congested = TRUE;
+            break;
+        }
+        else
+        {
+            status = NFA_STATUS_FAILED;
+            GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+            nfa_cho_cb.p_tx_ndef_msg = NULL;
+            break;
+        }
+    }
+
+    /*
+    ** free buffer when receiving response or disconnected because we may need to send
+    ** Hr message again due to collision
+    */
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_read_ndef_msg
+**
+** Description      allocate memory for NDEF message for the first segment
+**                  validate NDEF message to check if received complete message
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_CHO_RX_NDEF_STATUS nfa_cho_read_ndef_msg (UINT8 local_sap, UINT8 remote_sap)
+{
+    tNDEF_STATUS            ndef_status;
+    tNFA_CHO_RX_NDEF_STATUS rx_status;
+    BOOLEAN                 more;
+    UINT32                  length;
+
+    CHO_TRACE_DEBUG2 ("nfa_cho_read_ndef_msg () local_sap=0x%x, remote_sap=0x%x",
+                      local_sap, remote_sap);
+
+    /* if this is the first segment */
+    if (!nfa_cho_cb.p_rx_ndef_msg)
+    {
+        nfa_cho_cb.p_rx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+        if (!nfa_cho_cb.p_rx_ndef_msg)
+        {
+            CHO_TRACE_ERROR0 ("Failed to allocate buffer");
+            return NFA_CHO_RX_NDEF_TEMP_MEM;
+        }
+
+        nfa_cho_cb.rx_ndef_buf_size = LLCP_POOL_BUF_SIZE;
+        nfa_cho_cb.rx_ndef_cur_size = 0;
+    }
+
+    more = TRUE;
+    while (more)
+    {
+        more = LLCP_ReadDataLinkData (local_sap,
+                                      remote_sap,
+                                      (UINT16)(nfa_cho_cb.rx_ndef_buf_size - nfa_cho_cb.rx_ndef_cur_size),
+                                      &length,
+                                      nfa_cho_cb.p_rx_ndef_msg + nfa_cho_cb.rx_ndef_cur_size);
+
+        nfa_cho_cb.rx_ndef_cur_size += length;
+
+        /* if it doesn't fit into allocated memory */
+        if ((nfa_cho_cb.rx_ndef_cur_size >= nfa_cho_cb.rx_ndef_buf_size)
+          &&(more))
+        {
+            CHO_TRACE_ERROR0 ("Failed to store too much data");
+
+            LLCP_FlushDataLinkRxData (local_sap, remote_sap);
+
+            GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg);
+            nfa_cho_cb.p_rx_ndef_msg = NULL;
+
+            return NFA_CHO_RX_NDEF_PERM_MEM;
+        }
+    }
+
+    /* check NDEF message */
+    ndef_status = NDEF_MsgValidate (nfa_cho_cb.p_rx_ndef_msg, nfa_cho_cb.rx_ndef_cur_size, FALSE);
+
+    switch (ndef_status)
+    {
+    case NDEF_OK:
+        rx_status = NFA_CHO_RX_NDEF_COMPLETE;
+        break;
+
+    case NDEF_MSG_TOO_SHORT:
+    case NDEF_MSG_NO_MSG_END:
+    case NDEF_MSG_LENGTH_MISMATCH:
+        rx_status = NFA_CHO_RX_NDEF_INCOMPLTE;
+        break;
+
+    default:
+        rx_status = NFA_CHO_RX_NDEF_INVALID;
+        break;
+    }
+
+    if (rx_status == NFA_CHO_RX_NDEF_COMPLETE)
+    {
+#if (BT_TRACE_PROTOCOL == TRUE)
+        DispCHO (nfa_cho_cb.p_rx_ndef_msg, nfa_cho_cb.rx_ndef_cur_size, TRUE);
+#endif
+    }
+    else if (rx_status == NFA_CHO_RX_NDEF_INCOMPLTE)
+    {
+        CHO_TRACE_DEBUG0 ("Need more data to complete NDEF message");
+    }
+    else /* if (rx_status == NFA_CHO_RX_NDEF_INVALID) */
+    {
+        CHO_TRACE_ERROR1 ("Failed to validate NDEF message error=0x%x", ndef_status);
+        GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg);
+        nfa_cho_cb.p_rx_ndef_msg = NULL;
+    }
+
+    return rx_status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_add_cr_record
+**
+** Description      Adding Collision Resolution record
+**
+**
+** Returns          NDEF_OK if success
+**
+*******************************************************************************/
+tNDEF_STATUS nfa_cho_add_cr_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size)
+{
+    tNDEF_STATUS status;
+    UINT32       temp32;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_add_cr_record () cur_size = %d", *p_cur_size);
+
+    /* Get random number from timer */
+    temp32 = GKI_get_tick_count ();
+    nfa_cho_cb.tx_random_number = (UINT16) ((temp32 >> 16) ^ (temp32));
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+    if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_RANDOM)
+    {
+        nfa_cho_cb.tx_random_number = nfa_cho_cb.test_random_number;
+    }
+#endif
+
+    CHO_TRACE_DEBUG1 ("tx_random_number = 0x%04x", nfa_cho_cb.tx_random_number);
+
+    /* Add Well-Known Type:Collistion Resolution Record */
+    status = NDEF_MsgAddWktCr (p_msg, max_size, p_cur_size,
+                               nfa_cho_cb.tx_random_number);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_add_ac_record
+**
+** Description      Adding Alternative Carrier record
+**
+**
+** Returns          NDEF_OK if success
+**
+*******************************************************************************/
+tNDEF_STATUS nfa_cho_add_ac_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                    UINT8 num_ac_info, tNFA_CHO_AC_INFO *p_ac_info,
+                                    UINT8 *p_ndef, UINT32 max_ndef_size, UINT32 *p_cur_ndef_size)
+{
+    tNDEF_STATUS status = NDEF_OK;
+    UINT8        xx, yy;
+    UINT8       *p_rec, *p_id, id_len;
+    char         carrier_data_ref_str[NFA_CHO_MAX_REF_NAME_LEN];
+    char        *aux_data_ref[NFA_CHO_MAX_AUX_DATA_COUNT];
+    char         aux_data_ref_str[NFA_CHO_MAX_AUX_DATA_COUNT][NFA_CHO_MAX_REF_NAME_LEN];
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_add_ac_record (): num_ac_info = %d", num_ac_info);
+
+    /* initialize auxilary data reference */
+    for (xx = 0; xx < NFA_CHO_MAX_AUX_DATA_COUNT; xx++)
+    {
+        aux_data_ref[xx] = aux_data_ref_str[xx];
+    }
+
+    p_rec = p_ndef;
+
+    /* Alternative Carrier Records */
+    for (xx = 0; (xx < num_ac_info) && (status == NDEF_OK); xx++)
+    {
+        if (!p_rec)
+        {
+            status = NDEF_REC_NOT_FOUND;
+            break;
+        }
+
+        p_id = NDEF_RecGetId (p_rec, &id_len);
+
+        if ((p_id) && (id_len > 0) && (id_len <= NFA_CHO_MAX_REF_NAME_LEN))
+        {
+            memcpy (carrier_data_ref_str, p_id, id_len);
+            carrier_data_ref_str[id_len] = 0x00;
+        }
+        else
+        {
+            CHO_TRACE_ERROR1 ("nfa_cho_add_ac_record ():id_len=%d", id_len);
+            status = NDEF_REC_NOT_FOUND;
+            break;
+        }
+
+        p_rec = NDEF_MsgGetNextRec (p_rec);
+
+        /* auxilary data reference */
+        for (yy = 0; yy < p_ac_info[xx].num_aux_data; yy++)
+        {
+            if (!p_rec)
+            {
+                status = NDEF_REC_NOT_FOUND;
+                break;
+            }
+
+            p_id = NDEF_RecGetId (p_rec, &id_len);
+
+            if ((p_id) && (id_len > 0) && (id_len <= NFA_CHO_MAX_REF_NAME_LEN))
+            {
+                memcpy (aux_data_ref_str[yy], p_id, id_len);
+                aux_data_ref_str[yy][id_len] = 0x00;
+            }
+            else
+            {
+                CHO_TRACE_ERROR1 ("nfa_cho_add_ac_record ():id_len=%d", id_len);
+                status = NDEF_REC_NOT_FOUND;
+                break;
+            }
+
+            p_rec = NDEF_MsgGetNextRec (p_rec);
+        }
+
+        if (status == NDEF_OK)
+        {
+            /* Add Well-Known Type:Alternative Carrier Record */
+            status = NDEF_MsgAddWktAc (p_msg, max_size, p_cur_size,
+                                       p_ac_info[xx].cps, carrier_data_ref_str,
+                                       p_ac_info[xx].num_aux_data, aux_data_ref);
+        }
+
+        if (status != NDEF_OK)
+        {
+            break;
+        }
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_send_hr
+**
+** Description      Sending Handover Request Message
+**                  It may send one from AC list to select a specific AC.
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_send_hr (tNFA_CHO_API_SEND_HR *p_api_send_hr)
+{
+    tNDEF_STATUS    status;
+    UINT8          *p_msg_cr_ac;
+    UINT32          cur_size_cr_ac, max_size;
+    UINT8           version;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_send_hr ()");
+
+    /* Collistion Resolution Record and Alternative Carrier Records */
+
+    p_msg_cr_ac = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+    if (!p_msg_cr_ac)
+    {
+        CHO_TRACE_ERROR0 ("Failed to allocate buffer");
+        return NFA_STATUS_NO_BUFFERS;
+    }
+
+    max_size = LLCP_POOL_BUF_SIZE;
+    NDEF_MsgInit (p_msg_cr_ac, max_size, &cur_size_cr_ac);
+
+    /* Collistion Resolution Record */
+    if (NDEF_OK != nfa_cho_add_cr_record (p_msg_cr_ac, max_size, &cur_size_cr_ac))
+    {
+        CHO_TRACE_ERROR0 ("Failed to add cr record");
+        GKI_freebuf (p_msg_cr_ac);
+        return NFA_STATUS_FAILED;
+    }
+
+    /* Alternative Carrier Records */
+    if (NDEF_OK != nfa_cho_add_ac_record (p_msg_cr_ac, max_size, &cur_size_cr_ac,
+                                          p_api_send_hr->num_ac_info, p_api_send_hr->p_ac_info,
+                                          p_api_send_hr->p_ndef, p_api_send_hr->max_ndef_size,
+                                          &(p_api_send_hr->cur_ndef_size)))
+    {
+        CHO_TRACE_ERROR0 ("Failed to add ac record");
+        GKI_freebuf (p_msg_cr_ac);
+        return NFA_STATUS_FAILED;
+    }
+
+    /* Handover Request Message */
+
+    nfa_cho_cb.p_tx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+    if (!nfa_cho_cb.p_tx_ndef_msg)
+    {
+        CHO_TRACE_ERROR0 ("Failed to allocate buffer");
+        GKI_freebuf (p_msg_cr_ac);
+        return NFA_STATUS_FAILED;
+    }
+
+    max_size = LLCP_POOL_BUF_SIZE;
+
+    /* Handover Request Record */
+    version = NFA_CHO_VERSION;
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+    if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_VERSION)
+    {
+        version = nfa_cho_cb.test_version;
+    }
+#endif
+
+    status = NDEF_MsgCreateWktHr (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                  version);
+    if (status != NDEF_OK)
+    {
+        CHO_TRACE_ERROR0 ("Failed to create Hr");
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+        GKI_freebuf (p_msg_cr_ac);
+        return NFA_STATUS_FAILED;
+    }
+
+    /* Append Collistion Resolution Record and Alternative Carrier Records */
+    status = NDEF_MsgAppendPayload (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                    nfa_cho_cb.p_tx_ndef_msg, p_msg_cr_ac, cur_size_cr_ac);
+
+    GKI_freebuf (p_msg_cr_ac);
+
+    if (status != NDEF_OK)
+    {
+        CHO_TRACE_ERROR0 ("Failed to add cr/ac record");
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+        return NFA_STATUS_FAILED;
+    }
+
+
+    /* Append Alternative Carrier Reference Data or Handover Carrier Record */
+    status = NDEF_MsgAppendRec (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                p_api_send_hr->p_ndef, p_api_send_hr->cur_ndef_size);
+
+    if (status != NDEF_OK)
+    {
+        CHO_TRACE_ERROR0 ("Failed to add ac reference data or Hc record");
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+        return NFA_STATUS_FAILED;
+    }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispCHO (nfa_cho_cb.p_tx_ndef_msg, nfa_cho_cb.tx_ndef_cur_size, FALSE);
+#endif
+
+    /* Send it to peer */
+    nfa_cho_cb.tx_ndef_sent_size = 0;
+
+    status = nfa_cho_send_handover_msg ();
+
+    if (status == NFA_STATUS_CONGESTED)
+    {
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_send_hs
+**
+** Description      Send Handover Select Message
+**
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_send_hs (tNFA_CHO_API_SEND_HS *p_api_select)
+{
+    tNDEF_STATUS    status;
+    UINT8          *p_msg_ac;
+    UINT32          cur_size_ac = 0, max_size;
+    UINT8           version;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_send_hs () num_ac_info=%d", p_api_select->num_ac_info);
+
+    if (p_api_select->num_ac_info > 0)
+    {
+        /* Alternative Carrier Records */
+
+        p_msg_ac = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+        if (!p_msg_ac)
+        {
+            CHO_TRACE_ERROR0 ("Failed to allocate buffer");
+            return NFA_STATUS_FAILED;
+        }
+
+        max_size = LLCP_POOL_BUF_SIZE;
+        NDEF_MsgInit (p_msg_ac, max_size, &cur_size_ac);
+
+        if (NDEF_OK != nfa_cho_add_ac_record (p_msg_ac, max_size, &cur_size_ac,
+                                              p_api_select->num_ac_info, p_api_select->p_ac_info,
+                                              p_api_select->p_ndef, p_api_select->max_ndef_size,
+                                              &(p_api_select->cur_ndef_size)))
+        {
+            CHO_TRACE_ERROR0 ("Failed to add ac record");
+            GKI_freebuf (p_msg_ac);
+            return NFA_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        p_msg_ac = NULL;
+    }
+
+    /* Handover Select Message */
+    nfa_cho_cb.p_tx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (!nfa_cho_cb.p_tx_ndef_msg)
+    {
+        CHO_TRACE_ERROR0 ("Failed to allocate buffer");
+
+        if (p_msg_ac)
+            GKI_freebuf (p_msg_ac);
+
+        return NFA_STATUS_FAILED;
+    }
+    max_size = LLCP_POOL_BUF_SIZE;
+
+    /* Handover Select Record */
+    version = NFA_CHO_VERSION;
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+    if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_VERSION)
+    {
+        version = nfa_cho_cb.test_version;
+    }
+#endif
+    status = NDEF_MsgCreateWktHs (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                  version);
+
+    if (status != NDEF_OK)
+    {
+        CHO_TRACE_ERROR0 ("Failed to create Hs");
+
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+
+        if (p_msg_ac)
+            GKI_freebuf (p_msg_ac);
+
+        return NFA_STATUS_FAILED;
+    }
+
+    if (p_api_select->num_ac_info > 0)
+    {
+        /* Append Alternative Carrier Records */
+        status = NDEF_MsgAppendPayload (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                        nfa_cho_cb.p_tx_ndef_msg, p_msg_ac, cur_size_ac);
+
+        if (p_msg_ac)
+            GKI_freebuf (p_msg_ac);
+
+        if (status != NDEF_OK)
+        {
+            CHO_TRACE_ERROR0 ("Failed to add cr record");
+            GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+            nfa_cho_cb.p_tx_ndef_msg = NULL;
+            return NFA_STATUS_FAILED;
+        }
+
+        /* Append Alternative Carrier Reference Data */
+        status = NDEF_MsgAppendRec (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                    p_api_select->p_ndef, p_api_select->cur_ndef_size);
+
+        if (status != NDEF_OK)
+        {
+            CHO_TRACE_ERROR0 ("Failed to add ac reference data record");
+            GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+            nfa_cho_cb.p_tx_ndef_msg = NULL;
+            return NFA_STATUS_FAILED;
+        }
+    }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispCHO (nfa_cho_cb.p_tx_ndef_msg, nfa_cho_cb.tx_ndef_cur_size, FALSE);
+#endif
+
+    /* Send it to peer */
+    nfa_cho_cb.tx_ndef_sent_size = 0;
+
+    status = nfa_cho_send_handover_msg ();
+
+    if (status == NFA_STATUS_CONGESTED)
+    {
+        status = NFA_STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_send_hs_error
+**
+** Description      Sending Handover Select Message with error record
+**
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_send_hs_error (UINT8 error_reason, UINT32 error_data)
+{
+    tNDEF_STATUS    status;
+    UINT8           version;
+    UINT32          max_size;
+
+    CHO_TRACE_DEBUG2 ("nfa_cho_send_hs_error () error_reason=0x%x, error_data=0x%x",
+                       error_reason, error_data);
+
+    /* Handover Select Message */
+    nfa_cho_cb.p_tx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (!nfa_cho_cb.p_tx_ndef_msg)
+    {
+        CHO_TRACE_ERROR0 ("Failed to allocate buffer");
+        return NFA_STATUS_FAILED;
+    }
+
+    max_size = LLCP_POOL_BUF_SIZE;
+
+    /* Handover Select Record with Version */
+    version = NFA_CHO_VERSION;
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+    if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_VERSION)
+    {
+        version = nfa_cho_cb.test_version;
+    }
+#endif
+    status = NDEF_MsgCreateWktHs (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                  version);
+
+    if (status != NDEF_OK)
+    {
+        CHO_TRACE_ERROR0 ("Failed to create Hs");
+
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+
+        return NFA_STATUS_FAILED;
+    }
+
+    /* Add Error Records */
+    status = NDEF_MsgAddWktErr (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size,
+                                error_reason, error_data);
+
+    if (status != NDEF_OK)
+    {
+        CHO_TRACE_ERROR0 ("Failed to add err record");
+
+        GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg);
+        nfa_cho_cb.p_tx_ndef_msg = NULL;
+
+        return NFA_STATUS_FAILED;
+    }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispCHO (nfa_cho_cb.p_tx_ndef_msg, nfa_cho_cb.tx_ndef_cur_size, FALSE);
+#endif
+
+    /* Send it to peer */
+    nfa_cho_cb.tx_ndef_sent_size = 0;
+
+    status = nfa_cho_send_handover_msg ();
+
+    if (status == NFA_STATUS_CONGESTED)
+    {
+        status = NFA_STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_get_random_number
+**
+** Description      Return random number in Handover Request message
+**
+**
+** Returns          random number in "cr" record
+**
+*******************************************************************************/
+UINT16 nfa_cho_get_random_number (UINT8 *p_ndef_msg)
+{
+    UINT16 random_number;
+    UINT8 *p_cr_record, *p_cr_payload;
+    UINT32 cr_payload_len;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_get_random_number ()");
+
+    /* find Collision Resolution record */
+    p_cr_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN);
+
+    if (!p_cr_record)
+    {
+        CHO_TRACE_ERROR0 ("Failed to find cr record");
+        return 0;
+    }
+
+    /* get start of payload in Collision Resolution record */
+    p_cr_payload = NDEF_RecGetPayload (p_cr_record, &cr_payload_len);
+
+    if ((!p_cr_payload) || (cr_payload_len != 2))
+    {
+        CHO_TRACE_ERROR0 ("Failed to get cr payload (random number)");
+        return 0;
+    }
+
+    /* get random number from payload */
+    BE_STREAM_TO_UINT16 (random_number, p_cr_payload);
+
+    return random_number;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_parse_ac_records
+**
+** Description      Parsing NDEF message to retrieve Alternative Carrier records
+**                  and store into tNFA_CHO_AC_REC
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_parse_ac_records (UINT8 *p_ndef_msg, UINT8 *p_num_ac_rec, tNFA_CHO_AC_REC *p_ac_rec)
+{
+    UINT8 *p_ac_record, *p_ac_payload;
+    UINT32 ac_payload_len;
+
+    UINT8  xx, yy;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_parse_ac_records ()");
+
+    /* get Alternative Carrier record */
+    p_ac_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN);
+
+    xx = 0;
+
+    while ((p_ac_record) && (xx < NFA_CHO_MAX_AC_INFO))
+    {
+        /* get payload */
+        p_ac_payload = NDEF_RecGetPayload (p_ac_record, &ac_payload_len);
+
+        if ((!p_ac_payload) || (ac_payload_len < 3))
+        {
+            CHO_TRACE_ERROR0 ("Failed to get ac payload");
+            return NFA_STATUS_FAILED;
+        }
+
+        /* Carrier Power State */
+        BE_STREAM_TO_UINT8 (p_ac_rec->cps, p_ac_payload);
+
+        /* Carrier Data Reference Length and Characters */
+        BE_STREAM_TO_UINT8 (p_ac_rec->carrier_data_ref.ref_len, p_ac_payload);
+
+        ac_payload_len -= 2;
+
+        /* remaining must have carrier data ref and Auxiliary Data Reference Count at least */
+        if (ac_payload_len > p_ac_rec->carrier_data_ref.ref_len)
+        {
+            if (p_ac_rec->carrier_data_ref.ref_len > NFA_CHO_MAX_REF_NAME_LEN)
+            {
+                CHO_TRACE_ERROR1 ("Too many bytes for carrier_data_ref, ref_len = %d",
+                                   p_ac_rec->carrier_data_ref.ref_len);
+                return NFA_STATUS_FAILED;
+            }
+
+            BE_STREAM_TO_ARRAY (p_ac_payload,
+                                p_ac_rec->carrier_data_ref.ref_name,
+                                p_ac_rec->carrier_data_ref.ref_len);
+            ac_payload_len -= p_ac_rec->carrier_data_ref.ref_len;
+        }
+        else
+        {
+            CHO_TRACE_ERROR0 ("Failed to parse carrier_data_ref.ref_len");
+            return NFA_STATUS_FAILED;
+        }
+
+        /* Auxiliary Data Reference Count */
+        BE_STREAM_TO_UINT8 (p_ac_rec->aux_data_ref_count, p_ac_payload);
+        ac_payload_len--;
+
+        /* Auxiliary Data Reference Length and Characters */
+        for (yy = 0; (yy < p_ac_rec->aux_data_ref_count) && (yy < NFA_CHO_MAX_AUX_DATA_COUNT); yy++)
+        {
+            if (ac_payload_len > 0)
+            {
+                BE_STREAM_TO_UINT8 (p_ac_rec->aux_data_ref[yy].ref_len, p_ac_payload);
+                ac_payload_len--;
+
+                if (ac_payload_len >= p_ac_rec->aux_data_ref[yy].ref_len)
+                {
+                    if (p_ac_rec->aux_data_ref[yy].ref_len > NFA_CHO_MAX_REF_NAME_LEN)
+                    {
+                        CHO_TRACE_ERROR2 ("Too many bytes for aux_data_ref[%d], ref_len=%d",
+                                           yy, p_ac_rec->aux_data_ref[yy].ref_len);
+                        return NFA_STATUS_FAILED;
+                    }
+
+                    BE_STREAM_TO_ARRAY (p_ac_payload,
+                                        p_ac_rec->aux_data_ref[yy].ref_name,
+                                        p_ac_rec->aux_data_ref[yy].ref_len);
+                    ac_payload_len -= p_ac_rec->aux_data_ref[yy].ref_len;
+                }
+                else
+                {
+                    CHO_TRACE_ERROR1 ("Failed to parse ref_name for aux_data_ref[%d]", yy);
+                    return NFA_STATUS_FAILED;
+                }
+            }
+            else
+            {
+                CHO_TRACE_ERROR1 ("Failed to parse ref_len for aux_data_ref[%d]", yy);
+                return NFA_STATUS_FAILED;
+            }
+        }
+
+        if (ac_payload_len != 0)
+        {
+            CHO_TRACE_WARNING1 ("Found extra data in AC record[%d]", xx);
+        }
+
+        xx++;
+        p_ac_rec++;
+
+        /* get next Alternative Carrier record */
+        p_ac_record = NDEF_MsgGetNextRecByType (p_ac_record, NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN);
+    }
+
+    *p_num_ac_rec = xx;
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_parse_hr_record
+**
+** Description      Parsing Handover Request message to retrieve version, random number,
+**                  Alternative Carrier records and store into tNFA_CHO_AC_REC
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_parse_hr_record (UINT8  *p_ndef_msg,
+                                     UINT8  *p_version,
+                                     UINT16 *p_random_number,
+                                     UINT8  *p_num_ac_rec,
+                                     tNFA_CHO_AC_REC *p_ac_rec)
+{
+    UINT8 *p_hr_record, *p_hr_payload;
+    UINT32 hr_payload_len;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_parse_hr_record ()");
+
+    /* get Handover Request record */
+    p_hr_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN);
+
+    if (!p_hr_record)
+    {
+        CHO_TRACE_ERROR0 ("Failed to find Hr record");
+        return NFA_STATUS_FAILED;
+    }
+
+    p_hr_payload = NDEF_RecGetPayload (p_hr_record, &hr_payload_len);
+
+    if ((!p_hr_payload) || (hr_payload_len < 7))
+    {
+        CHO_TRACE_ERROR0 ("Failed to get Hr payload (version, cr/ac record)");
+        return NFA_STATUS_FAILED;
+    }
+
+    /* Version */
+    STREAM_TO_UINT8 ((*p_version), p_hr_payload);
+    hr_payload_len--;
+
+    /* NDEF message for Collision Resolution record and Alternative Carrier records */
+
+    if (NDEF_OK != NDEF_MsgValidate (p_hr_payload, hr_payload_len, FALSE))
+    {
+        CHO_TRACE_ERROR0 ("Failed to validate NDEF message for cr/ac records");
+        return NFA_STATUS_FAILED;
+    }
+
+    /* Collision Resolution record */
+    if (p_random_number)
+    {
+        *p_random_number = nfa_cho_get_random_number (p_hr_payload);
+    }
+
+    /* Alternative Carrier records */
+    if (p_ac_rec)
+    {
+        return (nfa_cho_parse_ac_records (p_hr_payload, p_num_ac_rec, p_ac_rec));
+    }
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_parse_carrier_config
+**
+** Description      Parse Alternative Carrier Configuration and Aux Data
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_parse_carrier_config (UINT8 *p_ndef_msg, UINT8 num_ac_rec, tNFA_CHO_AC_REC *p_ac_rec)
+{
+    UINT8  *p_record;
+    UINT8   xx, yy;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_parse_carrier_config () num_ac_rec = %d", num_ac_rec);
+
+    /* Parse Alternative Carrier Configuration and Aux Data */
+    for (xx = 0; xx < num_ac_rec; xx++)
+    {
+        p_record = NDEF_MsgGetFirstRecById (p_ndef_msg,
+                                            p_ac_rec->carrier_data_ref.ref_name,
+                                            p_ac_rec->carrier_data_ref.ref_len);
+
+        if (!p_record)
+        {
+            CHO_TRACE_ERROR2 ("Failed to find Payload ID: len=%d, [0x%x ...]",
+                              p_ac_rec->carrier_data_ref.ref_len,
+                              p_ac_rec->carrier_data_ref.ref_name[0]);
+            return NFA_STATUS_FAILED;
+        }
+
+        for (yy = 0; yy < p_ac_rec->aux_data_ref_count; yy++)
+        {
+            /* Get aux data record by Payload ID */
+            p_record = NDEF_MsgGetFirstRecById (p_ndef_msg,
+                                                p_ac_rec->aux_data_ref[yy].ref_name,
+                                                p_ac_rec->aux_data_ref[yy].ref_len);
+
+            if (!p_record)
+            {
+                CHO_TRACE_ERROR2 ("Failed to find Payload ID for Aux: len=%d, [0x%x ...]",
+                                  p_ac_rec->aux_data_ref[yy].ref_len,
+                                  p_ac_rec->aux_data_ref[yy].ref_name[0]);
+                return NFA_STATUS_FAILED;
+            }
+        }
+
+        p_ac_rec++;
+    }
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_hr
+**
+** Description      Parse Handover Request Message
+**                  In case of parsing error, let peer got timeout (1 sec).
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_cho_proc_hr (UINT32 length, UINT8 *p_ndef_msg)
+{
+    tNFA_CHO_EVT_DATA    evt_data;
+    tNFA_CHO_API_SEND_HS select;
+    UINT8  version;
+    UINT16 random_number;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_proc_hr () length=%d", length);
+
+    /* Parse Handover Request record */
+    if (NDEF_OK != nfa_cho_parse_hr_record (p_ndef_msg, &version, &random_number,
+                                            &evt_data.request.num_ac_rec,
+                                            &evt_data.request.ac_rec[0]))
+    {
+        CHO_TRACE_ERROR0 ("Failed to parse hr record");
+        return;
+    }
+
+    if (version != NFA_CHO_VERSION)
+    {
+        CHO_TRACE_DEBUG1 ("Version (0x%02x) not matched", version);
+        /* For the future, */
+        /* if we have higher major then support peer's version */
+        /* if we have lower major then send empty handover select message */
+        if (NFA_CHO_GET_MAJOR_VERSION (version) > NFA_CHO_GET_MAJOR_VERSION (NFA_CHO_VERSION))
+        {
+            select.num_ac_info = 0;
+            nfa_cho_send_hs (&select);
+            return;
+        }
+    }
+
+    if (NFA_STATUS_OK != nfa_cho_parse_carrier_config (p_ndef_msg,
+                                                       evt_data.request.num_ac_rec,
+                                                       &evt_data.request.ac_rec[0]))
+    {
+        CHO_TRACE_ERROR0 ("Failed to parse carrier configuration");
+
+        evt_data.request.status       = NFA_STATUS_FAILED;
+        evt_data.request.num_ac_rec   = 0;
+        evt_data.request.p_ref_ndef   = NULL;
+        evt_data.request.ref_ndef_len = 0;
+
+        nfa_cho_cb.p_cback (NFA_CHO_REQUEST_EVT, &evt_data);
+        return;
+    }
+
+    if (evt_data.request.num_ac_rec)
+    {
+        /* passing alternative carrier references */
+        evt_data.request.p_ref_ndef   = NDEF_MsgGetNextRec (p_ndef_msg);
+        *evt_data.request.p_ref_ndef |= NDEF_MB_MASK;
+        evt_data.request.ref_ndef_len = (UINT32)(length - (evt_data.request.p_ref_ndef - p_ndef_msg));
+    }
+    else
+    {
+        evt_data.request.p_ref_ndef   = NULL;
+        evt_data.request.ref_ndef_len = 0;
+    }
+
+    evt_data.request.status = NFA_STATUS_OK;
+
+    nfa_cho_cb.p_cback (NFA_CHO_REQUEST_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_get_error
+**
+** Description      Search Error record and parse it
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_get_error (UINT8 *p_ndef_msg, UINT8 *p_error_reason, UINT32 *p_error_data)
+{
+    UINT8 *p_err_record, *p_err_payload, u8;
+    UINT32 err_payload_len;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_get_error ()");
+
+    p_err_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, err_rec_type, ERR_REC_TYPE_LEN);
+
+    if (!p_err_record)
+    {
+        CHO_TRACE_DEBUG0 ("Found no err record");
+        return NFA_STATUS_FAILED;
+    }
+
+    p_err_payload = NDEF_RecGetPayload (p_err_record, &err_payload_len);
+
+    if (!p_err_payload)
+    {
+        CHO_TRACE_ERROR0 ("Failed to get err payload");
+        return NFA_STATUS_SYNTAX_ERROR;
+    }
+
+    BE_STREAM_TO_UINT8 (*p_error_reason, p_err_payload);
+
+    if (  (err_payload_len == 2)
+        &&(  (*p_error_reason == NFA_CHO_ERROR_TEMP_MEM)
+           ||(*p_error_reason == NFA_CHO_ERROR_CARRIER)  )  )
+    {
+        BE_STREAM_TO_UINT8 (u8, p_err_payload);
+        *p_error_data = (UINT32)u8;
+    }
+    else if (  (err_payload_len == 5)
+             &&(*p_error_reason == NFA_CHO_ERROR_PERM_MEM)  )
+    {
+        BE_STREAM_TO_UINT32 (*p_error_data, p_err_payload);
+    }
+    else
+    {
+        CHO_TRACE_ERROR2 ("Unknown error reason = %d, err_payload_len = %d",
+                          *p_error_reason, err_payload_len);
+        return NFA_STATUS_SYNTAX_ERROR;
+    }
+
+    CHO_TRACE_DEBUG2 ("error_reason=0x%x, error_data=0x%x", *p_error_reason, *p_error_data);
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_parse_hs_record
+**
+** Description      Parse Handover Select record
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_parse_hs_record (UINT8  *p_ndef_msg,
+                                     UINT8  *p_version,
+                                     UINT8  *p_num_ac_rec,
+                                     tNFA_CHO_AC_REC *p_ac_rec,
+                                     UINT8  *p_error_reason,
+                                     UINT32 *p_error_data)
+{
+    tNFA_STATUS status;
+    UINT8 *p_hs_record, *p_hs_payload;
+    UINT32 hs_payload_len;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_parse_hs_record ()");
+
+    /* get Handover Select record */
+    p_hs_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN);
+
+    if (!p_hs_record)
+    {
+        CHO_TRACE_ERROR0 ("Failed to find Hs record");
+        return NFA_STATUS_FAILED;
+    }
+
+    p_hs_payload = NDEF_RecGetPayload (p_hs_record, &hs_payload_len);
+
+    if ((!p_hs_payload) || (hs_payload_len < 1))  /* at least version */
+    {
+        CHO_TRACE_ERROR0 ("Failed to get Hs payload (version, ac record)");
+        return NFA_STATUS_FAILED;
+    }
+
+    STREAM_TO_UINT8 ((*p_version), p_hs_payload);
+    hs_payload_len--;
+
+    /* Check if error record is sent */
+    status = nfa_cho_get_error (p_ndef_msg, p_error_reason, p_error_data);
+
+    if (status == NFA_STATUS_SYNTAX_ERROR)
+    {
+        return NFA_STATUS_FAILED;
+    }
+    else if (status == NFA_STATUS_OK)
+    {
+        return NFA_STATUS_OK;
+    }
+
+    if (hs_payload_len >= 3 )
+    {
+        /* NDEF message for Alternative Carrier records */
+        if (NDEF_OK != NDEF_MsgValidate (p_hs_payload, hs_payload_len, FALSE))
+        {
+            CHO_TRACE_ERROR0 ("Failed to validate NDEF message for ac records");
+            return NFA_STATUS_FAILED;
+        }
+
+        /* Alternative Carrier records */
+        if (p_ac_rec)
+        {
+            if (NFA_STATUS_OK != nfa_cho_parse_ac_records (p_hs_payload, p_num_ac_rec, p_ac_rec))
+            {
+                return NFA_STATUS_FAILED;
+            }
+
+            CHO_TRACE_DEBUG1 ("Found %d ac record", *p_num_ac_rec);
+        }
+    }
+    else
+    {
+        CHO_TRACE_DEBUG0 ("Empty Handover Select Message");
+        *p_num_ac_rec = 0;
+    }
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_hs
+**
+** Description      Parse Handover Select Message
+**
+**
+** Returns          FALSE if we need to select one from inactive ACs
+**
+*******************************************************************************/
+void nfa_cho_proc_hs (UINT32 length, UINT8 *p_ndef_msg)
+{
+    tNFA_CHO_EVT_DATA evt_data;
+    UINT8  version, error_reason = 0;
+    UINT32 error_data;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_proc_hs ()");
+
+    evt_data.select.status = NFA_STATUS_OK;
+
+    /* Parse Handover Select record */
+    if (NFA_STATUS_OK != nfa_cho_parse_hs_record (p_ndef_msg, &version,
+                                                  &evt_data.select.num_ac_rec,
+                                                  &evt_data.select.ac_rec[0],
+                                                  &error_reason, &error_data))
+    {
+        CHO_TRACE_ERROR0 ("Failed to parse hs record");
+
+        evt_data.select.status = NFA_STATUS_FAILED;
+    }
+
+    if (  (evt_data.select.status == NFA_STATUS_OK)
+        &&(error_reason != 0)  )
+    {
+        /* We got error records */
+        evt_data.sel_err.error_reason = error_reason;
+        evt_data.sel_err.error_data   = error_data;
+
+        nfa_cho_cb.p_cback (NFA_CHO_SEL_ERR_EVT, &evt_data);
+        return;
+    }
+
+    if (  (evt_data.select.status == NFA_STATUS_OK)
+        &&(version != NFA_CHO_VERSION)  )
+    {
+        CHO_TRACE_ERROR1 ("Version (0x%02x) not matched", version);
+
+        evt_data.select.status = NFA_STATUS_FAILED;
+    }
+
+    /* parse Alternative Carrier information */
+
+    if (  (evt_data.select.status == NFA_STATUS_OK)
+        &&(NFA_STATUS_OK != nfa_cho_parse_carrier_config (p_ndef_msg,
+                                                          evt_data.select.num_ac_rec,
+                                                          &evt_data.select.ac_rec[0]))  )
+    {
+        CHO_TRACE_ERROR0 ("Failed to parse carrier configuration");
+
+        evt_data.select.status = NFA_STATUS_FAILED;
+    }
+
+    if (evt_data.select.status == NFA_STATUS_OK)
+    {
+        if (evt_data.select.num_ac_rec)
+        {
+            /* passing alternative carrier references */
+            evt_data.select.p_ref_ndef   = NDEF_MsgGetNextRec (p_ndef_msg);
+            *evt_data.select.p_ref_ndef |= NDEF_MB_MASK;
+            evt_data.select.ref_ndef_len = (UINT32)(length - (evt_data.select.p_ref_ndef - p_ndef_msg));
+        }
+        else
+        {
+            evt_data.select.p_ref_ndef   = NULL;
+            evt_data.select.ref_ndef_len = 0;
+        }
+    }
+    else
+    {
+        evt_data.select.num_ac_rec   = 0;
+        evt_data.select.p_ref_ndef   = NULL;
+        evt_data.select.ref_ndef_len = 0;
+    }
+
+    nfa_cho_cb.p_cback (NFA_CHO_SELECT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_proc_simplified_format
+**
+** Description      Parse simplified BT OOB/Wifi Message
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_cho_proc_simplified_format (UINT32 length, UINT8 *p_ndef_msg)
+{
+    tNFA_CHO_EVT_DATA evt_data;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_proc_simplified_format ()");
+
+    evt_data.select.status = NFA_STATUS_OK;
+
+    evt_data.select.num_ac_rec = 1;
+
+    evt_data.select.ac_rec[0].cps = NFA_CHO_CPS_UNKNOWN;
+    evt_data.select.ac_rec[0].carrier_data_ref.ref_len = 0;
+    evt_data.select.ac_rec[0].aux_data_ref_count       = 0;
+
+    evt_data.select.p_ref_ndef   = p_ndef_msg;
+    evt_data.select.ref_ndef_len = length;
+
+    nfa_cho_cb.p_cback (NFA_CHO_SELECT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_get_msg_type
+**
+** Description      Get handover message type to check collision
+**
+**
+** Returns          NFA_CHO_MSG_HR if it has Handover Request record
+**                  NFA_CHO_MSG_HS if it has Handover Select record
+**                  NFA_CHO_MSG_BT_OOB if it has simplified BT OOB record
+**                  NFA_CHO_MSG_WIFI if it has simplified WiFi record
+**                  NFA_CHO_MSG_UNKNOWN, otherwise
+**
+*******************************************************************************/
+tNFA_CHO_MSG_TYPE nfa_cho_get_msg_type (UINT32 length, UINT8 *p_ndef_msg)
+{
+    UINT8 *p_record;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_get_msg_type () length=%d", length);
+
+    p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN);
+
+    if (p_record)
+    {
+        CHO_TRACE_DEBUG0 ("Found Hr record");
+        return NFA_CHO_MSG_HR;
+    }
+
+    p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN);
+
+    if (p_record)
+    {
+        CHO_TRACE_DEBUG0 ("Found Hs record");
+        return NFA_CHO_MSG_HS;
+    }
+
+    p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_MEDIA,
+                                          p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN);
+
+    if (p_record)
+    {
+        CHO_TRACE_DEBUG0 ("Found simplified BT OOB record");
+        return NFA_CHO_MSG_BT_OOB;
+    }
+
+    p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_MEDIA,
+                                          p_wifi_rec_type, (UINT8) strlen ((char *) p_wifi_rec_type));
+
+    if (p_record)
+    {
+        CHO_TRACE_DEBUG0 ("Found simplified WiFi record");
+        return NFA_CHO_MSG_WIFI;
+    }
+
+    CHO_TRACE_ERROR0 ("Failed to find Hr/Hs record");
+
+    return NFA_CHO_MSG_UNKNOWN;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_get_local_device_role
+**
+** Description      Resolve collision and get role of local device
+**
+**
+** Returns          tNFA_CHO_ROLE_TYPE
+**
+*******************************************************************************/
+tNFA_CHO_ROLE_TYPE nfa_cho_get_local_device_role (UINT32 length, UINT8 *p_ndef_msg)
+{
+    UINT16 rx_random_number;
+    UINT8  version;
+
+    CHO_TRACE_DEBUG1 ("nfa_cho_get_local_device_role () length=%d", length);
+
+    /* Get random number in Handover Request record */
+    if (NDEF_OK != nfa_cho_parse_hr_record (p_ndef_msg, &version, &rx_random_number, NULL, NULL))
+    {
+        CHO_TRACE_ERROR0 ("Failed to parse hr record");
+        return NFA_CHO_ROLE_UNDECIDED;
+    }
+
+    CHO_TRACE_DEBUG2 ("tx_random_number=0x%x, rx_random_number=0x%x",
+                       nfa_cho_cb.tx_random_number, rx_random_number);
+
+    if (nfa_cho_cb.tx_random_number == rx_random_number)
+    {
+        return NFA_CHO_ROLE_UNDECIDED;
+    }
+    /* if the least significant bits are same */
+    else if (((nfa_cho_cb.tx_random_number ^ rx_random_number) & 0x0001) == 0)
+    {
+        if (nfa_cho_cb.tx_random_number > rx_random_number)
+            return NFA_CHO_ROLE_SELECTOR;
+        else
+            return NFA_CHO_ROLE_REQUESTER;
+    }
+    else
+    {
+        if (nfa_cho_cb.tx_random_number > rx_random_number)
+            return NFA_CHO_ROLE_REQUESTER;
+        else
+            return NFA_CHO_ROLE_SELECTOR;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_cho_update_random_number
+**
+** Description      Replace random number
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_cho_update_random_number (UINT8 *p_ndef_msg)
+{
+    UINT8 *p_hr_record, *p_hr_payload;
+    UINT8 *p_cr_record, *p_cr_payload;
+    UINT32 hr_payload_len, cr_payload_len;
+    UINT32 temp32;
+
+    CHO_TRACE_DEBUG0 ("nfa_cho_update_random_number ()");
+
+    /* get Handover Request record */
+    p_hr_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN);
+
+    if (!p_hr_record)
+    {
+        CHO_TRACE_ERROR0 ("Failed to find Hr record");
+        return NFA_STATUS_FAILED;
+    }
+
+    p_hr_payload = NDEF_RecGetPayload (p_hr_record, &hr_payload_len);
+
+    /* Skip Version */
+    p_hr_payload++;
+    hr_payload_len--;
+
+    /* NDEF message for Collision Resolution record and Alternative Carrier records */
+
+    /* find Collision Resolution record */
+    p_cr_record = NDEF_MsgGetFirstRecByType (p_hr_payload, NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN);
+
+    if (!p_cr_record)
+    {
+        CHO_TRACE_ERROR0 ("Failed to find cr record");
+        return NFA_STATUS_FAILED;
+    }
+
+    /* get start of payload in Collision Resolution record */
+    p_cr_payload = NDEF_RecGetPayload (p_cr_record, &cr_payload_len);
+
+    /* Get random number from timer */
+    temp32 = GKI_get_tick_count ();
+    nfa_cho_cb.tx_random_number = (UINT16) ((temp32 >> 16) ^ (temp32));
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+    if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_RANDOM)
+    {
+        nfa_cho_cb.tx_random_number = nfa_cho_cb.test_random_number;
+    }
+#endif
+
+    CHO_TRACE_DEBUG1 ("tx_random_number = 0x%04x", nfa_cho_cb.tx_random_number);
+
+    /* update random number in payload */
+    UINT16_TO_BE_STREAM (p_cr_payload, nfa_cho_cb.tx_random_number);
+
+    return NFA_STATUS_OK;
+}
diff --git a/src/nfa/dm/nfa_dm_act.c b/src/nfa/dm/nfa_dm_act.c
new file mode 100644
index 0000000..c4b5250
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_act.c
@@ -0,0 +1,1808 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions for device manager state
+ *  machine.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_ce_int.h"
+#include "nfc_api.h"
+#include "nfa_rw_int.h"
+#include "nfa_rw_api.h"
+#include "nfa_p2p_int.h"
+#include "nfa_cho_int.h"
+#include "nci_hmsgs.h"
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#include "nfa_ee_int.h"
+#include "nfa_hci_int.h"
+#endif
+
+#if (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE))
+#include "nfa_snep_int.h"
+#else
+#define nfa_snep_init ()
+#endif
+
+/* This is the timeout value to guarantee disable is performed within reasonable amount of time */
+#ifndef NFA_DM_DISABLE_TIMEOUT_VAL
+#define NFA_DM_DISABLE_TIMEOUT_VAL         1000
+#endif
+
+static void nfa_dm_set_init_nci_params (void);
+static tNFA_STATUS nfa_dm_start_polling (void);
+static BOOLEAN nfa_dm_deactivate_polling (void);
+static void nfa_dm_excl_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+static void nfa_dm_poll_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+
+
+/*******************************************************************************
+**
+** Function         nfa_dm_module_init_cback
+**
+** Description      Processing initialization complete event from sub-modules
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_module_init_cback (void)
+{
+    tNFA_DM_CBACK_DATA dm_cback_data;
+
+    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_ENABLE_EVT_PEND;
+
+    /* All subsystem are initialized */
+    dm_cback_data.status = NFA_STATUS_OK;
+    (*nfa_dm_cb.p_dm_cback) (NFA_DM_ENABLE_EVT, &dm_cback_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_nfcc_power_mode_proc_complete_cback
+**
+** Description      Processing complete of processing NFCC power state change
+**                  from all sub-modules
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_nfcc_power_mode_proc_complete_cback (void)
+{
+    tNFA_DM_PWR_MODE_CHANGE power_mode_change;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_nfcc_power_mode_proc_complete_cback () nfcc_pwr_mode = 0x%x",
+                      nfa_dm_cb.nfcc_pwr_mode);
+
+    /* if NFCC power state is change to full power */
+    if (nfa_dm_cb.nfcc_pwr_mode != NFA_DM_PWR_MODE_OFF_SLEEP)
+    {
+        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_NFCC_IS_RESTORING;
+
+        /* reconfigure BRCM NFCC */
+        nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_CMD, NULL);
+    }
+
+    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SETTING_PWR_MODE;
+
+    power_mode_change.status     = NFA_STATUS_OK;
+    power_mode_change.power_mode = nfa_dm_cb.nfcc_pwr_mode;
+    (*nfa_dm_cb.p_dm_cback) (NFA_DM_PWR_MODE_CHANGE_EVT, (tNFA_DM_CBACK_DATA*) &power_mode_change);
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_sys_enable
+**
+** Description      This function on enable
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_sys_enable (void)
+{
+    nfa_dm_set_init_nci_params ();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_init_nci_params
+**
+** Description      Set initial NCI configuration parameters
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_set_init_nci_params (void)
+{
+    UINT8   xx;
+
+    /* set NCI default value if other than zero */
+
+    /* LF_T3T_IDENTIFIERS_1/2/.../16 */
+    for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++)
+    {
+        nfa_dm_cb.params.lf_t3t_id[xx][0] = 0xFF;
+        nfa_dm_cb.params.lf_t3t_id[xx][1] = 0xFF;
+        nfa_dm_cb.params.lf_t3t_id[xx][2] = 0x02;
+        nfa_dm_cb.params.lf_t3t_id[xx][2] = 0xFE;
+    }
+
+    /* LF_T3T_PMM */
+    for (xx = 0; xx < NCI_PARAM_LEN_LF_T3T_PMM; xx++)
+    {
+        nfa_dm_cb.params.lf_t3t_pmm[xx] = 0xFF;
+    }
+
+    /* LF_T3T_FLAGS:
+    ** DH needs to set this configuration, even if default value (not listening) is used,
+    ** to let NFCC know of intention (not listening) of DH.
+    */
+
+    /* FWI */
+    nfa_dm_cb.params.fwi[0] = 0x04;
+
+    /* WT */
+    nfa_dm_cb.params.wt[0] = 14;
+
+    /* Set CE default configuration */
+    if (p_nfa_dm_ce_cfg[0])
+    {
+        nfa_dm_check_set_config (p_nfa_dm_ce_cfg[0], &p_nfa_dm_ce_cfg[1], FALSE);
+    }
+
+    /* Set optional general default configuration */
+    if (p_nfa_dm_gen_cfg && p_nfa_dm_gen_cfg[0])
+    {
+        nfa_dm_check_set_config (p_nfa_dm_gen_cfg[0], &p_nfa_dm_gen_cfg[1], FALSE);
+    }
+
+    if (p_nfa_dm_interface_mapping && nfa_dm_num_dm_interface_mapping)
+    {
+        NFC_DiscoveryMap (nfa_dm_num_dm_interface_mapping, p_nfa_dm_interface_mapping, NULL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_proc_nfcc_power_mode
+**
+** Description      Processing NFCC power mode changes
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_dm_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+    NFA_TRACE_DEBUG1 ("nfa_dm_proc_nfcc_power_mode (): nfcc_power_mode=%d",
+                       nfcc_power_mode);
+
+    /* if NFCC power mode is change to full power */
+    if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
+    {
+        memset (&nfa_dm_cb.params, 0x00, sizeof (tNFA_DM_PARAMS));
+
+        nfa_dm_cb.setcfg_pending_mask = 0;
+        nfa_dm_cb.setcfg_pending_num  = 0;
+        nfa_dm_set_init_nci_params ();
+    }
+
+    nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_DM);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disable_event
+**
+** Description      report disable event
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disable_event (void)
+{
+    /* Deregister DM from sys */
+    nfa_sys_deregister (NFA_ID_DM);
+
+    /* Notify app */
+    nfa_dm_cb.flags &= ~(NFA_DM_FLAGS_DM_IS_ACTIVE
+                        |NFA_DM_FLAGS_DM_DISABLING_NFC
+                        |NFA_DM_FLAGS_ENABLE_EVT_PEND);
+    (*nfa_dm_cb.p_dm_cback) (NFA_DM_DISABLE_EVT, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_nfc_response_cback
+**
+** Description      Call DM event hanlder with NFC response callback data
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_nfc_response_cback (tNFC_RESPONSE_EVT event, tNFC_RESPONSE *p_data)
+{
+    tNFA_DM_CBACK_DATA dm_cback_data;
+    tNFA_GET_CONFIG   *p_nfa_get_confg;
+    tNFA_CONN_EVT_DATA conn_evt;
+    UINT8 dm_cback_evt;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG2 ("nfa_dm_nfc_response_cback () %s(0x%x)", nfa_dm_nfc_revt_2_str (event), event);
+#else
+    NFA_TRACE_DEBUG1 ("nfa_dm_nfc_response_cback () event=0x%x", event);
+#endif
+
+    switch (event)
+    {
+    case NFC_ENABLE_REVT:                        /* 0  Enable event */
+
+        /* NFC stack enabled. Enable nfa sub-systems */
+        if (p_data->enable.status == NFC_STATUS_OK)
+        {
+            nfa_dm_set_init_nci_params ();
+
+            /* Initialize NFA subsystems */
+            nfa_sys_enable_subsystems ();
+        }
+        else if (nfa_dm_cb.flags & NFA_DM_FLAGS_ENABLE_EVT_PEND)
+        {
+            /* Notify app */
+            nfa_dm_cb.flags &= ~(NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_DM_IS_ACTIVE);
+            dm_cback_data.status = p_data->enable.status;
+            (*nfa_dm_cb.p_dm_cback) (NFA_DM_ENABLE_EVT, &dm_cback_data);
+        }
+        break;
+
+    case NFC_DISABLE_REVT:                       /* 1  Disable event */
+        nfa_dm_disable_event ();
+        break;
+
+    case NFC_SET_CONFIG_REVT:                    /* 2  Set Config Response */
+        /* If this setconfig was due to NFA_SetConfig, then notify the app */
+        if (nfa_dm_cb.setcfg_pending_mask & 1)      /* lsb=whether last NCI_SET_CONFIG was due to NFA_SetConfig */
+        {
+            dm_cback_data.set_config.status         = p_data->set_config.status;
+            dm_cback_data.set_config.num_param_id   = p_data->set_config.num_param_id;
+            memcpy (dm_cback_data.set_config.param_ids, p_data->set_config.param_ids, p_data->set_config.num_param_id);
+            (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
+        }
+
+        /* Update the pending mask */
+        if (nfa_dm_cb.setcfg_pending_num>0)
+        {
+            nfa_dm_cb.setcfg_pending_mask >>= 1;
+            nfa_dm_cb.setcfg_pending_num--;
+        }
+        else
+        {
+            /* This should not occur (means we got a SET_CONFIG_NTF that's unaccounted for */
+            NFA_TRACE_ERROR0 ("NFA received unexpected NFC_SET_CONFIG_REVT");
+        }
+        break;
+
+    case NFC_GET_CONFIG_REVT:                    /* 3  Get Config Response */
+        if (p_data->get_config.status == NFC_STATUS_OK)
+        {
+            if ((p_nfa_get_confg = (tNFA_GET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_GET_CONFIG) + p_data->get_config.tlv_size))) != NULL)
+            {
+                p_nfa_get_confg->status = NFA_STATUS_OK;
+                p_nfa_get_confg->tlv_size = p_data->get_config.tlv_size;
+                memcpy (p_nfa_get_confg->param_tlvs, p_data->get_config.p_param_tlvs, p_data->get_config.tlv_size);
+                (*nfa_dm_cb.p_dm_cback) (NFA_DM_GET_CONFIG_EVT, (tNFA_DM_CBACK_DATA *) p_nfa_get_confg);
+
+                GKI_freebuf (p_nfa_get_confg);
+                return;
+            }
+            else
+            {
+                NFA_TRACE_DEBUG0 ("nfa_dm_nfc_response_cback unable to allocate buffer");
+            }
+        }
+
+        /* Return result of getconfig to the app */
+        dm_cback_data.get_config.status = NFA_STATUS_FAILED;
+        (*nfa_dm_cb.p_dm_cback) (NFA_DM_GET_CONFIG_EVT, &dm_cback_data);
+        break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+    case NFC_NFCEE_DISCOVER_REVT:                /* NFCEE Discover response */
+    case NFC_NFCEE_INFO_REVT:                    /* NFCEE Discover Notification */
+    case NFC_EE_ACTION_REVT:                     /* EE Action notification */
+    case NFC_NFCEE_MODE_SET_REVT:                /* NFCEE Mode Set response */
+    case NFC_EE_DISCOVER_REQ_REVT:               /* EE Discover Req notification */
+        nfa_ee_proc_evt (event, p_data);
+        break;
+#endif
+
+    case NFC_RF_FIELD_REVT:                      /* RF Field information            */
+        dm_cback_data.rf_field.status          = NFA_STATUS_OK;
+        dm_cback_data.rf_field.rf_field_status = p_data->rf_field.rf_field;
+        (*nfa_dm_cb.p_dm_cback) (NFA_DM_RF_FIELD_EVT, &dm_cback_data);
+        break;
+
+    case NFC_SET_ROUTING_REVT:                   /* Configure Routing response */
+        break;
+
+    case NFC_GET_ROUTING_REVT:                   /* Retrieve Routing response */
+        break;
+
+    case NFC_GEN_ERROR_REVT:                     /* generic error command or notification */
+        break;
+
+    case NFC_NFCC_RESTART_REVT:                  /* NFCC has been re-initialized */
+
+        if (p_data->status == NFC_STATUS_OK)
+        {
+            nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL;
+            nfa_dm_cb.flags |= NFA_DM_FLAGS_NFCC_IS_RESTORING;
+
+            /* NFCC will start from IDLE when turned on again */
+            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+            nfa_dm_cb.disc_cb.disc_state = NFA_DM_RFST_IDLE;
+        }
+        else
+        {
+            nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
+        }
+        /* Notify NFA submodules change of NFCC power mode */
+        nfa_sys_cback_reg_nfcc_power_mode_proc_complete (nfa_dm_nfcc_power_mode_proc_complete_cback);
+        nfa_sys_notify_nfcc_power_mode (nfa_dm_cb.nfcc_pwr_mode);
+        break;
+
+    case NFC_NFCC_TIMEOUT_REVT:
+    case NFC_NFCC_TRANSPORT_ERR_REVT:
+        NFA_TRACE_DEBUG1 ("flags:0x%08x", nfa_dm_cb.flags);
+        dm_cback_evt = (event == NFC_NFCC_TIMEOUT_REVT) ? NFA_DM_NFCC_TIMEOUT_EVT : NFA_DM_NFCC_TRANSPORT_ERR_EVT;
+        (*nfa_dm_cb.p_dm_cback) (dm_cback_evt, NULL);
+        break;
+
+    case NFC_NFCC_POWER_OFF_REVT:
+        nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
+
+        /* Notify NFA submodules change of NFCC power mode */
+        nfa_sys_cback_reg_nfcc_power_mode_proc_complete (nfa_dm_nfcc_power_mode_proc_complete_cback);
+        nfa_sys_notify_nfcc_power_mode (NFA_DM_PWR_MODE_OFF_SLEEP);
+        break;
+
+    case NFC_RF_COMM_PARAMS_UPDATE_REVT:
+        conn_evt.status = p_data->status;
+        nfa_dm_conn_cback_event_notify (NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
+        break;
+
+    default:
+        break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_dm_enable
+**
+** Description      Initialises the NFC device manager
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_enable (tNFA_DM_MSG *p_data)
+{
+    tNFA_DM_CBACK_DATA dm_cback_data;
+    NFA_TRACE_DEBUG0 ("nfa_dm_enable ()");
+
+    /* Check if NFA is already enabled */
+    if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE))
+    {
+        /* Initialize BRCM control block, it musb be called before setting any flags */
+        nfa_dm_cb.flags |= (NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_ENABLE_EVT_PEND);
+        nfa_sys_cback_reg_enable_complete (nfa_dm_module_init_cback);
+
+
+        /* Store Enable parameters */
+        nfa_dm_cb.p_dm_cback    = p_data->enable.p_dm_cback;
+        nfa_dm_cb.p_conn_cback  = p_data->enable.p_conn_cback;
+
+        /* Enable NFC stack */
+        NFC_Enable (nfa_dm_nfc_response_cback);
+    }
+    else
+    {
+        NFA_TRACE_ERROR0 ("nfa_dm_enable: ERROR ALREADY ENABLED.");
+        dm_cback_data.status = NFA_STATUS_ALREADY_STARTED;
+        (*(p_data->enable.p_dm_cback)) (NFA_DM_ENABLE_EVT, &dm_cback_data);
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disable
+**
+** Description      Disables the NFC device manager
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_disable (tNFA_DM_MSG *p_data)
+{
+    tNFC_DEACT_TYPE deactivate_type = NFA_DEACTIVATE_TYPE_IDLE;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_disable (): graceful:%d", p_data->disable.graceful);
+
+    if (p_data->disable.graceful)
+    {
+        /* if RF discovery is enabled */
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)
+        {
+            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+
+            if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+            {
+                /* if waiting RSP in idle state */
+                if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
+                {
+                    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
+                }
+            }
+            else
+            {
+                nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
+                nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
+                if ((nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF)) == 0)
+                {
+                    /* not waiting to deactivate, clear the flag now */
+                    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+                }
+            }
+        }
+        /* Start timeout for graceful shutdown. If timer expires, then force an ungraceful shutdown */
+        nfa_sys_start_timer (&nfa_dm_cb.tle, NFA_DM_TIMEOUT_DISABLE_EVT, NFA_DM_DISABLE_TIMEOUT_VAL);
+    }
+
+    /* Disable all subsystems other than DM (DM will be disabled after all  */
+    /* the other subsystem have been disabled)                              */
+    nfa_sys_disable_subsystems (p_data->disable.graceful);
+    return (TRUE);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disable_complete
+**
+** Description      Called when all NFA subsytems are disabled.
+**
+**                  NFC core stack can now be disabled.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_disable_complete (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_disable_complete ()");
+
+    if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_DISABLING_NFC) == 0)
+    {
+        NFA_TRACE_DEBUG0 ("nfa_dm_disable_complete (): proceeding with nfc core shutdown.");
+
+        nfa_dm_cb.flags |= NFA_DM_FLAGS_DM_DISABLING_NFC;
+
+        nfa_sys_stop_timer (&nfa_dm_cb.tle);
+
+        /* Free all buffers for NDEF handlers */
+        nfa_dm_ndef_dereg_all();
+
+        /* Disable nfc core stack */
+        NFC_Disable ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_config
+**
+** Description      Process set config command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_set_config (tNFA_DM_MSG *p_data)
+{
+    tNFC_STATUS status;
+    UINT8       buff[255];
+    UINT8      *p = buff;
+
+    tNFA_DM_CBACK_DATA dm_cback_data;
+
+    if (p_data->setconfig.length + 2 > 255)
+    {
+        /* Total length of TLV must be less than 256 (1 byte) */
+        status = NFC_STATUS_FAILED;
+    }
+    else
+    {
+        UINT8_TO_STREAM (p, p_data->setconfig.param_id);
+        UINT8_TO_STREAM (p, p_data->setconfig.length);
+        ARRAY_TO_STREAM (p, p_data->setconfig.p_data, p_data->setconfig.length)
+        status = nfa_dm_check_set_config ((UINT8) (p_data->setconfig.length + 2), buff, TRUE);
+    }
+
+    if (status != NFC_STATUS_OK)
+    {
+        dm_cback_data.set_config.status = NFA_STATUS_INVALID_PARAM;
+        (*nfa_dm_cb.p_dm_cback) (NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_get_config
+**
+** Description      Process get config command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_get_config (tNFA_DM_MSG *p_data)
+{
+    NFC_GetConfig (p_data->getconfig.num_ids, p_data->getconfig.p_pmids);
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_conn_cback_event_notify
+**
+** Description      Notify application of CONN_CBACK event, using appropriate
+**                  callback
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_dm_conn_cback_event_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data)
+{
+    if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
+    {
+        /* Use exclusive RF mode callback */
+        if (nfa_dm_cb.p_excl_conn_cback)
+            (*nfa_dm_cb.p_excl_conn_cback) (event, p_data);
+    }
+    else
+    {
+        (*nfa_dm_cb.p_conn_cback) (event, p_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_rel_excl_rf_control_and_notify
+**
+** Description      Stop exclusive RF control and notify app of
+**                  NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_rel_excl_rf_control_and_notify (void)
+{
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_rel_excl_rf_control_and_notify ()");
+
+    /* Exclusive RF control stopped. Notify app */
+    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_EXCL_RF_ACTIVE;
+
+    /* Stop exclusive RF discovery for exclusive RF mode */
+    nfa_dm_stop_excl_discovery ();
+
+    /* Notify app that exclusive RF control has stopped */
+    conn_evt.status = NFA_STATUS_OK;
+    (*nfa_dm_cb.p_excl_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT, &conn_evt);
+    nfa_dm_cb.p_excl_conn_cback = NULL;
+    nfa_dm_cb.p_excl_ndef_cback = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_request_excl_rf_ctrl
+**
+** Description      Request exclusive RF control
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_request_excl_rf_ctrl (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_request_excl_rf_ctrl ()");
+
+    if (!nfa_dm_cb.p_excl_conn_cback)
+    {
+        if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
+        {
+            conn_evt.status = NFA_STATUS_FAILED;
+            (*p_data->req_excl_rf_ctrl.p_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
+            return TRUE;
+        }
+
+        /* Store callbacks */
+        nfa_dm_cb.p_excl_conn_cback = p_data->req_excl_rf_ctrl.p_conn_cback;
+        nfa_dm_cb.p_excl_ndef_cback = p_data->req_excl_rf_ctrl.p_ndef_cback;
+
+        nfa_dm_cb.flags |= NFA_DM_FLAGS_EXCL_RF_ACTIVE;
+
+        /* start exclusive RF discovery */
+        nfa_dm_start_excl_discovery (p_data->req_excl_rf_ctrl.poll_mask,
+                                     &p_data->req_excl_rf_ctrl.listen_cfg,
+                                     nfa_dm_excl_disc_cback);
+    }
+    else
+    {
+        NFA_TRACE_ERROR0 ("Exclusive rf control already requested");
+
+        conn_evt.status = NFA_STATUS_FAILED;
+        (*p_data->req_excl_rf_ctrl.p_conn_cback) (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
+    }
+
+    return TRUE;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_release_excl_rf_ctrl
+**
+** Description      Release exclusive RF control
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_release_excl_rf_ctrl (tNFA_DM_MSG *p_data)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_release_excl_rf_ctrl ()");
+
+    /* nfa_dm_rel_excl_rf_control_and_notify() is called when discovery state goes IDLE */
+    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+
+    /* if discover command has been sent in IDLE state and waiting for response
+    ** then just wait for responose. Otherwise initiate deactivating.
+    */
+    if (!(  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+          &&(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)  ))
+    {
+        nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_deactivate
+**
+** Description      Process deactivate command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_deactivate (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt;
+    tNFA_DEACTIVATE_TYPE deact_type;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_deactivate ()");
+
+    if (  (p_data->deactivate.sleep_mode == FALSE)                 /* Always allow deactivate to IDLE */
+        ||(  (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_T1T)      /* Do not allow deactivate to SLEEP for T1T,NFCDEP, ISO15693 */
+           &&(nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_NFC_DEP)
+           &&(nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_ISO15693)  )  )
+    {
+        if (  (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
+            &&((nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) == 0x00)  )
+        {
+            /* Exclusive RF control doesn't use NFA P2P */
+            /* NFA P2P will deactivate NFC link after deactivating LLCP link */
+            nfa_p2p_deactivate_llcp ();
+            return (TRUE);
+        }
+        else
+        {
+            deact_type  = NFA_DEACTIVATE_TYPE_DISCOVERY;
+            if (p_data->deactivate.sleep_mode)
+            {
+                if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)
+                {
+                    /* Deactivate to sleep mode not allowed in this state. */
+                    deact_type = NFA_DEACTIVATE_TYPE_IDLE;
+                }
+                else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_LISTEN_SLEEP)
+                {
+                    deact_type = NFA_DEACTIVATE_TYPE_SLEEP;
+                }
+            }
+            if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES)
+            {
+                /* Only deactivate to IDLE is allowed in this state. */
+                deact_type = NFA_DEACTIVATE_TYPE_IDLE;
+            }
+            if (nfa_dm_rf_deactivate (deact_type) == NFA_STATUS_OK)
+            {
+                nfa_rw_stop_presence_check_timer ();
+                return (TRUE);
+            }
+        }
+    }
+
+    NFA_TRACE_ERROR0 ("nfa_dm_act_deactivate (): invalid protocol or mode");
+
+    /* Notify error to application */
+    conn_evt.status = NFA_STATUS_FAILED;
+    nfa_dm_conn_cback_event_notify (NFA_DEACTIVATE_FAIL_EVT, &conn_evt);
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_power_off_sleep
+**
+** Description      Process power off sleep mode request
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_power_off_sleep (tNFA_DM_MSG *p_data)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_power_off_sleep ()");
+
+    NFC_SetPowerOffSleep ((BOOLEAN) (p_data->hdr.layer_specific));
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_reg_vsc
+**
+** Description      Process registers VSC callback
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_reg_vsc(tNFA_DM_MSG *p_data)
+{
+    if (NFC_RegVSCback(p_data->reg_vsc.is_register, p_data->reg_vsc.p_cback) != NFC_STATUS_OK)
+    {
+        NFA_TRACE_ERROR0 ("NFC_RegVSCback failed");
+    }
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_send_vsc
+**
+** Description      Send the NCI Vendor Specific command to the NCI command queue
+**
+** Returns          FALSE (message buffer is NOT freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_send_vsc(tNFA_DM_MSG *p_data)
+{
+    BT_HDR  *p_cmd = (BT_HDR *)p_data;
+
+    p_cmd->offset   = sizeof (tNFA_DM_API_SEND_VSC) - BT_HDR_SIZE;
+    p_cmd->len      = p_data->send_vsc.cmd_params_len;
+    NFC_SendVsCommand (p_data->send_vsc.oid, p_cmd, p_data->send_vsc.p_cback);
+
+    /* Most dm action functions return TRUE, so nfa-sys frees the GKI buffer carrying the message,
+     * This action function re-use the GKI buffer to send the VSC, so the GKI buffer can not be freed by nfa-sys */
+    return (FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_start_polling
+**
+** Description      Start polling
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_start_polling (void)
+{
+    tNFA_STATUS             status;
+    tNFA_TECHNOLOGY_MASK    poll_tech_mask;
+    tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_start_polling ()");
+
+    poll_tech_mask = nfa_dm_cb.poll_mask;
+
+    /* start RF discovery with discovery callback */
+    if (nfa_dm_cb.poll_disc_handle == NFA_HANDLE_INVALID)
+    {
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
+            poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
+            poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
+            poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
+            poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
+            poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
+        }
+        if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO)
+        {
+            poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
+        }
+
+        nfa_dm_cb.poll_disc_handle = nfa_dm_add_rf_discover (poll_disc_mask,
+                                                             NFA_DM_DISC_HOST_ID_DH,
+                                                             nfa_dm_poll_disc_cback);
+
+        if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
+            status = NFA_STATUS_OK;
+        else
+            status = NFA_STATUS_FAILED;
+    }
+    else
+    {
+        status = NFA_STATUS_OK;
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_enable_polling
+**
+** Description      Process enable polling command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_enable_polling (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_enable_polling ()");
+
+    if (  (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED))
+        &&(!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)  )  )
+    {
+        nfa_dm_cb.poll_mask = p_data->enable_poll.poll_mask;
+
+        if (nfa_dm_start_polling () == NFA_STATUS_OK)
+        {
+            nfa_dm_cb.flags |= NFA_DM_FLAGS_POLLING_ENABLED;
+
+            evt_data.status = NFA_STATUS_OK;
+            nfa_dm_conn_cback_event_notify (NFA_POLL_ENABLED_EVT, &evt_data);
+            return (TRUE);
+        }
+    }
+    else
+    {
+        NFA_TRACE_ERROR0 ("nfa_dm_act_enable_polling (): already started");
+    }
+
+    /* send NFA_POLL_ENABLED_EVT with NFA_STATUS_FAILED */
+    evt_data.status = NFA_STATUS_FAILED;
+    nfa_dm_conn_cback_event_notify (NFA_POLL_ENABLED_EVT, &evt_data);
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_deactivate_polling
+**
+** Description      Deactivate any polling state
+**
+** Returns          TRUE if need to wait for deactivation
+**
+*******************************************************************************/
+static BOOLEAN nfa_dm_deactivate_polling (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_deactivate_polling ()");
+
+    if (  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES)
+        ||(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)  )
+    {
+        nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        return FALSE;
+    }
+    else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
+    {
+        if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP)
+        {
+            /* NFA P2P will deactivate NFC link after deactivating LLCP link */
+            nfa_p2p_deactivate_llcp ();
+        }
+        else
+        {
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        return TRUE;
+    }
+    else
+    {
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_disable_polling
+**
+** Description      Process disable polling command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_disable_polling (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_disable_polling ()");
+
+    if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
+    {
+        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POLLING_ENABLED;
+
+        if (nfa_dm_deactivate_polling () == FALSE)
+        {
+            nfa_dm_delete_rf_discover (nfa_dm_cb.poll_disc_handle);
+            nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+
+            evt_data.status = NFA_STATUS_OK;
+            nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
+        }
+        else
+        {
+            nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
+        }
+    }
+    else
+    {
+        evt_data.status = NFA_STATUS_FAILED;
+        nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_send_raw_frame
+**
+** Description      Send an raw frame on RF link
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_send_raw_frame (tNFA_DM_MSG *p_data)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_send_raw_frame ()");
+
+    /* If NFC link is activated */
+    if (  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
+        ||(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)  )
+    {
+        /* If not in exclusive mode, and not activated for LISTEN, then forward raw data to NFA_RW to send */
+        if (  !(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
+            &&!(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)
+            &&(  (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T1T)
+               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T2T)
+               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T3T)
+               ||(  (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO_DEP)
+                  &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_ISO_DEP)  )
+               ||(nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693)  )  )
+        {
+            /* if RW is checking presence then it will put into pending queue */
+            status = nfa_rw_send_raw_frame ((BT_HDR*)p_data);
+        }
+        else
+        {
+            status = NFC_SendData (NFC_RF_CONN_ID, (BT_HDR*) p_data);
+        }
+    }
+
+    if (status == NFC_STATUS_FAILED)
+    {
+        /* free the buffer */
+        return TRUE;
+    }
+    else
+    {
+        /* NCI layer will free buffer */
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_p2p_listen_tech
+**
+** Description      Notify change of P2P listen technologies to NFA P2P
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_set_p2p_listen_tech (tNFA_DM_MSG *p_data)
+{
+    NFA_TRACE_DEBUG1 ("nfa_dm_set_p2p_listen_tech ()  tech_mask = %d",
+                      p_data->set_p2p_listen_tech.tech_mask);
+
+    nfa_p2p_update_listen_tech (p_data->set_p2p_listen_tech.tech_mask);
+    nfa_dm_conn_cback_event_notify (NFA_SET_P2P_LISTEN_TECH_EVT, NULL);
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_start_rf_discovery
+**
+** Description      Process start RF discovery command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_start_rf_discovery (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_start_rf_discovery ()");
+
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)
+    {
+        evt_data.status = NFA_STATUS_OK;
+        nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+    }
+    else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE)
+    {
+        evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+        nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+    }
+    else
+    {
+        nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_ENABLED|NFA_DM_DISC_FLAGS_NOTIFY);
+        nfa_dm_start_rf_discover ();
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_stop_rf_discovery
+**
+** Description      Process stop RF discovery command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_stop_rf_discovery (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_stop_rf_discovery ()");
+
+    if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) ||
+        (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) )
+    {
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+
+        /* if discover command has been sent in IDLE state and waiting for response */
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)
+        {
+            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+        }
+        else
+        {
+            evt_data.status = NFA_STATUS_OK;
+            nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
+        }
+    }
+    else
+    {
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
+        nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+    }
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_set_rf_disc_duration
+**
+** Description      Set duration for RF discovery
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_set_rf_disc_duration (tNFA_DM_MSG *p_data)
+{
+    nfa_dm_cb.disc_cb.disc_duration = p_data->disc_duration.rf_disc_dur_ms;
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_select
+**
+** Description      Process RF select command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_select (tNFA_DM_MSG *p_data)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_select ()");
+
+    nfa_dm_rf_discover_select (p_data->select.rf_disc_id,
+                               p_data->select.protocol,
+                               p_data->select.rf_interface);
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_update_rf_params
+**
+** Description      Process update RF communication parameters command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_update_rf_params (tNFA_DM_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_act_update_rf_params ()");
+
+    if (NFC_UpdateRFCommParams (&p_data->update_rf_params.params) != NFC_STATUS_OK)
+    {
+        conn_evt.status = NFA_STATUS_FAILED;
+        nfa_dm_conn_cback_event_notify (NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_disable_timeout
+**
+** Description      timeout on disable process. Shutdown immediately
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_act_disable_timeout (tNFA_DM_MSG *p_data)
+{
+    tNFA_DM_API_DISABLE disable;
+
+    disable.graceful = FALSE;
+    nfa_dm_disable ((tNFA_DM_MSG *) &disable);
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_conn_cback_notify
+**
+** Description      Notify app of reader/writer/ndef events
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_dm_act_conn_cback_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data)
+{
+    NFA_TRACE_DEBUG1 ("nfa_dm_act_conn_cback_notify (): event:0x%X", event);
+
+    /* Notify event using appropriate CONN_CBACK */
+    nfa_dm_conn_cback_event_notify (event, p_data);
+
+    /* If not in exclusive RF mode, then read NDEF message from tag (if automatic reading is enabled) */
+    if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))
+    {
+        if (  (event == NFA_NDEF_DETECT_EVT)
+            &&(nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF)  )
+        {
+            /* read NDEF message from tag */
+            if (p_data->ndef_detect.status == NFA_STATUS_OK)
+            {
+                NFA_RwReadNDef ();
+            }
+            else if (p_data->ndef_detect.status == NFA_STATUS_FAILED)
+            {
+                nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
+            }
+            /* ignore NFA_STATUS_BUSY */
+        }
+        else if (  (event == NFA_READ_CPLT_EVT)
+                 &&(nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF))
+        {
+            /* reading NDEF message is done */
+            nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_act_data_cback
+**
+** Description      Processing data from RF link
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_act_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    BT_HDR             *p_msg = (BT_HDR *) p_data->data.p_data;
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_act_data_cback (): event = 0x%X", event);
+
+    if (event == NFC_DATA_CEVT)
+    {
+        if (p_msg)
+        {
+            evt_data.data.p_data = (UINT8 *) (p_msg + 1) + p_msg->offset;
+            evt_data.data.len    = p_msg->len;
+
+            nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);
+
+            GKI_freebuf (p_msg);
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_dm_act_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
+        }
+    }
+    else if (event == NFC_DEACTIVATE_CEVT)
+    {
+        NFC_SetStaticRfCback (NULL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_excl_disc_cback
+**
+** Description      Processing event from discovery callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_excl_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_excl_disc_cback (): event:0x%02X", event);
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISC_START_EVT:
+        evt_data.status = NFA_STATUS_OK;
+        nfa_dm_conn_cback_event_notify (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &evt_data);
+        break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+        if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A)
+        {
+            /* store SEL_RES response */
+            nfa_dm_cb.disc_cb.activated_sel_res = p_data->activate.rf_tech_param.param.pa.sel_rsp;
+        }
+
+        if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)
+        {
+            /* Set data callback to receive raw frame */
+            NFC_SetStaticRfCback (nfa_dm_act_data_cback);
+
+            memset (&(evt_data.activated.params), 0x00, sizeof (tNFA_TAG_PARAMS));
+            memcpy (&(evt_data.activated.activate_ntf), &(p_data->activate), sizeof (tNFC_ACTIVATE_DEVT));
+
+            nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data);
+        }
+        else
+        {
+            /* holding activation notification until sub-module is ready */
+            nfa_dm_cb.p_activate_ntf = (UINT8*) GKI_getbuf (sizeof (tNFC_ACTIVATE_DEVT));
+
+            if (nfa_dm_cb.p_activate_ntf)
+            {
+                memcpy (nfa_dm_cb.p_activate_ntf,
+                        &(p_data->activate),
+                        sizeof (tNFC_ACTIVATE_DEVT));
+
+                if (  (nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T1T)
+                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T2T)
+                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T3T)
+                    ||(  (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP)
+                       &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_ISO_DEP) )
+                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFA_PROTOCOL_ISO15693) )
+                {
+                    /* Notify NFA tag sub-system */
+                    nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, FALSE);
+                }
+                else /* if NFC-DEP, ISO-DEP with frame interface or others */
+                {
+                    /* Set data callback to receive raw frame */
+                    NFC_SetStaticRfCback (nfa_dm_act_data_cback);
+                    nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
+                }
+            }
+            else
+            {
+                /* deactivate and restart RF discovery */
+                nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+            }
+        }
+        break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+
+        /* clear stored NFCID/UID */
+        nfa_dm_cb.activated_nfcid_len = 0;
+
+        if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP)
+        {
+            /* Notify NFA RW sub-systems */
+            nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, FALSE);
+        }
+
+        /* if deactivated as sleep mode */
+        if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
+            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
+        {
+            evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
+        }
+        else
+        {
+            evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        }
+
+        /* notify deactivation to upper layer */
+        nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+
+        /* clean up SEL_RES response */
+        nfa_dm_cb.disc_cb.activated_sel_res = 0;
+        break;
+
+    case NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT:
+        /* DH initiated deactivation in NFA_DM_RFST_W4_HOST_SELECT */
+        /* No need to notify NFA RW sub-systems                    */
+
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        /* notify deactivation to application */
+        nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+        break;
+
+    default:
+        NFA_TRACE_ERROR0 ("Unexpected event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_poll_disc_cback
+**
+** Description      Processing event from discovery callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_poll_disc_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_poll_disc_cback (): event:0x%02X", event);
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISC_START_EVT:
+        break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+
+        if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A)
+        {
+            /* store SEL_RES response */
+            nfa_dm_cb.disc_cb.activated_sel_res = p_data->activate.rf_tech_param.param.pa.sel_rsp;
+        }
+
+        /* holding activation notification until sub-module is ready */
+        nfa_dm_cb.p_activate_ntf = (UINT8*) GKI_getbuf (sizeof (tNFC_ACTIVATE_DEVT));
+
+        if (nfa_dm_cb.p_activate_ntf)
+        {
+            memcpy (nfa_dm_cb.p_activate_ntf,
+                    &(p_data->activate),
+                    sizeof (tNFC_ACTIVATE_DEVT));
+
+            if (  (nfa_dm_cb.disc_cb.activated_protocol     == NFC_PROTOCOL_NFC_DEP)
+                &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_NFC_DEP)  )
+            {
+                /* activate LLCP */
+                nfa_p2p_activate_llcp (p_data);
+            }
+            else if (  (nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T1T)
+                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T2T)
+                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T3T)
+                     ||(  (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP)
+                        &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_ISO_DEP)  )
+                     ||(nfa_dm_cb.disc_cb.activated_protocol  == NFA_PROTOCOL_ISO15693)  )
+            {
+                /* Notify NFA tag sub-system */
+                nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, TRUE);
+            }
+            else /* if NFC-DEP/ISO-DEP with frame interface */
+            {
+                /* Set data callback to receive raw frame */
+                NFC_SetStaticRfCback (nfa_dm_act_data_cback);
+                nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
+            }
+        }
+        else
+        {
+            /* deactivate and restart RF discovery */
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+        }
+        break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+
+        /* clear stored NFCID/UID */
+        nfa_dm_cb.activated_nfcid_len = 0;
+
+        if (  (nfa_dm_cb.disc_cb.activated_protocol     == NFC_PROTOCOL_NFC_DEP)
+            &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_NFC_DEP)  )
+        {
+            /*
+            ** If LLCP link is not deactivated yet,
+            ** LLCP will receive deactivation ntf through data callback.
+            ** NFA P2P will receive callback event from LLCP.
+            */
+        }
+        else
+        {
+            /* Notify NFA RW sub-systems */
+            nfa_rw_proc_disc_evt (NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, TRUE);
+        }
+
+        /* if NFA sent NFA_ACTIVATED_EVT earlier */
+        if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_DEACTIVATED_EVT)
+        {
+            nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
+
+            /* if deactivated as sleep mode */
+            if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
+                ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
+            {
+                evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
+            }
+            else
+            {
+                evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+            }
+            /* notify deactivation to application */
+            nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+        }
+
+        /* clean up SEL_RES response */
+        nfa_dm_cb.disc_cb.activated_sel_res = 0;
+
+        if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED))
+        {
+            /* deregister discovery callback from NFA DM Discovery */
+            nfa_dm_delete_rf_discover (nfa_dm_cb.poll_disc_handle);
+            nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+
+            /* this is for disable polling */
+            if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_POLL_STOP_EVT)
+            {
+                nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
+
+                evt_data.status = NFA_STATUS_OK;
+                nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
+            }
+        }
+
+        break;
+
+    case NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT:
+        /* DH initiated deactivation in NFA_DM_RFST_W4_HOST_SELECT */
+        /* No need to notify NFA RW sub-systems                    */
+
+        /* clear stored NFCID/UID */
+        nfa_dm_cb.activated_nfcid_len = 0;
+        /* clean up SEL_RES response */
+        nfa_dm_cb.disc_cb.activated_sel_res = 0;
+
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        /* notify deactivation to application */
+        nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+
+        if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED))
+        {
+            /* deregister discovery callback from NFA DM Discovery */
+            nfa_dm_delete_rf_discover (nfa_dm_cb.poll_disc_handle);
+            nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+
+            /* this is for disable polling */
+            if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_POLL_STOP_EVT)
+            {
+                nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
+
+                evt_data.status = NFA_STATUS_OK;
+                nfa_dm_conn_cback_event_notify (NFA_POLL_DISABLED_EVT, &evt_data);
+            }
+        }
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_notify_activation_status
+**
+** Description      Processing activation status from sub-modules
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_dm_notify_activation_status (tNFA_STATUS status, tNFA_TAG_PARAMS *p_params)
+{
+    tNFA_CONN_EVT_DATA  evt_data;
+    tNFC_RF_TECH_PARAMS *p_tech_params;
+    UINT8               *p_nfcid = NULL, nfcid_len;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_notify_activation_status (): status:0x%X", status);
+
+    if (!nfa_dm_cb.p_activate_ntf)
+    {
+        /* this is for NFA P2P listen */
+        return;
+    }
+
+    if (status == NFA_STATUS_OK)
+    {
+        /* notify NFC link activation */
+        memcpy ( &(evt_data.activated.activate_ntf),
+                 nfa_dm_cb.p_activate_ntf,
+                 sizeof (tNFC_ACTIVATE_DEVT));
+
+        p_tech_params = &evt_data.activated.activate_ntf.rf_tech_param;
+
+        if (p_params)
+        {
+            memcpy (&(evt_data.activated.params),
+                    p_params,
+                    sizeof (tNFA_TAG_PARAMS));
+        }
+
+        /* get length of NFCID and location */
+        if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_A)
+        {
+            nfcid_len = p_tech_params->param.pa.nfcid1_len;
+            p_nfcid   = p_tech_params->param.pa.nfcid1;
+        }
+        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_B)
+        {
+            nfcid_len = NFC_NFCID0_MAX_LEN;
+            p_nfcid   = p_tech_params->param.pb.nfcid0;
+        }
+        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_F)
+        {
+            nfcid_len = NFC_NFCID2_LEN;
+            p_nfcid   = p_tech_params->param.pf.nfcid2;
+        }
+        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_ISO15693)
+        {
+            nfcid_len = NFC_ISO15693_UID_LEN;
+            p_nfcid   = p_tech_params->param.pi93.uid;
+        }
+        else
+        {
+            nfcid_len = 0;
+        }
+
+        /*
+        ** If not in exlusive RF mode, and
+        **      P2P activation, then push default NDEF message through SNEP
+        **      TAG activation, then read NDEF message
+        */
+        if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP)
+        {
+            /*
+            ** Default NDEF message will be put to NFC Forum defualt SNEP server
+            ** after receiving NFA_LLCP_ACTIVATED_EVT.
+            */
+        }
+        /* Do not perform NDEF operations on KOVIO */
+        else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_KOVIO)
+        {
+            NFA_TRACE_DEBUG1 ("Not an NFC-Forum tag, bypassing NDEF detection", nfa_dm_cb.disc_cb.activated_protocol);
+        }
+        else if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))
+        {
+            /*
+            ** if the same tag is activated then do not perform auto NDEF detection.
+            ** Application may put a tag into sleep mode and reactivate the same tag.
+            */
+
+            if (  (p_tech_params->mode != nfa_dm_cb.disc_cb.activated_tech_mode)
+                ||(nfcid_len != nfa_dm_cb.activated_nfcid_len)
+                ||(memcmp (p_nfcid, nfa_dm_cb.activated_nfcid, nfcid_len)))
+            {
+                if (  (nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T1T)
+                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T2T)
+                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFC_PROTOCOL_T3T)
+                    ||(  (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP)
+                       &&(nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_ISO_DEP)  )
+                    ||(nfa_dm_cb.disc_cb.activated_protocol  == NFA_PROTOCOL_ISO15693)  )
+                {
+                    if (p_nfa_dm_cfg->auto_detect_ndef)
+                    {
+                        if (p_nfa_dm_cfg->auto_read_ndef)
+                        {
+                            nfa_dm_cb.flags |= NFA_DM_FLAGS_AUTO_READING_NDEF;
+                        }
+                        NFA_RwDetectNDef ();
+                    }
+                    else if (p_nfa_dm_cfg->auto_read_ndef)
+                    {
+                        NFA_RwReadNDef ();
+                    }
+                }
+            }
+        }
+
+        /* store activated tag information */
+        nfa_dm_cb.activated_nfcid_len = nfcid_len;
+        if (nfcid_len)
+            memcpy (nfa_dm_cb.activated_nfcid, p_nfcid, nfcid_len);
+
+        nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
+        nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data);
+    }
+    else
+    {
+        /* if NFC_DEP, NFA P2P will deactivate */
+        if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP)
+        {
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+        }
+    }
+
+    GKI_freebuf (nfa_dm_cb.p_activate_ntf);
+    nfa_dm_cb.p_activate_ntf = NULL;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_nfc_revt_2_str
+**
+** Description      convert nfc revt to string
+**
+*******************************************************************************/
+char *nfa_dm_nfc_revt_2_str (tNFC_RESPONSE_EVT event)
+{
+    switch (event) {
+    case NFC_ENABLE_REVT:
+        return "NFC_ENABLE_REVT";
+
+    case NFC_DISABLE_REVT:
+        return "NFC_DISABLE_REVT";
+
+    case NFC_SET_CONFIG_REVT:
+        return "NFC_SET_CONFIG_REVT";
+
+    case NFC_GET_CONFIG_REVT:
+        return "NFC_GET_CONFIG_REVT";
+
+    case NFC_NFCEE_DISCOVER_REVT:
+        return "NFC_NFCEE_DISCOVER_REVT";
+
+    case NFC_NFCEE_INFO_REVT:
+        return "NFC_NFCEE_INFO_REVT";
+
+    case NFC_NFCEE_MODE_SET_REVT:
+        return "NFC_NFCEE_MODE_SET_REVT";
+
+    case NFC_RF_FIELD_REVT:
+        return "NFC_RF_FIELD_REVT";
+
+    case NFC_EE_ACTION_REVT:
+        return "NFC_EE_ACTION_REVT";
+
+    case NFC_EE_DISCOVER_REQ_REVT:
+        return "NFC_EE_DISCOVER_REQ_REVT";
+
+    case NFC_SET_ROUTING_REVT:
+        return "NFC_SET_ROUTING_REVT";
+
+    case NFC_GET_ROUTING_REVT:
+        return "NFC_GET_ROUTING_REVT";
+
+    case NFC_GEN_ERROR_REVT:
+        return "NFC_GEN_ERROR_REVT";
+
+    case NFC_NFCC_RESTART_REVT:
+        return "NFC_NFCC_RESTART_REVT";
+
+    case NFC_NFCC_TIMEOUT_REVT:
+        return "NFC_NFCC_TIMEOUT_REVT";
+
+    case NFC_NFCC_TRANSPORT_ERR_REVT:
+        return "NFC_NFCC_TRANSPORT_ERR_REVT";
+
+    case NFC_NFCC_POWER_OFF_REVT:
+        return "NFC_NFCC_POWER_OFF_REVT";
+
+    default:
+        return "unknown revt";
+        break;
+    }
+}
+#endif /* BT_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_api.c b/src/nfa/dm/nfa_dm_api.c
new file mode 100644
index 0000000..139062f
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_api.c
@@ -0,0 +1,1050 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for device management
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#include "nfa_ce_int.h"
+#include "nfa_sys_int.h"
+#include "ndef_utils.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function         NFA_Init
+**
+** Description      This function initializes control blocks for NFA
+**
+**                  p_hal_entry_tbl points to a table of HAL entry points
+**
+**                  NOTE: the buffer that p_hal_entry_tbl points must be
+**                  persistent until NFA is disabled.
+**
+** Returns          none
+**
+*******************************************************************************/
+void NFA_Init(tHAL_NFC_ENTRY *p_hal_entry_tbl)
+{
+    NFA_TRACE_API0 ("NFA_Init ()");
+    nfa_sys_init();
+    nfa_dm_init();
+    nfa_ee_init();
+    nfa_p2p_init();
+    nfa_cho_init();
+    nfa_snep_init(FALSE);
+    nfa_rw_init();
+    nfa_ce_init();
+    nfa_hci_init();
+
+
+    /* Initialize NFC module */
+    NFC_Init (p_hal_entry_tbl);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Enable
+**
+** Description      This function enables NFC. Prior to calling NFA_Enable,
+**                  the NFCC must be powered up, and ready to receive commands.
+**                  This function enables the tasks needed by NFC, opens the NCI
+**                  transport, resets the NFC controller, downloads patches to
+**                  the NFCC (if necessary), and initializes the NFC subsystems.
+**
+**                  This function should only be called once - typically when NFC
+**                  is enabled during boot-up, or when NFC is enabled from a
+**                  settings UI. Subsequent calls to NFA_Enable while NFA is
+**                  enabling or enabled will be ignored. When the NFC startup
+**                  procedure is completed, an NFA_DM_ENABLE_EVT is returned to the
+**                  application using the tNFA_DM_CBACK.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Enable (tNFA_DM_CBACK        *p_dm_cback,
+                        tNFA_CONN_CBACK      *p_conn_cback)
+{
+    tNFA_DM_API_ENABLE *p_msg;
+
+    NFA_TRACE_API0 ("NFA_Enable ()");
+
+    /* Validate parameters */
+    if ((!p_dm_cback) || (!p_conn_cback))
+    {
+        NFA_TRACE_ERROR0 ("NFA_Enable (): error null callback");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_DM_API_ENABLE *) GKI_getbuf (sizeof (tNFA_DM_API_ENABLE))) != NULL)
+    {
+        p_msg->hdr.event    = NFA_DM_API_ENABLE_EVT;
+        p_msg->p_dm_cback   = p_dm_cback;
+        p_msg->p_conn_cback = p_conn_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Disable
+**
+** Description      This function is called to shutdown NFC. The tasks for NFC
+**                  are terminated, and clean up routines are performed. This
+**                  function is typically called during platform shut-down, or
+**                  when NFC is disabled from a settings UI. When the NFC
+**                  shutdown procedure is completed, an NFA_DM_DISABLE_EVT is
+**                  returned to the application using the tNFA_DM_CBACK.
+**
+**                  The platform should wait until the NFC_DISABLE_REVT is
+**                  received before powering down the NFC chip and NCI transport.
+**                  This is required to so that NFA can gracefully shut down any
+**                  open connections.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Disable (BOOLEAN graceful)
+{
+    tNFA_DM_API_DISABLE *p_msg;
+
+    NFA_TRACE_API1 ("NFA_Disable (graceful=%i)", graceful);
+
+    if ((p_msg = (tNFA_DM_API_DISABLE *) GKI_getbuf (sizeof (tNFA_DM_API_DISABLE))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_DISABLE_EVT;
+        p_msg->graceful  = graceful;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetConfig
+**
+** Description      Set the configuration parameters to NFCC. The result is
+**                  reported with an NFA_DM_SET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function. Most Configuration
+**                  parameters are related to RF discovery.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BUSY if previous setting is on-going
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetConfig (tNFA_PMID param_id,
+                           UINT8     length,
+                           UINT8    *p_data)
+{
+    tNFA_DM_API_SET_CONFIG *p_msg;
+
+    NFA_TRACE_API1 ("NFA_SetConfig (): param_id:0x%X", param_id);
+
+    if ((p_msg = (tNFA_DM_API_SET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_SET_CONFIG) + length))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_SET_CONFIG_EVT;
+
+        p_msg->param_id = param_id;
+        p_msg->length   = length;
+        p_msg->p_data   = (UINT8 *) (p_msg + 1);
+
+        /* Copy parameter data */
+        memcpy (p_msg->p_data, p_data, length);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_GetConfig
+**
+** Description      Get the configuration parameters from NFCC. The result is
+**                  reported with an NFA_DM_GET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_GetConfig (UINT8 num_ids,
+                           tNFA_PMID *p_param_ids)
+{
+    tNFA_DM_API_GET_CONFIG *p_msg;
+
+    NFA_TRACE_API1 ("NFA_GetConfig (): num_ids: %i", num_ids);
+
+
+    if ((p_msg = (tNFA_DM_API_GET_CONFIG *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_GET_CONFIG) + num_ids))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_GET_CONFIG_EVT;
+
+        p_msg->num_ids = num_ids;
+        p_msg->p_pmids = (tNFA_PMID *) (p_msg+1);
+
+        /* Copy the param IDs */
+        memcpy (p_msg->p_pmids, p_param_ids, num_ids);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RequestExclusiveRfControl
+**
+** Description      Request exclusive control of NFC.
+**                  - Previous behavior (polling/tag reading, DH card emulation)
+**                    will be suspended .
+**                  - Polling and listening will be done based on the specified
+**                    params
+**
+**                  The NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT event of
+**                  tNFA_CONN_CBACK indicates the status of the operation.
+**
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT indicates link
+**                  activation/deactivation.
+**
+**                  NFA_SendRawFrame is used to send data to the peer. NFA_DATA_EVT
+**                  indicates data from the peer.
+**
+**                  If a tag is activated, then the NFA_RW APIs may be used to
+**                  send commands to the tag. Incoming NDEF messages are sent to
+**                  the NDEF callback.
+**
+**                  Once exclusive RF control has started, NFA will not activate
+**                  LLCP internally. The application has exclusive control of
+**                  the link.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RequestExclusiveRfControl  (tNFA_TECHNOLOGY_MASK poll_mask,
+                                            tNFA_LISTEN_CFG      *p_listen_cfg,
+                                            tNFA_CONN_CBACK      *p_conn_cback,
+                                            tNFA_NDEF_CBACK      *p_ndef_cback)
+{
+    tNFA_DM_API_REQ_EXCL_RF_CTRL *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RequestExclusiveRfControl () poll_mask=0x%x", poll_mask);
+
+    if (!p_conn_cback)
+    {
+        NFA_TRACE_ERROR0 ("NFA_RequestExclusiveRfControl (): error null callback");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_DM_API_REQ_EXCL_RF_CTRL *) GKI_getbuf (sizeof (tNFA_DM_API_REQ_EXCL_RF_CTRL))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT;
+        p_msg->poll_mask    = poll_mask;
+        p_msg->p_conn_cback = p_conn_cback;
+        p_msg->p_ndef_cback = p_ndef_cback;
+
+        if (p_listen_cfg)
+            memcpy (&p_msg->listen_cfg, p_listen_cfg, sizeof (tNFA_LISTEN_CFG));
+        else
+            memset (&p_msg->listen_cfg, 0x00, sizeof (tNFA_LISTEN_CFG));
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_ReleaseExclusiveRfControl
+**
+** Description      Release exclusive control of NFC. Once released, behavior
+**                  prior to obtaining exclusive RF control will resume.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_ReleaseExclusiveRfControl (void)
+{
+    BT_HDR *p_msg;
+
+    NFA_TRACE_API0 ("NFA_ReleaseExclusiveRfControl ()");
+
+    if (!nfa_dm_cb.p_excl_conn_cback)
+    {
+        NFA_TRACE_ERROR0 ("NFA_ReleaseExclusiveRfControl (): Exclusive rf control is not in progress");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+    {
+        p_msg->event = NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT;
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_EnablePolling
+**
+** Description      Enable polling for technologies specified by poll_mask.
+**
+**                  The following events (notified using the connection
+**                  callback registered with NFA_Enable) are generated during
+**                  polling:
+**
+**                  - NFA_POLL_ENABLED_EVT indicates whether or not polling
+**                    successfully enabled.
+**                  - NFA_DISC_RESULT_EVT indicates there are more than one devices,
+**                    so application must select one of tags by calling NFA_Select().
+**                  - NFA_SELECT_RESULT_EVT indicates whether previous selection was
+**                    successful or not. If it was failed then application must select
+**                    again or deactivate by calling NFA_Deactivate().
+**                  - NFA_ACTIVATED_EVT is generated when an NFC link is activated.
+**                  - NFA_NDEF_DETECT_EVT is generated if tag is activated
+**                  - NFA_LLCP_ACTIVATED_EVT/NFA_LLCP_DEACTIVATED_EVT is generated
+**                    if NFC-DEP is activated
+**                  - NFA_DEACTIVATED_EVT will be returned after deactivating NFC link.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EnablePolling (tNFA_TECHNOLOGY_MASK poll_mask)
+{
+    tNFA_DM_API_ENABLE_POLL *p_msg;
+
+    NFA_TRACE_API1 ("NFA_EnablePolling () 0x%X", poll_mask);
+
+    if ((p_msg = (tNFA_DM_API_ENABLE_POLL *) GKI_getbuf (sizeof (tNFA_DM_API_ENABLE_POLL))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_ENABLE_POLLING_EVT;
+        p_msg->poll_mask = poll_mask;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_DisablePolling
+**
+** Description      Disable polling
+**                  NFA_POLL_DISABLED_EVT will be returned after stopping polling.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_DisablePolling (void)
+{
+    BT_HDR *p_msg;
+
+    NFA_TRACE_API0 ("NFA_DisablePolling ()");
+
+    if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+    {
+        p_msg->event = NFA_DM_API_DISABLE_POLLING_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetP2pListenTech
+**
+** Description      This function is called to set listen technology for NFC-DEP.
+**                  This funtion may be called before or after starting any server
+**                  on NFA P2P/CHO/SNEP.
+**                  If there is no technology for NFC-DEP, P2P listening will be
+**                  stopped.
+**
+**                  NFA_SET_P2P_LISTEN_TECH_EVT without data will be returned.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetP2pListenTech (tNFA_TECHNOLOGY_MASK tech_mask)
+{
+    tNFA_DM_API_SET_P2P_LISTEN_TECH *p_msg;
+
+    NFA_TRACE_API1 ("NFA_P2pSetListenTech (): tech_mask:0x%X", tech_mask);
+
+    if ((p_msg = (tNFA_DM_API_SET_P2P_LISTEN_TECH *) GKI_getbuf (sizeof (tNFA_DM_API_SET_P2P_LISTEN_TECH))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_SET_P2P_LISTEN_TECH_EVT;
+        p_msg->tech_mask = tech_mask;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_StartRfDiscovery
+**
+** Description      Start RF discovery
+**                  RF discovery parameters shall be set by other APIs.
+**
+**                  An NFA_RF_DISCOVERY_STARTED_EVT indicates whether starting was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_StartRfDiscovery (void)
+{
+    BT_HDR *p_msg;
+
+    NFA_TRACE_API0 ("NFA_StartRfDiscovery ()");
+
+    if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+    {
+        p_msg->event = NFA_DM_API_START_RF_DISCOVERY_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_StopRfDiscovery
+**
+** Description      Stop RF discovery
+**
+**                  An NFA_RF_DISCOVERY_STOPPED_EVT indicates whether stopping was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_StopRfDiscovery (void)
+{
+    BT_HDR *p_msg;
+
+    NFA_TRACE_API0 ("NFA_StopRfDiscovery ()");
+
+    if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+    {
+        p_msg->event = NFA_DM_API_STOP_RF_DISCOVERY_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetRfDiscoveryDuration
+**
+** Description      Set the duration of the single discovery period in [ms].
+**                  Allowable range: 0 ms to 0xFFFF ms.
+**
+**                  If discovery is already started, the application should
+**                  call NFA_StopRfDiscovery prior to calling
+**                  NFA_SetRfDiscoveryDuration, and then call
+**                  NFA_StartRfDiscovery afterwards to restart discovery using
+**                  the new duration.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SetRfDiscoveryDuration (UINT16 discovery_period_ms)
+{
+    tNFA_DM_API_SET_RF_DISC_DUR *p_msg;
+
+    NFA_TRACE_API0 ("NFA_SetRfDiscoveryDuration ()");
+
+    /* Post the API message */
+    if ((p_msg = (tNFA_DM_API_SET_RF_DISC_DUR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_SET_RF_DISC_DURATION_EVT;
+
+        /* Set discovery duration */
+        p_msg->rf_disc_dur_ms = discovery_period_ms;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Select
+**
+** Description      Select one from detected devices during discovery
+**                  (from NFA_DISC_RESULT_EVTs). The application should wait for
+**                  the final NFA_DISC_RESULT_EVT before selecting.
+**
+**                  An NFA_SELECT_RESULT_EVT indicates whether selection was successful or not.
+**                  If failed then application must select again or deactivate by NFA_Deactivate().
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if RF interface is not matched protocol
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_Select (UINT8             rf_disc_id,
+                        tNFA_NFC_PROTOCOL protocol,
+                        tNFA_INTF_TYPE    rf_interface)
+{
+    tNFA_DM_API_SELECT *p_msg;
+
+    NFA_TRACE_API3 ("NFA_Select (): rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
+                    rf_disc_id, protocol, rf_interface);
+
+    if (  ((rf_interface == NFA_INTERFACE_ISO_DEP) && (protocol != NFA_PROTOCOL_ISO_DEP))
+        ||((rf_interface == NFA_INTERFACE_NFC_DEP) && (protocol != NFA_PROTOCOL_NFC_DEP))  )
+    {
+        NFA_TRACE_ERROR0 ("NFA_Select (): RF interface is not matched protocol");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_DM_API_SELECT *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_SELECT)))) != NULL)
+    {
+        p_msg->hdr.event     = NFA_DM_API_SELECT_EVT;
+        p_msg->rf_disc_id    = rf_disc_id;
+        p_msg->protocol      = protocol;
+        p_msg->rf_interface  = rf_interface;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication parameters
+**                  once the Frame RF Interface has been activated.
+**
+**                  An NFA_UPDATE_RF_PARAM_RESULT_EVT indicates whether updating
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_UpdateRFCommParams (tNFA_RF_COMM_PARAMS *p_params)
+{
+    tNFA_DM_API_UPDATE_RF_PARAMS *p_msg;
+
+    NFA_TRACE_API0 ("NFA_UpdateRFCommParams ()");
+
+    if ((p_msg = (tNFA_DM_API_UPDATE_RF_PARAMS *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_UPDATE_RF_PARAMS)))) != NULL)
+    {
+        p_msg->hdr.event     = NFA_DM_API_UPDATE_RF_PARAMS_EVT;
+        memcpy (&p_msg->params, p_params, sizeof (tNFA_RF_COMM_PARAMS));
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_Deactivate
+**
+** Description
+**                  If sleep_mode=TRUE:
+**                      Deselect the activated device by deactivating into sleep mode.
+**
+**                      An NFA_DEACTIVATE_FAIL_EVT indicates that selection was not successful.
+**                      Application can select another discovered device or deactivate by NFA_Deactivate ()
+**                      after receiving NFA_DEACTIVATED_EVT.
+**
+**                      Deactivating to sleep mode is not allowed when NFCC is in wait-for-host-select
+**                      mode, or in listen-sleep states; NFA will deactivate to idle or discovery state
+**                      for these cases respectively.
+**
+**
+**                  If sleep_mode=FALSE:
+**                      Deactivate the connection (e.g. as a result of presence check failure)
+**                      NFA_DEACTIVATED_EVT will indicate that link is deactivated.
+**                      Polling/listening will resume (unless the nfcc is in wait_for-all-discoveries state)
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Deactivate (BOOLEAN sleep_mode)
+{
+    tNFA_DM_API_DEACTIVATE *p_msg;
+
+    NFA_TRACE_API1 ("NFA_Deactivate (): sleep_mode:%i", sleep_mode);
+
+    if ((p_msg = (tNFA_DM_API_DEACTIVATE *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_DEACTIVATE)))) != NULL)
+    {
+        p_msg->hdr.event    = NFA_DM_API_DEACTIVATE_EVT;
+        p_msg->sleep_mode   = sleep_mode;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SendRawFrame
+**
+** Description      Send a raw frame over the activated interface with the NFCC.
+**                  This function can only be called after NFC link is activated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendRawFrame (UINT8  *p_raw_data,
+                              UINT16  data_len)
+{
+    BT_HDR *p_msg;
+    UINT16  size;
+    UINT8  *p;
+
+    NFA_TRACE_API1 ("NFA_SendRawFrame () data_len:%d", data_len);
+
+    /* Validate parameters */
+    if ((data_len == 0) || (p_raw_data == NULL))
+        return (NFA_STATUS_INVALID_PARAM);
+
+    size = BT_HDR_SIZE + NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + data_len;
+    if ((p_msg = (BT_HDR *) GKI_getbuf (size)) != NULL)
+    {
+        p_msg->event  = NFA_DM_API_RAW_FRAME_EVT;
+        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+        p_msg->len    = data_len;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        memcpy (p, p_raw_data, data_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+** NDEF Handler APIs
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefTypeHandler
+**
+** Description      This function allows the applications to register for
+**                  specific types of NDEF records. When NDEF records are
+**                  received, NFA will parse the record-type field, and pass
+**                  the record to the registered tNFA_NDEF_CBACK.
+**
+**                  For records types which were not registered, the record will
+**                  be sent to the default handler. A default type-handler may
+**                  be registered by calling this NFA_RegisterNDefTypeHandler
+**                  with tnf=NFA_TNF_DEFAULT. In this case, all un-registered
+**                  record types will be sent to the callback. Only one default
+**                  handler may be registered at a time.
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this record type.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RegisterNDefTypeHandler (BOOLEAN         handle_whole_message,
+                                         tNFA_TNF        tnf,
+                                         UINT8           *p_type_name,
+                                         UINT8           type_name_len,
+                                         tNFA_NDEF_CBACK *p_ndef_cback)
+{
+    tNFA_DM_API_REG_NDEF_HDLR *p_msg;
+
+    NFA_TRACE_API2 ("NFA_RegisterNDefTypeHandler (): handle whole ndef message: %i, tnf=0x%02x", handle_whole_message, tnf);
+
+    /* Check for NULL callback */
+    if (!p_ndef_cback)
+    {
+        NFA_TRACE_ERROR0 ("NFA_RegisterNDefTypeHandler (): error - null callback");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+
+    if ((p_msg = (tNFA_DM_API_REG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_REG_NDEF_HDLR) + type_name_len))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT;
+
+        p_msg->flags = (handle_whole_message ? NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE : 0);
+        p_msg->tnf = tnf;
+        p_msg->name_len = type_name_len;
+        p_msg->p_ndef_cback = p_ndef_cback;
+        memcpy (p_msg->name, p_type_name, type_name_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefUriHandler
+**
+** Description      This API is a special-case of NFA_RegisterNDefTypeHandler
+**                  with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and allows
+**                  registering for specific URI types (e.g. 'tel:' or 'mailto:').
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this registration.
+**
+**                  If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains the
+**                  unabridged URI. For all other uri_id values, the p_abs_uri
+**                  parameter is ignored (i.e the URI prefix is implied by uri_id).
+**                  See [NFC RTD URI] for more information.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RegisterNDefUriHandler (BOOLEAN          handle_whole_message,
+                                                       tNFA_NDEF_URI_ID uri_id,
+                                                       UINT8            *p_abs_uri,
+                                                       UINT8            uri_id_len,
+                                                       tNFA_NDEF_CBACK  *p_ndef_cback)
+{
+    tNFA_DM_API_REG_NDEF_HDLR *p_msg;
+
+    NFA_TRACE_API2 ("NFA_RegisterNDefUriHandler (): handle whole ndef message: %i, uri_id=0x%02x", handle_whole_message, uri_id);
+
+    /* Check for NULL callback */
+    if (!p_ndef_cback)
+    {
+        NFA_TRACE_ERROR0 ("NFA_RegisterNDefUriHandler (): error - null callback");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+
+    if ((p_msg = (tNFA_DM_API_REG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_REG_NDEF_HDLR) + uri_id_len))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_REG_NDEF_HDLR_EVT;
+
+        p_msg->flags = NFA_NDEF_FLAGS_WKT_URI;
+
+        if (handle_whole_message)
+        {
+            p_msg->flags |= NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE;
+        }
+
+        /* abs_uri is only valid fir uri_id=NFA_NDEF_URI_ID_ABSOLUTE */
+        if (uri_id != NFA_NDEF_URI_ID_ABSOLUTE)
+        {
+            uri_id_len = 0;
+        }
+
+        p_msg->tnf = NFA_TNF_WKT;
+        p_msg->uri_id = uri_id;
+        p_msg->name_len = uri_id_len;
+        p_msg->p_ndef_cback = p_ndef_cback;
+        memcpy (p_msg->name, p_abs_uri, uri_id_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_DeregisterNDefTypeHandler
+**
+** Description      Deregister NDEF record type handler.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DeregisterNDefTypeHandler (tNFA_HANDLE ndef_type_handle)
+{
+    tNFA_DM_API_DEREG_NDEF_HDLR *p_msg;
+
+    NFA_TRACE_API1 ("NFA_DeregisterNDefHandler (): handle 0x%08x", ndef_type_handle);
+
+
+    if ((p_msg = (tNFA_DM_API_DEREG_NDEF_HDLR *) GKI_getbuf ((UINT16) (sizeof (tNFA_DM_API_DEREG_NDEF_HDLR)))) != NULL)
+    {
+        p_msg->hdr.event = NFA_DM_API_DEREG_NDEF_HDLR_EVT;
+        p_msg->ndef_type_handle = ndef_type_handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_PowerOffSleepMode
+**
+** Description      This function is called to enter or leave NFCC Power Off Sleep mode
+**                  NFA_DM_PWR_MODE_CHANGE_EVT will be sent to indicate status.
+**
+**                  start_stop : TRUE if entering Power Off Sleep mode
+**                               FALSE if leaving Power Off Sleep mode
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_PowerOffSleepMode (BOOLEAN start_stop)
+{
+    BT_HDR *p_msg;
+
+    NFA_TRACE_API1 ("NFA_PowerOffSleepState () start_stop=%d", start_stop);
+
+    if (nfa_dm_cb.flags & NFA_DM_FLAGS_SETTING_PWR_MODE)
+    {
+        NFA_TRACE_ERROR0 ("NFA_PowerOffSleepState (): NFA DM is busy to update power mode");
+        return (NFA_STATUS_FAILED);
+    }
+    else
+    {
+        nfa_dm_cb.flags |= NFA_DM_FLAGS_SETTING_PWR_MODE;
+    }
+
+    if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+    {
+        p_msg->event          = NFA_DM_API_POWER_OFF_SLEEP_EVT;
+        p_msg->layer_specific = start_stop;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RegVSCback
+**
+** Description      This function is called to register or de-register a callback
+**                  function to receive Proprietary NCI response and notification
+**                  events.
+**                  The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFA_RegVSCback (BOOLEAN          is_register,
+                            tNFA_VSC_CBACK   *p_cback)
+{
+    tNFA_DM_API_REG_VSC *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RegVSCback() is_register=%d", is_register);
+
+    if (p_cback == NULL)
+    {
+        NFA_TRACE_ERROR0 ("NFA_RegVSCback() requires a valid callback function");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_DM_API_REG_VSC *) GKI_getbuf (sizeof(tNFA_DM_API_REG_VSC))) != NULL)
+    {
+        p_msg->hdr.event        = NFA_DM_API_REG_VSC_EVT;
+        p_msg->is_register      = is_register;
+        p_msg->p_cback          = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SendVsCommand
+**
+** Description      This function is called to send an NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  oid             - The opcode of the VS command.
+**                  cmd_params_len  - The command parameter len
+**                  p_cmd_params    - The command parameter
+**                  p_cback         - The callback function to receive the command
+**                                    status
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SendVsCommand (UINT8            oid,
+                               UINT8            cmd_params_len,
+                               UINT8            *p_cmd_params,
+                               tNFA_VSC_CBACK    *p_cback)
+{
+    tNFA_DM_API_SEND_VSC *p_msg;
+    UINT16  size = sizeof(tNFA_DM_API_SEND_VSC) + cmd_params_len;
+
+    NFA_TRACE_API1 ("NFA_SendVsCommand() oid=0x%x", oid);
+
+    if ((p_msg = (tNFA_DM_API_SEND_VSC *) GKI_getbuf (size)) != NULL)
+    {
+        p_msg->hdr.event        = NFA_DM_API_SEND_VSC_EVT;
+        p_msg->oid              = oid;
+        p_msg->p_cback          = p_cback;
+        if (cmd_params_len && p_cmd_params)
+        {
+            p_msg->cmd_params_len   = cmd_params_len;
+            p_msg->p_cmd_params     = (UINT8 *)(p_msg + 1);
+            memcpy (p_msg->p_cmd_params, p_cmd_params, cmd_params_len);
+        }
+        else
+        {
+            p_msg->cmd_params_len   = 0;
+            p_msg->p_cmd_params     = NULL;
+        }
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SetTraceLevel
+**
+** Description      This function sets the trace level for NFA.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFA_SetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        nfa_sys_set_trace_level (new_level);
+
+    return (nfa_sys_cb.trace_level);
+}
+
diff --git a/src/nfa/dm/nfa_dm_cfg.c b/src/nfa/dm/nfa_dm_cfg.c
new file mode 100644
index 0000000..58d8ace
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_cfg.c
@@ -0,0 +1,91 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for NFA modules
+ *
+ ******************************************************************************/
+#include "nfa_api.h"
+
+/* the SetConfig for CE T3T/T4T */
+const UINT8 nfa_dm_ce_cfg[] =
+{
+    13,                         /* total length */
+    NFC_PMID_LF_T3T_PMM,        /* Type-3 tag default PMM */
+    NCI_PARAM_LEN_LF_T3T_PMM,
+    0x20,
+    0x79,
+    0xFF,
+    0xFF,
+    0xFF,
+    0xFF,
+    0xFF,
+    0xFF,
+    NFC_PMID_FWI,               /* FWI for ISO-DEP */
+    1,
+    CE_T4T_ISO_DEP_FWI
+};
+
+UINT8 *p_nfa_dm_ce_cfg = (UINT8 *) nfa_dm_ce_cfg;
+
+/* the SetConfig for optional general NFC stack functions */
+const UINT8 nfa_dm_gen_cfg[] =
+{
+    3,                         /* total length */
+    NFC_PMID_RF_FIELD_INFO,     /* Instruct NFCC to report RF field generated by remote device (or not) */
+    1,
+    0x01
+};
+
+UINT8 *p_nfa_dm_gen_cfg = NULL;
+
+UINT8 nfa_ee_max_ee_cfg = NFA_EE_MAX_EE_SUPPORTED;
+
+
+const tNCI_DISCOVER_MAPS nfa_dm_interface_mapping[NFA_DM_NUM_INTERFACE_MAP] =
+{
+    /* Protocols that use Frame Interface do not need to be included in the interface mapping */
+    {
+        NCI_PROTOCOL_ISO_DEP,
+        NCI_INTERFACE_MODE_POLL_N_LISTEN,
+        NCI_INTERFACE_ISO_DEP
+    },
+    {
+        NCI_PROTOCOL_NFC_DEP,
+        NCI_INTERFACE_MODE_POLL_N_LISTEN,
+        NCI_INTERFACE_NFC_DEP
+    }
+};
+/* set to NULL to use the default mapping set by stack */
+tNCI_DISCOVER_MAPS *p_nfa_dm_interface_mapping = NULL;
+UINT8 nfa_dm_num_dm_interface_mapping = 0;
+
+
+const tNFA_DM_CFG nfa_dm_cfg =
+{
+    NFA_DM_AUTO_DETECT_NDEF,                /* Automatic NDEF detection (when not in exclusive RF mode) */
+    NFA_DM_AUTO_READ_NDEF                   /* Automatic NDEF read (when not in exclusive RF mode)      */
+
+};
+
+tNFA_DM_CFG *p_nfa_dm_cfg = (tNFA_DM_CFG *) &nfa_dm_cfg;
+
+
+
+
diff --git a/src/nfa/dm/nfa_dm_discover.c b/src/nfa/dm/nfa_dm_discover.c
new file mode 100644
index 0000000..82c1406
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_discover.c
@@ -0,0 +1,2442 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions for device manager discovery
+ *  function.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_p2p_int.h"
+#include "nfa_sys_int.h"
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#endif
+#include "nfa_rw_int.h"
+
+/*
+**  static functions
+*/
+
+static UINT8 nfa_dm_get_rf_discover_config (tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
+                                            tNFC_DISCOVER_PARAMS disc_params[],
+                                            UINT8 max_params);
+static tNFA_STATUS nfa_dm_set_rf_listen_mode_config (tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
+static void nfa_dm_set_rf_listen_mode_raw_config (tNFA_DM_DISC_TECH_PROTO_MASK *p_disc_mask);
+static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask (tNFC_RF_TECH_N_MODE tech_n_mode,
+                                                               tNFC_PROTOCOL       protocol);
+static void nfa_dm_notify_discovery (tNFA_DM_RF_DISC_DATA *p_data);
+static tNFA_STATUS nfa_dm_disc_notify_activation (tNFC_DISCOVER *p_data);
+static void nfa_dm_disc_notify_deactivation (tNFA_DM_RF_DISC_SM_EVENT sm_event, tNFC_DISCOVER *p_data);
+static void nfa_dm_disc_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_dm_disc_state_2_str (UINT8 state);
+static char *nfa_dm_disc_event_2_str (UINT8 event);
+#endif
+
+
+/*******************************************************************************
+**
+** Function         nfa_dm_get_rf_discover_config
+**
+** Description      Build RF discovery configurations from tNFA_DM_DISC_TECH_PROTO_MASK
+**
+** Returns          number of RF discovery configurations
+**
+*******************************************************************************/
+static UINT8 nfa_dm_get_rf_discover_config (tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
+                                            tNFC_DISCOVER_PARAMS         disc_params[],
+                                            UINT8 max_params)
+{
+    UINT8 num_params = 0;
+
+    /* Check polling A */
+    if (dm_disc_mask & ( NFA_DM_DISC_MASK_PA_T1T
+                        |NFA_DM_DISC_MASK_PA_T2T
+                        |NFA_DM_DISC_MASK_PA_ISO_DEP
+                        |NFA_DM_DISC_MASK_PA_NFC_DEP
+                        |NFA_DM_DISC_MASK_P_LEGACY) )
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_A;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling B */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_PB_ISO_DEP)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_B;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling F */
+    if (dm_disc_mask & ( NFA_DM_DISC_MASK_PF_T3T
+                        |NFA_DM_DISC_MASK_PF_NFC_DEP) )
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_F;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling A Active mode  */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_PAA_NFC_DEP)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_A_ACTIVE;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling F Active mode  */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_PFA_NFC_DEP)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_F_ACTIVE;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening A */
+    if (dm_disc_mask & ( NFA_DM_DISC_MASK_LA_T1T
+                        |NFA_DM_DISC_MASK_LA_T2T
+                        |NFA_DM_DISC_MASK_LA_ISO_DEP
+                        |NFA_DM_DISC_MASK_LA_NFC_DEP) )
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_A;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening B */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_B;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening F */
+    if (dm_disc_mask & ( NFA_DM_DISC_MASK_LF_T3T
+                        |NFA_DM_DISC_MASK_LF_NFC_DEP) )
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_F;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening A Active mode */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_LAA_NFC_DEP)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening F Active mode */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_LFA_NFC_DEP)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling ISO 15693 */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_P_ISO15693)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_ISO15693;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling B' */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_P_B_PRIME)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_B_PRIME;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check polling KOVIO */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_P_KOVIO)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_POLL_KOVIO;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening ISO 15693 */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_L_ISO15693)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    /* Check listening B' */
+    if (dm_disc_mask & NFA_DM_DISC_MASK_L_B_PRIME)
+    {
+        disc_params[num_params].type      = NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
+        disc_params[num_params].frequency = 1;
+        num_params++;
+
+        if (num_params >= max_params)
+            return num_params;
+    }
+
+    return num_params;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_rf_listen_mode_config
+**
+** Description      Update listening protocol to NFCC
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+static tNFA_STATUS nfa_dm_set_rf_listen_mode_config (tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask)
+{
+    UINT8 params[40], *p;
+    UINT8 platform  = 0;
+    UINT8 sens_info = 0;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_set_rf_listen_mode_config () tech_proto_mask = 0x%08X",
+                       tech_proto_mask);
+
+    /*
+    ** T1T listen     LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
+    ** T2T listen     LA_PROT 0x00
+    ** T3T listen     No bit for T3T in LF_PROT (CE T3T set listen parameters, system code, NFCID2, etc.)
+    ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
+    ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
+    */
+
+    if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T1T)
+    {
+        platform = NCI_PARAM_PLATFORM_T1T;
+    }
+    else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T2T)
+    {
+        /* platform = 0 and sens_info = 0 */
+    }
+    else
+    {
+        if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)
+        {
+            sens_info |= NCI_PARAM_SEL_INFO_ISODEP;
+        }
+
+        if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP)
+        {
+            sens_info |= NCI_PARAM_SEL_INFO_NFCDEP;
+        }
+    }
+
+    p = params;
+
+    /*
+    ** for Listen A
+    **
+    ** Set ATQA 0x0C00 for T1T listen
+    ** If the ATQA values are 0x0000, then the FW will use 0x0400
+    ** which works for ISODEP, T2T and NFCDEP.
+    */
+    if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] == NFA_DM_DISC_HOST_ID_DH)
+    {
+        UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
+        UINT8_TO_STREAM (p, 0x04);
+        UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
+        UINT8_TO_STREAM (p, platform);
+        UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_SEL_INFO);
+        UINT8_TO_STREAM (p, sens_info);
+    }
+    else /* Let NFCC use UICC configuration by configuring with length = 0 */
+    {
+        UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LA_NFCID1);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LA_HIST_BY);
+        UINT8_TO_STREAM (p, 0);
+    }
+
+    /* for Listen B */
+    if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] == NFA_DM_DISC_HOST_ID_DH)
+    {
+        UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_SENSB_INFO);
+        if (tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
+        {
+            UINT8_TO_STREAM (p, NCI_LISTEN_PROTOCOL_ISO_DEP);
+        }
+        else
+        {
+            UINT8_TO_STREAM (p,  0x00);
+        }
+    }
+    else /* Let NFCC use UICC configuration by configuring with length = 0 */
+    {
+        UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LB_NFCID0);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LB_APPDATA);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LB_ADC_FO);
+        UINT8_TO_STREAM (p, 0);
+        UINT8_TO_STREAM (p, NFC_PMID_LB_H_INFO);
+        UINT8_TO_STREAM (p, 0);
+    }
+
+    /* for Listen F */
+    if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] == NFA_DM_DISC_HOST_ID_DH)
+    {
+        UINT8_TO_STREAM (p, NFC_PMID_LF_PROTOCOL);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_PROTOCOL);
+        if (tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP)
+        {
+            UINT8_TO_STREAM (p, NCI_LISTEN_PROTOCOL_NFC_DEP);
+        }
+        else
+        {
+            UINT8_TO_STREAM (p, 0x00);
+        }
+    }
+    else
+    {
+        /* If DH is not listening on T3T, let NFCC use UICC configuration by configuring with length = 0 */
+        if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_T3T) == 0)
+        {
+            UINT8_TO_STREAM (p, NFC_PMID_LF_PROTOCOL);
+            UINT8_TO_STREAM (p, 0);
+            UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_FLAGS2);
+            UINT8_TO_STREAM (p, 0);
+        }
+    }
+
+    if (p > params)
+    {
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+    }
+
+    return NFA_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_total_duration
+**
+** Description      Update total duration to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_set_total_duration (void)
+{
+    UINT8 params[10], *p;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_set_total_duration ()");
+
+    p = params;
+
+    /* for total duration */
+    UINT8_TO_STREAM (p, NFC_PMID_TOTAL_DURATION);
+    UINT8_TO_STREAM (p, NCI_PARAM_LEN_TOTAL_DURATION);
+    UINT16_TO_STREAM (p, nfa_dm_cb.disc_cb.disc_duration);
+
+    if (p > params)
+    {
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_set_rf_listen_mode_raw_config
+**
+** Description      Set raw listen parameters
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_set_rf_listen_mode_raw_config (tNFA_DM_DISC_TECH_PROTO_MASK *p_disc_mask)
+{
+    tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
+    tNFA_LISTEN_CFG  *p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
+    UINT8 params[250], *p, xx;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_set_rf_listen_mode_raw_config ()");
+
+    /*
+    ** Discovery Configuration Parameters for Listen A
+    */
+    if (  (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] == NFA_DM_DISC_HOST_ID_DH)
+        &&(p_cfg->la_enable)  )
+    {
+        p = params;
+
+        UINT8_TO_STREAM (p, NFC_PMID_LA_BIT_FRAME_SDD);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
+        UINT8_TO_STREAM (p, p_cfg->la_bit_frame_sdd);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LA_PLATFORM_CONFIG);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
+        UINT8_TO_STREAM (p, p_cfg->la_platform_config);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LA_SEL_INFO);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LA_SEL_INFO);
+        UINT8_TO_STREAM (p, p_cfg->la_sel_info);
+
+        if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T)
+        {
+            disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
+        }
+        else
+        {
+            /* If T4T or NFCDEP */
+            if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP)
+            {
+                disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
+            }
+
+            if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_NFCDEP)
+            {
+                disc_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+            }
+
+            /* If neither, T4T nor NFCDEP, then its T2T */
+            if (disc_mask == 0)
+            {
+                disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
+            }
+        }
+
+        UINT8_TO_STREAM (p, NFC_PMID_LA_NFCID1);
+        UINT8_TO_STREAM (p, p_cfg->la_nfcid1_len);
+        ARRAY_TO_STREAM (p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
+
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+    }
+
+    /*
+    ** Discovery Configuration Parameters for Listen B
+    */
+    if (  (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] == NFA_DM_DISC_HOST_ID_DH)
+        &&(p_cfg->lb_enable)  )
+    {
+        p = params;
+
+        UINT8_TO_STREAM (p, NFC_PMID_LB_SENSB_INFO);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_SENSB_INFO);
+        UINT8_TO_STREAM (p, p_cfg->lb_sensb_info);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LB_NFCID0);
+        UINT8_TO_STREAM (p, p_cfg->lb_nfcid0_len);
+        ARRAY_TO_STREAM (p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LB_APPDATA);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_APPDATA);
+        ARRAY_TO_STREAM (p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LB_SFGI);
+        UINT8_TO_STREAM (p, 1);
+        UINT8_TO_STREAM (p, p_cfg->lb_adc_fo);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LB_ADC_FO);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LB_ADC_FO);
+        UINT8_TO_STREAM (p, p_cfg->lb_adc_fo);
+
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+
+        if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP)
+        {
+            disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
+        }
+    }
+
+    /*
+    ** Discovery Configuration Parameters for Listen F
+    */
+    if (  (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] == NFA_DM_DISC_HOST_ID_DH)
+        &&(p_cfg->lf_enable)  )
+    {
+        p = params;
+
+        UINT8_TO_STREAM (p, NFC_PMID_LF_CON_BITR_F);
+        UINT8_TO_STREAM (p, 1);
+        UINT8_TO_STREAM (p, p_cfg->lf_con_bitr_f);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LF_PROTOCOL);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_PROTOCOL);
+        UINT8_TO_STREAM (p, p_cfg->lf_protocol_type);
+
+        UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_FLAGS2);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
+        UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
+
+        /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be ignored */
+        for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++)
+        {
+            if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000)
+            {
+                UINT8_TO_STREAM (p, NFC_PMID_LF_T3T_ID1 + xx);
+                UINT8_TO_STREAM (p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
+                ARRAY_TO_STREAM (p, p_cfg->lf_t3t_identifier[xx], NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
+            }
+        }
+
+        UINT8_TO_STREAM (p,  NFC_PMID_LF_T3T_PMM);
+        UINT8_TO_STREAM (p,  NCI_PARAM_LEN_LF_T3T_PMM);
+        ARRAY_TO_STREAM (p,  p_cfg->lf_t3t_pmm, NCI_PARAM_LEN_LF_T3T_PMM);
+
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+
+        if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED)
+        {
+            disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
+        }
+        if (p_cfg->lf_protocol_type & NCI_LISTEN_PROTOCOL_NFC_DEP)
+        {
+            disc_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+        }
+    }
+
+    /*
+    ** Discovery Configuration Parameters for Listen ISO-DEP
+    */
+    if ((disc_mask & (NFA_DM_DISC_MASK_LA_ISO_DEP|NFA_DM_DISC_MASK_LB_ISO_DEP))
+      &&(p_cfg->li_enable))
+    {
+        p = params;
+
+        UINT8_TO_STREAM (p, NFC_PMID_FWI);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_FWI);
+        UINT8_TO_STREAM (p, p_cfg->li_fwi);
+
+        if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP)
+        {
+            UINT8_TO_STREAM (p, NFC_PMID_LA_HIST_BY);
+            UINT8_TO_STREAM (p, p_cfg->la_hist_bytes_len);
+            ARRAY_TO_STREAM (p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
+        }
+
+        if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP)
+        {
+            UINT8_TO_STREAM (p, NFC_PMID_LB_H_INFO);
+            UINT8_TO_STREAM (p, p_cfg->lb_h_info_resp_len);
+            ARRAY_TO_STREAM (p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
+        }
+
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+    }
+
+    /*
+    ** Discovery Configuration Parameters for Listen NFC-DEP
+    */
+    if (  (disc_mask & (NFA_DM_DISC_MASK_LA_NFC_DEP|NFA_DM_DISC_MASK_LF_NFC_DEP))
+        &&(p_cfg->ln_enable))
+    {
+        p = params;
+
+        UINT8_TO_STREAM (p, NFC_PMID_WT);
+        UINT8_TO_STREAM (p, NCI_PARAM_LEN_WT);
+        UINT8_TO_STREAM (p, p_cfg->ln_wt);
+
+        UINT8_TO_STREAM (p, NFC_PMID_ATR_RES_GEN_BYTES);
+        UINT8_TO_STREAM (p, p_cfg->ln_atr_res_gen_bytes_len);
+        ARRAY_TO_STREAM (p, p_cfg->ln_atr_res_gen_bytes, p_cfg->ln_atr_res_gen_bytes_len);
+
+        UINT8_TO_STREAM (p, NFC_PMID_ATR_RSP_CONFIG);
+        UINT8_TO_STREAM (p, 1);
+        UINT8_TO_STREAM (p, p_cfg->ln_atr_res_config);
+
+        nfa_dm_check_set_config ((UINT8) (p - params), params, FALSE);
+    }
+
+    *p_disc_mask = disc_mask;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_set_rf_listen_mode_raw_config () disc_mask = 0x%x", disc_mask);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_get_disc_mask
+**
+** Description      Convert RF technology, mode and protocol to bit mask
+**
+** Returns          tNFA_DM_DISC_TECH_PROTO_MASK
+**
+*******************************************************************************/
+static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask (tNFC_RF_TECH_N_MODE tech_n_mode,
+                                                               tNFC_PROTOCOL       protocol)
+{
+    /* Set initial disc_mask to legacy poll or listen */
+    tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY : NFA_DM_DISC_MASK_P_LEGACY);
+
+    switch (tech_n_mode)
+    {
+    case NFC_DISCOVERY_TYPE_POLL_A:
+        switch (protocol)
+        {
+        case NFC_PROTOCOL_T1T:
+            disc_mask = NFA_DM_DISC_MASK_PA_T1T;
+            break;
+        case NFC_PROTOCOL_T2T:
+            disc_mask = NFA_DM_DISC_MASK_PA_T2T;
+            break;
+        case NFC_PROTOCOL_ISO_DEP:
+            disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
+            break;
+        case NFC_PROTOCOL_NFC_DEP:
+            disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
+            break;
+        }
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_B:
+        if (protocol == NFC_PROTOCOL_ISO_DEP)
+            disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_F:
+        if (protocol == NFC_PROTOCOL_T3T)
+            disc_mask = NFA_DM_DISC_MASK_PF_T3T;
+        else if (protocol == NFC_PROTOCOL_NFC_DEP)
+            disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_ISO15693:
+        disc_mask = NFA_DM_DISC_MASK_P_ISO15693;
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_B_PRIME:
+        disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_KOVIO:
+        disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_A_ACTIVE:
+        disc_mask = NFA_DM_DISC_MASK_PAA_NFC_DEP;
+        break;
+    case NFC_DISCOVERY_TYPE_POLL_F_ACTIVE:
+        disc_mask = NFA_DM_DISC_MASK_PFA_NFC_DEP;
+        break;
+
+    case NFC_DISCOVERY_TYPE_LISTEN_A:
+        switch (protocol)
+        {
+        case NFC_PROTOCOL_T1T:
+            disc_mask = NFA_DM_DISC_MASK_LA_T1T;
+            break;
+        case NFC_PROTOCOL_T2T:
+            disc_mask = NFA_DM_DISC_MASK_LA_T2T;
+            break;
+        case NFC_PROTOCOL_ISO_DEP:
+            disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
+            break;
+        case NFC_PROTOCOL_NFC_DEP:
+            disc_mask = NFA_DM_DISC_MASK_LA_NFC_DEP;
+            break;
+        }
+        break;
+    case NFC_DISCOVERY_TYPE_LISTEN_B:
+        if (protocol == NFC_PROTOCOL_ISO_DEP)
+            disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
+        break;
+    case NFC_DISCOVERY_TYPE_LISTEN_F:
+        if (protocol == NFC_PROTOCOL_T3T)
+            disc_mask = NFA_DM_DISC_MASK_LF_T3T;
+        else if (protocol == NFC_PROTOCOL_NFC_DEP)
+            disc_mask = NFA_DM_DISC_MASK_LF_NFC_DEP;
+        break;
+    case NFC_DISCOVERY_TYPE_LISTEN_ISO15693:
+        disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
+        break;
+    case NFC_DISCOVERY_TYPE_LISTEN_B_PRIME:
+        disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
+        break;
+    case NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE:
+        disc_mask = NFA_DM_DISC_MASK_LAA_NFC_DEP;
+        break;
+    case NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
+        disc_mask = NFA_DM_DISC_MASK_LFA_NFC_DEP;
+        break;
+    }
+
+    NFA_TRACE_DEBUG3 ("nfa_dm_disc_get_disc_mask (): tech_n_mode:0x%X, protocol:0x%X, disc_mask:0x%X",
+                       tech_n_mode, protocol, disc_mask);
+    return (disc_mask);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_discovery_cback
+**
+** Description      Discovery callback event from NFC
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_discovery_cback (tNFC_DISCOVER_EVT event, tNFC_DISCOVER *p_data)
+{
+    tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_disc_discovery_cback (): event:0x%X", event);
+
+    switch (event)
+    {
+    case NFC_START_DEVT:
+        dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
+        break;
+    case NFC_RESULT_DEVT:
+        dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
+        break;
+    case NFC_SELECT_DEVT:
+        dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
+        break;
+    case NFC_ACTIVATE_DEVT:
+        dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
+        break;
+    case NFC_DEACTIVATE_DEVT:
+        if (p_data->deactivate.is_ntf)
+            dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
+        else
+            dm_disc_event = NFA_DM_RF_DEACTIVATE_RSP;
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("Unexpected event");
+        return;
+    }
+
+    nfa_dm_disc_sm_execute (dm_disc_event, (tNFA_DM_RF_DISC_DATA *) p_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_notify_started
+**
+** Description      Report NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT or
+**                  NFA_RF_DISCOVERY_STARTED_EVT, if needed
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_notify_started (tNFA_STATUS status)
+{
+    tNFA_CONN_EVT_DATA      evt_data;
+
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
+    {
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+        evt_data.status = status;
+
+        if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+            nfa_dm_conn_cback_event_notify (NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &evt_data);
+        else
+            nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_conn_event_notify
+**
+** Description      Notify application of CONN_CBACK event, using appropriate
+**                  callback
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_dm_disc_conn_event_notify (UINT8 event, tNFA_STATUS status)
+{
+    tNFA_CONN_EVT_DATA      evt_data;
+
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
+    {
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+        evt_data.status               = status;
+
+        if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
+        {
+            /* Use exclusive RF mode callback */
+            if (nfa_dm_cb.p_excl_conn_cback)
+                (*nfa_dm_cb.p_excl_conn_cback) (event, &evt_data);
+        }
+        else
+        {
+            (*nfa_dm_cb.p_conn_cback) (event, &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_send_deactivate_cmd
+**
+** Description      Send deactivate command to NFCC, if needed.
+**
+** Returns          NFC_STATUS_OK             - deactivate cmd is sent
+**                  NCI_STATUS_FAILED         - no buffers
+**                  NFC_STATUS_SEMANTIC_ERROR - this function does not attempt
+**                                              to send deactivate cmd
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_dm_send_deactivate_cmd (tNFC_DEACT_TYPE deactivate_type)
+{
+    tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
+    tNFA_DM_DISC_FLAGS w4_flags = nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
+
+    if (!w4_flags)
+    {
+        /* if deactivate CMD was not sent to NFCC */
+        nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
+
+        status = NFC_Deactivate (deactivate_type);
+    }
+    else if ((w4_flags == NFA_DM_DISC_FLAGS_W4_NTF) && (deactivate_type == NFC_DEACTIVATE_TYPE_IDLE))
+    {
+        nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_NTF);
+        nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP);
+        nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
+        status = NFC_Deactivate (deactivate_type);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_start_rf_discover
+**
+** Description      Start RF discovery
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_start_rf_discover (void)
+{
+    tNFC_DISCOVER_PARAMS    disc_params[NFA_DM_MAX_DISC_PARAMS];
+    tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask = 0, poll_mask, listen_mask;
+    UINT8                   num_params, xx;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_start_rf_discover ()");
+    /* Make sure that RF discovery was enabled, or some app has exclusive control */
+    if (  (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED))
+        &&(nfa_dm_cb.disc_cb.excl_disc_entry.in_use == FALSE)  )
+    {
+        return;
+    }
+
+    /* get listen mode routing table for technology */
+    nfa_ee_get_tech_route (NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
+
+    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+    {
+        nfa_dm_set_rf_listen_mode_raw_config (&dm_disc_mask);
+        dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask & NFA_DM_DISC_MASK_POLL);
+        nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
+    }
+    else
+    {
+        /* Collect RF discovery request from sub-modules */
+        for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+        {
+            if (nfa_dm_cb.disc_cb.entry[xx].in_use)
+            {
+                poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask & NFA_DM_DISC_MASK_POLL);
+
+                /* clear poll mode technolgies and protocols which are already used by others */
+                poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
+
+                listen_mask = 0;
+
+                /*
+                ** add listen mode technolgies and protocols if host ID is matched to listen mode routing table
+                */
+
+                /* NFC-A */
+                if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A])
+                {
+                    listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
+                                   & ( NFA_DM_DISC_MASK_LA_T1T
+                                      |NFA_DM_DISC_MASK_LA_T2T
+                                      |NFA_DM_DISC_MASK_LA_ISO_DEP
+                                      |NFA_DM_DISC_MASK_LA_NFC_DEP
+                                      |NFA_DM_DISC_MASK_LAA_NFC_DEP );
+                }
+                else
+                {
+                    /* host can listen ISO-DEP based on AID routing */
+                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LA_ISO_DEP);
+                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LA_NFC_DEP);
+                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LAA_NFC_DEP);
+                }
+
+                /* NFC-B */
+                /* multiple hosts can listen ISO-DEP based on AID routing */
+                listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
+                               & NFA_DM_DISC_MASK_LB_ISO_DEP;
+
+                /* NFC-F */
+                if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F])
+                {
+                    listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
+                                   & ( NFA_DM_DISC_MASK_LF_T3T
+                                      |NFA_DM_DISC_MASK_LF_NFC_DEP
+                                      |NFA_DM_DISC_MASK_LFA_NFC_DEP );
+                }
+                else
+                {
+                    /* NFCC can listen T3T based on NFCID routing */
+                    listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask  & NFA_DM_DISC_MASK_LF_T3T);
+                }
+
+                /* NFC-B Prime */
+                if (nfa_dm_cb.disc_cb.entry[xx].host_id == nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP])
+                {
+                    listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask
+                                   & NFA_DM_DISC_MASK_L_B_PRIME;
+                }
+
+                /*
+                ** clear listen mode technolgies and protocols which are already used by others
+                */
+
+                /* Check if other modules are listening T1T or T2T */
+                if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_T1T|NFA_DM_DISC_MASK_LA_T2T))
+                {
+                    listen_mask &= ~( NFA_DM_DISC_MASK_LA_T1T
+                                     |NFA_DM_DISC_MASK_LA_T2T
+                                     |NFA_DM_DISC_MASK_LA_ISO_DEP
+                                     |NFA_DM_DISC_MASK_LA_NFC_DEP );
+                }
+
+                /* T1T/T2T has priority on NFC-A */
+                if (  (dm_disc_mask & (NFA_DM_DISC_MASK_LA_ISO_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP))
+                    &&(listen_mask & (NFA_DM_DISC_MASK_LA_T1T|NFA_DM_DISC_MASK_LA_T2T)))
+                {
+                    dm_disc_mask &= ~( NFA_DM_DISC_MASK_LA_ISO_DEP
+                                      |NFA_DM_DISC_MASK_LA_NFC_DEP );
+                }
+
+                /* Don't remove ISO-DEP because multiple hosts can listen ISO-DEP based on AID routing */
+
+                /* Check if other modules are listening NFC-DEP */
+                if (dm_disc_mask & (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP))
+                {
+                    listen_mask &= ~( NFA_DM_DISC_MASK_LA_NFC_DEP
+                                     |NFA_DM_DISC_MASK_LAA_NFC_DEP );
+                }
+
+                nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask = poll_mask | listen_mask;
+
+                NFA_TRACE_DEBUG2 ("nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x",
+                                   xx, nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
+
+                dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
+            }
+        }
+
+        /* Let P2P set GEN bytes for LLCP to NFCC */
+        if (dm_disc_mask & ( NFA_DM_DISC_MASK_PA_NFC_DEP
+                            |NFA_DM_DISC_MASK_PF_NFC_DEP
+                            |NFA_DM_DISC_MASK_LA_NFC_DEP
+                            |NFA_DM_DISC_MASK_LF_NFC_DEP
+                            |NFA_DM_DISC_MASK_PAA_NFC_DEP
+                            |NFA_DM_DISC_MASK_PFA_NFC_DEP
+                            |NFA_DM_DISC_MASK_LAA_NFC_DEP
+                            |NFA_DM_DISC_MASK_LFA_NFC_DEP ))
+        {
+            nfa_p2p_set_config (dm_disc_mask);
+        }
+    }
+
+    NFA_TRACE_DEBUG1 ("dm_disc_mask = 0x%x", dm_disc_mask);
+
+    /* Get Discovery Technology parameters */
+    num_params = nfa_dm_get_rf_discover_config (dm_disc_mask, disc_params, NFA_DM_MAX_DISC_PARAMS);
+
+    if (num_params)
+    {
+        /*
+        ** NFCC will abort programming personality slots if not available.
+        ** NFCC programs the personality slots in the following order of RF technologies:
+        **      NFC-A, NFC-B, NFC-BP, NFC-I93
+        */
+
+        /* if this is not for exclusive control */
+        if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+        {
+            /* update listening protocols in each NFC technology */
+            nfa_dm_set_rf_listen_mode_config (dm_disc_mask);
+        }
+
+        /* Set polling duty cycle */
+        nfa_dm_set_total_duration ();
+        nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
+
+        NFC_DiscoveryStart (num_params, disc_params, nfa_dm_disc_discovery_cback);
+        /* set flag about waiting for response in IDLE state */
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+
+        /* register callback to get interface error NTF */
+        NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
+    }
+    else
+    {
+        /* RF discovery is started but there is no valid technology or protocol to discover */
+        nfa_dm_disc_notify_started (NFA_STATUS_OK);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_notify_discovery
+**
+** Description      Send RF discovery notification to upper layer
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_notify_discovery (tNFA_DM_RF_DISC_DATA *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    /* let application select a device */
+    conn_evt.disc_result.status = NFA_STATUS_OK;
+    memcpy (&(conn_evt.disc_result.discovery_ntf),
+            &(p_data->nfc_discover.result),
+            sizeof (tNFC_RESULT_DEVT));
+
+    nfa_dm_conn_cback_event_notify (NFA_DISC_RESULT_EVT, &conn_evt);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_notify_activation
+**
+** Description      Send RF activation notification to sub-module
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+static tNFA_STATUS nfa_dm_disc_notify_activation (tNFC_DISCOVER *p_data)
+{
+    UINT8   xx, host_id_in_LRT;
+    UINT8   iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
+
+    tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
+    tNFC_PROTOCOL       protocol    = p_data->activate.protocol;
+
+    tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
+
+    NFA_TRACE_DEBUG2 ("nfa_dm_disc_notify_activation (): tech_n_mode:0x%X, proto:0x%X",
+                       tech_n_mode, protocol);
+
+    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+    {
+        nfa_dm_cb.disc_cb.activated_tech_mode    = tech_n_mode;
+        nfa_dm_cb.disc_cb.activated_rf_disc_id   = p_data->activate.rf_disc_id;
+        nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
+        nfa_dm_cb.disc_cb.activated_protocol     = protocol;
+        nfa_dm_cb.disc_cb.activated_handle       = NFA_HANDLE_INVALID;
+
+        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
+            (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+        return (NFA_STATUS_OK);
+    }
+
+    /* if this is NFCEE direct RF interface, notify activation to whoever listening UICC */
+    if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
+    {
+        for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+        {
+            if (  (nfa_dm_cb.disc_cb.entry[xx].in_use)
+                &&(nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH))
+            {
+                nfa_dm_cb.disc_cb.activated_rf_disc_id   = p_data->activate.rf_disc_id;
+                nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
+                nfa_dm_cb.disc_cb.activated_protocol     = NFC_PROTOCOL_UNKNOWN;
+                nfa_dm_cb.disc_cb.activated_handle       = xx;
+
+                NFA_TRACE_DEBUG2 ("activated_rf_interface:0x%x, activated_handle: 0x%x",
+                                   nfa_dm_cb.disc_cb.activated_rf_interface,
+                                   nfa_dm_cb.disc_cb.activated_handle);
+
+                if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+                    (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+                return (NFA_STATUS_OK);
+            }
+        }
+        return (NFA_STATUS_FAILED);
+    }
+
+    /* get bit mask of technolgies/mode and protocol */
+    activated_disc_mask = nfa_dm_disc_get_disc_mask (tech_n_mode, protocol);
+
+    /* get host ID of technology from listen mode routing table */
+    if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
+    {
+        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
+    }
+    else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
+    {
+        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
+    }
+    else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
+    {
+        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
+    }
+    else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
+    {
+        host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
+    }
+    else    /* DH only */
+    {
+        host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
+    }
+
+    if (protocol == NFC_PROTOCOL_NFC_DEP) {
+        // Force NFC-DEP to the host
+        host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
+    }
+
+    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+    {
+        /* if any matching NFC technology and protocol */
+        if (nfa_dm_cb.disc_cb.entry[xx].in_use)
+        {
+            if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT)
+            {
+                if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & activated_disc_mask)
+                    break;
+            }
+            else
+            {
+                /* check ISO-DEP listening even if host in LRT is not matched */
+                if (protocol == NFC_PROTOCOL_ISO_DEP)
+                {
+                    if (  (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
+                        &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP))
+                    {
+                        iso_dep_t3t__listen = xx;
+                    }
+                    else if (  (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
+                             &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP))
+                    {
+                        iso_dep_t3t__listen = xx;
+                    }
+                }
+                /* check T3T listening even if host in LRT is not matched */
+                else if (protocol == NFC_PROTOCOL_T3T)
+                {
+                    if (  (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
+                        &&(nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask & NFA_DM_DISC_MASK_LF_T3T))
+                    {
+                        iso_dep_t3t__listen = xx;
+                    }
+                }
+            }
+        }
+    }
+
+    if (xx >= NFA_DM_DISC_NUM_ENTRIES)
+    {
+        /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
+        xx = iso_dep_t3t__listen;
+    }
+
+    if (xx < NFA_DM_DISC_NUM_ENTRIES)
+    {
+        nfa_dm_cb.disc_cb.activated_tech_mode    = tech_n_mode;
+        nfa_dm_cb.disc_cb.activated_rf_disc_id   = p_data->activate.rf_disc_id;
+        nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
+        nfa_dm_cb.disc_cb.activated_protocol     = protocol;
+        nfa_dm_cb.disc_cb.activated_handle       = xx;
+
+        NFA_TRACE_DEBUG2 ("activated_protocol:0x%x, activated_handle: 0x%x",
+                           nfa_dm_cb.disc_cb.activated_protocol,
+                           nfa_dm_cb.disc_cb.activated_handle);
+
+        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+            (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
+
+        return (NFA_STATUS_OK);
+    }
+    else
+    {
+        nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
+        nfa_dm_cb.disc_cb.activated_handle   = NFA_HANDLE_INVALID;
+        return (NFA_STATUS_FAILED);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_notify_deactivation
+**
+** Description      Send deactivation notification to sub-module
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_dm_disc_notify_deactivation (tNFA_DM_RF_DISC_SM_EVENT sm_event,
+                                             tNFC_DISCOVER *p_data)
+{
+    tNFA_HANDLE         xx;
+    tNFA_DM_RF_DISC_EVT disc_evt;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_disc_notify_deactivation (): activated_handle=%d",
+                       nfa_dm_cb.disc_cb.activated_handle);
+
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
+    {
+        NFA_TRACE_DEBUG0 ("nfa_dm_disc_notify_deactivation (): for presence check");
+        return;
+    }
+
+    if (sm_event == NFA_DM_RF_DEACTIVATE_RSP)
+    {
+        /*
+        ** Activation has been aborted by upper layer in NFA_DM_RFST_W4_HOST_SELECT
+        ** or NFA_DM_RFST_LISTEN_SLEEP
+        */
+        disc_evt = NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT;
+    }
+    else
+    {
+        /* Received deactivation NTF */
+        disc_evt = NFA_DM_RF_DISC_DEACTIVATED_EVT;
+    }
+
+    if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+    {
+        if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
+            (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (disc_evt, p_data);
+    }
+    else
+    {
+        /* notify event to activated module */
+        xx = nfa_dm_cb.disc_cb.activated_handle;
+
+        if (  (sm_event == NFA_DM_RF_DEACTIVATE_RSP)
+            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)  )
+        {
+            /* Don't remove handle in NFA_DM_RFST_W4_HOST_SELECT or NFA_DM_RFST_LISTEN_SLEEP */
+            nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
+        }
+
+        if ((xx < NFA_DM_DISC_NUM_ENTRIES) && (nfa_dm_cb.disc_cb.entry[xx].in_use))
+        {
+            if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+                (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (disc_evt, p_data);
+        }
+    }
+
+    /* clear activated information */
+    nfa_dm_cb.disc_cb.activated_tech_mode    = 0;
+    nfa_dm_cb.disc_cb.activated_rf_disc_id   = 0;
+    nfa_dm_cb.disc_cb.activated_rf_interface = 0;
+    nfa_dm_cb.disc_cb.activated_protocol     = NFA_PROTOCOL_INVALID;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_presence_check
+**
+** Description      Perform legacy presence check (put tag to sleep, then
+**                  wake it up to see if tag is present)
+**
+** Returns          TRUE if operation started
+**
+*******************************************************************************/
+tNFC_STATUS nfa_dm_disc_presence_check (void)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE)
+    {
+        /* Deactivate to sleep mode */
+        status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
+        if (status == NFC_STATUS_OK)
+        {
+            /* deactivate to sleep is sent on behave of presence check.
+             * set the presence check information in control block */
+            nfa_dm_cb.disc_cb.disc_flags          |= NFA_DM_DISC_FLAGS_CHECKING;
+            nfa_dm_cb.presence_check_deact_pending = FALSE;
+        }
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_end_presence_check
+**
+** Description      Perform legacy presence check (put tag to sleep, then
+**                  wake it up to see if tag is present)
+**
+** Returns          TRUE if operation started
+**
+*******************************************************************************/
+static void nfa_dm_disc_end_presence_check (tNFC_STATUS status)
+{
+    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING)
+    {
+        /* notify RW module that presence checking is finished */
+        nfa_rw_handle_presence_check_rsp (status);
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
+        if (nfa_dm_cb.presence_check_deact_pending)
+        {
+            nfa_dm_cb.presence_check_deact_pending = FALSE;
+            nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD,
+                                          (tNFA_DM_RF_DISC_DATA *) &nfa_dm_cb.presence_check_deact_type);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_data_cback
+**
+** Description      Monitoring interface error through data callback
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_disc_data_cback ()");
+
+    /* if selection failed */
+    if (event == NFC_ERROR_CEVT)
+    {
+        nfa_dm_disc_sm_execute (NFA_DM_CORE_INTF_ERROR_NTF, NULL);
+    }
+    else if (event == NFC_DATA_CEVT)
+    {
+        GKI_freebuf (p_data->data.p_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_new_state
+**
+** Description      Processing discovery events in NFA_DM_RFST_IDLE state
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_disc_new_state (tNFA_DM_RF_DISC_STATE new_state)
+{
+    tNFA_CONN_EVT_DATA      evt_data;
+    tNFA_DM_RF_DISC_STATE   old_state = nfa_dm_cb.disc_cb.disc_state;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG5 ("nfa_dm_disc_new_state (): old_state: %s (%d), new_state: %s (%d) disc_flags: 0x%x",
+                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
+                       nfa_dm_disc_state_2_str (new_state), new_state, nfa_dm_cb.disc_cb.disc_flags);
+#else
+    NFA_TRACE_DEBUG3 ("nfa_dm_disc_new_state(): old_state: %d, new_state: %d disc_flags: 0x%x",
+                       nfa_dm_cb.disc_cb.disc_state, new_state, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+    nfa_dm_cb.disc_cb.disc_state = new_state;
+    if (new_state == NFA_DM_RFST_IDLE)
+    {
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
+        {
+            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
+
+            /* if exclusive RF control is stopping */
+            if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)
+            {
+                if (old_state > NFA_DM_RFST_DISCOVERY)
+                {
+                    /* notify deactivation to application */
+                    evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+                    nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+                }
+
+                nfa_dm_rel_excl_rf_control_and_notify ();
+            }
+            else
+            {
+                evt_data.status = NFA_STATUS_OK;
+                nfa_dm_conn_cback_event_notify (NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
+            }
+        }
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING)
+        {
+            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+            nfa_sys_check_disabled ();
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_idle
+**
+** Description      Processing discovery events in NFA_DM_RFST_IDLE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_idle (tNFA_DM_RF_DISC_SM_EVENT event,
+                                 tNFA_DM_RF_DISC_DATA *p_data)
+{
+    UINT8              xx;
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISCOVER_CMD:
+        nfa_dm_start_rf_discover ();
+        break;
+
+    case NFA_DM_RF_DISCOVER_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+
+        if (p_data->nfc_discover.status == NFC_STATUS_OK)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
+
+            /* if RF discovery was stopped while waiting for response */
+            if (nfa_dm_cb.disc_cb.disc_flags & (NFA_DM_DISC_FLAGS_STOPPING|NFA_DM_DISC_FLAGS_DISABLING))
+            {
+                /* stop discovery */
+                nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+                break;
+            }
+
+            if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
+            {
+                if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)
+                {
+                    nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+                    if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
+                        (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
+                }
+            }
+            else
+            {
+                /* notify event to each module which is waiting for start */
+                for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+                {
+                    /* if registered module is waiting for starting discovery */
+                    if (  (nfa_dm_cb.disc_cb.entry[xx].in_use)
+                        &&(nfa_dm_cb.disc_cb.dm_disc_mask & nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask)
+                        &&(nfa_dm_cb.disc_cb.entry[xx].disc_flags & NFA_DM_DISC_FLAGS_NOTIFY)  )
+                    {
+                        nfa_dm_cb.disc_cb.entry[xx].disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
+
+                        if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
+                            (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) (NFA_DM_RF_DISC_START_EVT, (tNFC_DISCOVER*) p_data);
+                    }
+                }
+
+            }
+            nfa_dm_disc_notify_started (p_data->nfc_discover.status);
+        }
+        else
+        {
+            /* in rare case that the discovery states of NFCC and DH mismatch and NFCC rejects Discover Cmd
+             * deactivate idle and then start disvocery when got deactivate rsp */
+            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        /* restart discovery */
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING)
+        {
+            nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
+            nfa_sys_check_disabled ();
+        }
+        else
+            nfa_dm_start_rf_discover ();
+        break;
+
+    case NFA_DM_LP_LISTEN_CMD:
+        nfa_dm_disc_new_state (NFA_DM_RFST_LP_LISTEN);
+        break;
+
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_idle (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_discovery
+**
+** Description      Processing discovery events in NFA_DM_RFST_DISCOVERY state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_discovery (tNFA_DM_RF_DISC_SM_EVENT event,
+                                      tNFA_DM_RF_DISC_DATA *p_data)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        /* if deactivate CMD was not sent to NFCC */
+        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
+        {
+            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+            NFC_Deactivate (p_data->deactivate_type);
+        }
+        break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover ();
+        break;
+    case NFA_DM_RF_DISCOVER_NTF:
+        nfa_dm_disc_new_state (NFA_DM_RFST_W4_ALL_DISCOVERIES);
+        nfa_dm_notify_discovery (p_data);
+        break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+        if (p_data->nfc_discover.activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
+        }
+        else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80)
+        {
+            /* Listen mode */
+            nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
+        }
+        else
+        {
+            /* Poll mode */
+            nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
+        }
+
+        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
+        {
+            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
+
+            /* after receiving deactivate event, restart discovery */
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+
+    case NFA_DM_LP_LISTEN_CMD:
+        break;
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_discovery (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_w4_all_discoveries
+**
+** Description      Processing discovery events in NFA_DM_RFST_W4_ALL_DISCOVERIES state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_w4_all_discoveries (tNFA_DM_RF_DISC_SM_EVENT event,
+                                               tNFA_DM_RF_DISC_DATA *p_data)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        /* if deactivate CMD was not sent to NFCC */
+        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
+        {
+            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+            /* only IDLE mode is allowed */
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover ();
+        break;
+    case NFA_DM_RF_DISCOVER_NTF:
+        /* Notification Type = NCI_DISCOVER_NTF_LAST or NCI_DISCOVER_NTF_LAST_ABORT */
+        if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
+        }
+        nfa_dm_notify_discovery (p_data);
+        break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+        /*
+        ** This is only for ISO15693.
+        ** FW sends activation NTF when all responses are received from tags without host selecting.
+        */
+        nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
+
+        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
+        {
+            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
+
+            /* after receiving deactivate event, restart discovery */
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_all_discoveries (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_w4_host_select
+**
+** Description      Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_w4_host_select (tNFA_DM_RF_DISC_SM_EVENT event,
+                                           tNFA_DM_RF_DISC_DATA *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt;
+    tNFA_DM_DISC_FLAGS  old_pres_check_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
+    BOOLEAN             pres_check_event = FALSE;
+    BOOLEAN             pres_check_event_processed = FALSE;
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISCOVER_SELECT_CMD:
+        /* if not waiting to deactivate */
+        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
+        {
+            NFC_DiscoverySelect (p_data->select.rf_disc_id,
+                                 p_data->select.protocol,
+                                 p_data->select.rf_interface);
+        }
+        else
+        {
+            nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
+        }
+        break;
+
+    case NFA_DM_RF_DISCOVER_SELECT_RSP:
+        pres_check_event = TRUE;
+        /* notify application status of selection */
+        if (p_data->nfc_discover.status == NFC_STATUS_OK)
+        {
+            pres_check_event_processed = TRUE;
+            conn_evt.status = NFA_STATUS_OK;
+            /* register callback to get interface error NTF */
+            NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
+        }
+        else
+            conn_evt.status = NFA_STATUS_FAILED;
+
+        if (!old_pres_check_flag)
+        {
+            nfa_dm_disc_conn_event_notify (NFA_SELECT_RESULT_EVT, p_data->nfc_discover.status);
+        }
+        break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+        nfa_dm_disc_new_state (NFA_DM_RFST_POLL_ACTIVE);
+        if (old_pres_check_flag)
+        {
+            /* notify RW module of presence of tag */
+            nfa_rw_handle_presence_check_rsp (NFC_STATUS_OK);
+            if (nfa_dm_cb.presence_check_deact_pending)
+            {
+                nfa_dm_cb.presence_check_deact_pending = FALSE;
+                nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD,
+                                       (tNFA_DM_RF_DISC_DATA *) &nfa_dm_cb.presence_check_deact_type);
+            }
+        }
+
+        else if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
+        {
+            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
+
+            /* after receiving deactivate event, restart discovery */
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        if (old_pres_check_flag)
+        {
+            nfa_dm_cb.presence_check_deact_pending = TRUE;
+            nfa_dm_cb.presence_check_deact_type    = p_data->deactivate_type;
+        }
+        /* if deactivate CMD was not sent to NFCC */
+        else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))
+        {
+            nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
+            /* only IDLE mode is allowed */
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+        nfa_dm_start_rf_discover ();
+        /* notify exiting from host select state */
+        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
+        break;
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+        pres_check_event    = TRUE;
+        if (!old_pres_check_flag)
+        {
+            /* target activation failed, upper layer may deactivate or select again */
+            conn_evt.status = NFA_STATUS_FAILED;
+            nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
+        }
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_w4_host_select (): Unexpected discovery event");
+        break;
+    }
+
+    if (old_pres_check_flag && pres_check_event && !pres_check_event_processed)
+    {
+        /* performing presence check for unknow protocol and exception conditions happened
+         * clear presence check information and report failure */
+        nfa_dm_disc_end_presence_check (NFC_STATUS_FAILED);
+        if (nfa_dm_cb.presence_check_deact_pending)
+        {
+            nfa_dm_cb.presence_check_deact_pending = FALSE;
+
+            NFC_Deactivate (nfa_dm_cb.presence_check_deact_type);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_poll_active
+**
+** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_poll_active (tNFA_DM_RF_DISC_SM_EVENT event,
+                                        tNFA_DM_RF_DISC_DATA *p_data)
+{
+    tNFC_STATUS status;
+    tNFA_DM_DISC_FLAGS  old_pres_check_flag = (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
+    BOOLEAN             pres_check_event = FALSE;
+    BOOLEAN             pres_check_event_processed = FALSE;
+
+    switch (event)
+    {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        if (old_pres_check_flag)
+        {
+            /* presence check is already enabled when deactivate cmd is requested,
+             * keep the information in control block to issue it later */
+            nfa_dm_cb.presence_check_deact_pending = TRUE;
+            nfa_dm_cb.presence_check_deact_type    = p_data->deactivate_type;
+        }
+        else
+        {
+            status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
+        }
+
+        break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        /* register callback to get interface error NTF */
+        NFC_SetStaticRfCback (nfa_dm_disc_data_cback);
+        break;
+    case NFA_DM_RF_DEACTIVATE_NTF:
+        pres_check_event    = TRUE;
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
+        if (  (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
+            ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_W4_HOST_SELECT);
+            if (old_pres_check_flag)
+            {
+                pres_check_event_processed  = TRUE;
+                /* process pending deactivate request */
+                if (nfa_dm_cb.presence_check_deact_pending)
+                {
+                    nfa_dm_cb.presence_check_deact_pending = FALSE;
+                    /* notify RW module that presence checking is finished */
+                    nfa_dm_disc_end_presence_check (NFC_STATUS_OK);
+
+                    if (nfa_dm_cb.presence_check_deact_type == NFC_DEACTIVATE_TYPE_IDLE)
+                        NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+                    else
+                        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
+                }
+                else
+                {
+                    /* Successfully went to sleep mode for presence check */
+                    /* Now wake up the tag to see if it is present */
+                    NFC_DiscoverySelect (nfa_dm_cb.disc_cb.activated_rf_disc_id,
+                                         nfa_dm_cb.disc_cb.activated_protocol,
+                                         nfa_dm_cb.disc_cb.activated_rf_interface);
+                }
+
+            }
+        }
+        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+            nfa_dm_start_rf_discover ();
+        }
+        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
+            if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
+            {
+                /* stop discovery */
+                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+            }
+        }
+        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
+        break;
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+        pres_check_event    = TRUE;
+        NFC_Deactivate (NFC_DEACTIVATE_TYPE_DISCOVERY);
+        break;
+
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_poll_active (): Unexpected discovery event");
+        break;
+    }
+
+    if (old_pres_check_flag && pres_check_event && !pres_check_event_processed)
+    {
+        /* performing presence check for unknow protocol and exception conditions happened
+         * clear presence check information and report failure */
+        nfa_dm_disc_end_presence_check (NFC_STATUS_FAILED);
+        if (nfa_dm_cb.presence_check_deact_pending)
+        {
+            nfa_dm_cb.presence_check_deact_pending = FALSE;
+
+            NFC_Deactivate (nfa_dm_cb.presence_check_deact_type);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_listen_active
+**
+** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_listen_active (tNFA_DM_RF_DISC_SM_EVENT event,
+                                          tNFA_DM_RF_DISC_DATA     *p_data)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
+        break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        break;
+    case NFA_DM_RF_DEACTIVATE_NTF:
+        /* clear both W4_RSP and W4_NTF because of race condition between deactivat CMD and link loss */
+        nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
+
+        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+            nfa_dm_start_rf_discover ();
+        }
+        else if (  (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
+                 ||(p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_SLEEP);
+        }
+        else if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)
+        {
+            /* Discovery */
+            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
+            if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)
+            {
+                /* stop discovery */
+                NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+            }
+        }
+        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
+        break;
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_active (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_listen_sleep
+**
+** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_listen_sleep (tNFA_DM_RF_DISC_SM_EVENT event,
+                                         tNFA_DM_RF_DISC_DATA *p_data)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        nfa_dm_send_deactivate_cmd (p_data->deactivate_type);
+        break;
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
+        /* if deactivate type in CMD was IDLE */
+        if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF))
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+            nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_RSP, &(p_data->nfc_discover));
+        }
+        break;
+    case NFA_DM_RF_DEACTIVATE_NTF:
+        /* clear both W4_RSP and W4_NTF because of race condition between deactivat CMD and link loss */
+        nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_RSP|NFA_DM_DISC_FLAGS_W4_NTF);
+        if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+            nfa_dm_start_rf_discover ();
+        }
+        else if (p_data->nfc_discover.deactivate.type == NFA_DEACTIVATE_TYPE_DISCOVERY)
+        {
+            nfa_dm_disc_new_state (NFA_DM_RFST_DISCOVERY);
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("Unexpected deactivation type");
+            nfa_dm_disc_new_state (NFA_DM_RFST_IDLE);
+            nfa_dm_start_rf_discover ();
+        }
+        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
+        break;
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+        nfa_dm_disc_new_state (NFA_DM_RFST_LISTEN_ACTIVE);
+        if (nfa_dm_disc_notify_activation (&(p_data->nfc_discover)) == NFA_STATUS_FAILED)
+        {
+            NFA_TRACE_DEBUG0 ("Not matched, restart discovery after receiving deactivate ntf");
+
+            /* after receiving deactivate event, restart discovery */
+            NFC_Deactivate (NFA_DEACTIVATE_TYPE_IDLE);
+        }
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_listen_sleep (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_lp_listen
+**
+** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_lp_listen (tNFA_DM_RF_DISC_SM_EVENT event,
+                                           tNFA_DM_RF_DISC_DATA *p_data)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+        nfa_dm_disc_new_state (NFA_DM_RFST_LP_ACTIVE);
+        nfa_dm_disc_notify_activation (&(p_data->nfc_discover));
+        break;
+
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_lp_listen (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_lp_active
+**
+** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_dm_disc_sm_lp_active (tNFA_DM_RF_DISC_SM_EVENT event,
+                                           tNFA_DM_RF_DISC_DATA *p_data)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_DEACTIVATE_NTF:
+        nfa_dm_disc_new_state (NFA_DM_RFST_LP_LISTEN);
+        nfa_dm_disc_notify_deactivation (NFA_DM_RF_DEACTIVATE_NTF, &(p_data->nfc_discover));
+        break;
+    default:
+        NFA_TRACE_ERROR0 ("nfa_dm_disc_sm_lp_active (): Unexpected discovery event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_sm_execute
+**
+** Description      Processing discovery related events
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_disc_sm_execute (tNFA_DM_RF_DISC_SM_EVENT event, tNFA_DM_RF_DISC_DATA *p_data)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG5 ("nfa_dm_disc_sm_execute (): state: %s (%d), event: %s(%d) disc_flags: 0x%x",
+                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
+                       nfa_dm_disc_event_2_str (event), event, nfa_dm_cb.disc_cb.disc_flags);
+#else
+    NFA_TRACE_DEBUG3 ("nfa_dm_disc_sm_execute(): state: %d, event:%d disc_flags: 0x%x",
+                       nfa_dm_cb.disc_cb.disc_state, event, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+
+    switch (nfa_dm_cb.disc_cb.disc_state)
+    {
+    /*  RF Discovery State - Idle */
+    case NFA_DM_RFST_IDLE:
+        nfa_dm_disc_sm_idle (event, p_data);
+        break;
+
+    /* RF Discovery State - Discovery */
+    case NFA_DM_RFST_DISCOVERY:
+        nfa_dm_disc_sm_discovery (event, p_data);
+        break;
+
+    /*RF Discovery State - Wait for all discoveries */
+    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
+        nfa_dm_disc_sm_w4_all_discoveries (event, p_data);
+        break;
+
+    /* RF Discovery State - Wait for host selection */
+    case NFA_DM_RFST_W4_HOST_SELECT:
+        nfa_dm_disc_sm_w4_host_select (event, p_data);
+        break;
+
+    /* RF Discovery State - Poll mode activated */
+    case NFA_DM_RFST_POLL_ACTIVE:
+        nfa_dm_disc_sm_poll_active (event, p_data);
+        break;
+
+    /* RF Discovery State - listen mode activated */
+    case NFA_DM_RFST_LISTEN_ACTIVE:
+        nfa_dm_disc_sm_listen_active (event, p_data);
+        break;
+
+    /* RF Discovery State - listen mode sleep */
+    case NFA_DM_RFST_LISTEN_SLEEP:
+        nfa_dm_disc_sm_listen_sleep (event, p_data);
+        break;
+
+    /* Listening in Low Power mode    */
+    case NFA_DM_RFST_LP_LISTEN:
+        nfa_dm_disc_sm_lp_listen (event, p_data);
+        break;
+
+    /* Activated in Low Power mode    */
+    case NFA_DM_RFST_LP_ACTIVE:
+        nfa_dm_disc_sm_lp_active (event, p_data);
+        break;
+    }
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG3 ("nfa_dm_disc_sm_execute (): new state: %s (%d), disc_flags: 0x%x",
+                       nfa_dm_disc_state_2_str (nfa_dm_cb.disc_cb.disc_state), nfa_dm_cb.disc_cb.disc_state,
+                       nfa_dm_cb.disc_cb.disc_flags);
+#else
+    NFA_TRACE_DEBUG2 ("nfa_dm_disc_sm_execute(): new state: %d,  disc_flags: 0x%x",
+                       nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_add_rf_discover
+**
+** Description      Add discovery configuration and callback function
+**
+** Returns          valid handle if success
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_dm_add_rf_discover (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
+                                    tNFA_DM_DISC_HOST_ID         host_id,
+                                    tNFA_DISCOVER_CBACK         *p_disc_cback)
+{
+    UINT8       xx;
+
+    NFA_TRACE_DEBUG1 ("nfa_dm_add_rf_discover () disc_mask=0x%x", disc_mask);
+
+    for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++)
+    {
+        if (!nfa_dm_cb.disc_cb.entry[xx].in_use)
+        {
+            nfa_dm_cb.disc_cb.entry[xx].in_use              = TRUE;
+            nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
+            nfa_dm_cb.disc_cb.entry[xx].host_id             = host_id;
+            nfa_dm_cb.disc_cb.entry[xx].p_disc_cback        = p_disc_cback;
+            nfa_dm_cb.disc_cb.entry[xx].disc_flags          = NFA_DM_DISC_FLAGS_NOTIFY;
+            return xx;
+        }
+    }
+
+    return NFA_HANDLE_INVALID;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_start_excl_discovery
+**
+** Description      Start exclusive RF discovery
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_start_excl_discovery (tNFA_TECHNOLOGY_MASK poll_tech_mask,
+                                  tNFA_LISTEN_CFG *p_listen_cfg,
+                                  tNFA_DISCOVER_CBACK  *p_disc_cback)
+{
+    tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_start_excl_discovery ()");
+
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
+        poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
+        poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
+        poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
+        poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
+        poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
+    }
+    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO)
+    {
+        poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
+    }
+
+    nfa_dm_cb.disc_cb.excl_disc_entry.in_use              = TRUE;
+    nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
+    nfa_dm_cb.disc_cb.excl_disc_entry.host_id             = NFA_DM_DISC_HOST_ID_DH;
+    nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback        = p_disc_cback;
+    nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags          = NFA_DM_DISC_FLAGS_NOTIFY;
+
+    memcpy (&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg, sizeof (tNFA_LISTEN_CFG));
+
+    nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_CMD, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_stop_excl_discovery
+**
+** Description      Stop exclusive RF discovery
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_stop_excl_discovery (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_stop_excl_discovery ()");
+
+    nfa_dm_cb.disc_cb.excl_disc_entry.in_use       = FALSE;
+    nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_delete_rf_discover
+**
+** Description      Remove discovery configuration and callback function
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_delete_rf_discover (tNFA_HANDLE handle)
+{
+    NFA_TRACE_DEBUG1 ("nfa_dm_delete_rf_discover () handle=0x%x", handle);
+
+    if (handle < NFA_DM_DISC_NUM_ENTRIES)
+    {
+        nfa_dm_cb.disc_cb.entry[handle].in_use = FALSE;
+    }
+    else
+    {
+        NFA_TRACE_ERROR0 ("Invalid discovery handle");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_rf_discover_select
+**
+** Description      Select target, protocol and RF interface
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_rf_discover_select (UINT8             rf_disc_id,
+                                       tNFA_NFC_PROTOCOL protocol,
+                                       tNFA_INTF_TYPE    rf_interface)
+{
+    tNFA_DM_DISC_SELECT_PARAMS select_params;
+    tNFA_CONN_EVT_DATA conn_evt;
+
+    NFA_TRACE_DEBUG3 ("nfa_dm_disc_select () rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
+                       rf_disc_id, protocol, rf_interface);
+
+    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)
+    {
+        /* state is OK: notify the status when the response is received from NFCC */
+        select_params.rf_disc_id   = rf_disc_id;
+        select_params.protocol     = protocol;
+        select_params.rf_interface = rf_interface;
+
+        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
+        nfa_dm_disc_sm_execute (NFA_DM_RF_DISCOVER_SELECT_CMD, (tNFA_DM_RF_DISC_DATA *) &select_params);
+    }
+    else
+    {
+        /* Wrong state: notify failed status right away */
+        conn_evt.status = NFA_STATUS_FAILED;
+        nfa_dm_conn_cback_event_notify (NFA_SELECT_RESULT_EVT, &conn_evt);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_rf_deactivate
+**
+** Description      Deactivate NFC link
+**
+** Returns          NFA_STATUS_OK if success
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_rf_deactivate (tNFA_DEACTIVATE_TYPE deactivate_type)
+{
+    NFA_TRACE_DEBUG1 ("nfa_dm_rf_deactivate () deactivate_type:0x%X", deactivate_type);
+
+    if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP)
+    {
+        if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
+            deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
+        else
+            deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
+    }
+
+    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+    {
+        return NFA_STATUS_FAILED;
+    }
+    else
+    {
+        nfa_dm_disc_sm_execute (NFA_DM_RF_DEACTIVATE_CMD, (tNFA_DM_RF_DISC_DATA *) &deactivate_type);
+        return NFA_STATUS_OK;
+    }
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_state_2_str
+**
+** Description      convert nfc discovery state to string
+**
+*******************************************************************************/
+static char *nfa_dm_disc_state_2_str (UINT8 state)
+{
+    switch (state)
+    {
+    case NFA_DM_RFST_IDLE:
+        return "IDLE";
+
+    case NFA_DM_RFST_DISCOVERY:
+        return "DISCOVERY";
+
+    case NFA_DM_RFST_W4_ALL_DISCOVERIES:
+        return "W4_ALL_DISCOVERIES";
+
+    case NFA_DM_RFST_W4_HOST_SELECT:
+        return "W4_HOST_SELECT";
+
+    case NFA_DM_RFST_POLL_ACTIVE:
+        return "POLL_ACTIVE";
+
+    case NFA_DM_RFST_LISTEN_ACTIVE:
+        return "LISTEN_ACTIVE";
+
+    case NFA_DM_RFST_LISTEN_SLEEP:
+        return "LISTEN_SLEEP";
+
+    case NFA_DM_RFST_LP_LISTEN:
+        return "LP_LISTEN";
+
+    case NFA_DM_RFST_LP_ACTIVE:
+        return "LP_ACTIVE";
+    }
+    return "Unknown";
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_disc_event_2_str
+**
+** Description      convert nfc discovery RSP/NTF to string
+**
+*******************************************************************************/
+static char *nfa_dm_disc_event_2_str (UINT8 event)
+{
+    switch (event)
+    {
+    case NFA_DM_RF_DISCOVER_CMD:
+        return "DISCOVER_CMD";
+
+    case NFA_DM_RF_DISCOVER_RSP:
+        return "DISCOVER_RSP";
+
+    case NFA_DM_RF_DISCOVER_NTF:
+        return "DISCOVER_NTF";
+
+    case NFA_DM_RF_DISCOVER_SELECT_CMD:
+        return "SELECT_CMD";
+
+    case NFA_DM_RF_DISCOVER_SELECT_RSP:
+        return "SELECT_RSP";
+
+    case NFA_DM_RF_INTF_ACTIVATED_NTF:
+        return "ACTIVATED_NTF";
+
+    case NFA_DM_RF_DEACTIVATE_CMD:
+        return "DEACTIVATE_CMD";
+
+    case NFA_DM_RF_DEACTIVATE_RSP:
+        return "DEACTIVATE_RSP";
+
+    case NFA_DM_RF_DEACTIVATE_NTF:
+        return "DEACTIVATE_NTF";
+
+    case NFA_DM_LP_LISTEN_CMD:
+        return "NFA_DM_LP_LISTEN_CMD";
+
+    case NFA_DM_CORE_INTF_ERROR_NTF:
+        return "INTF_ERROR_NTF";
+
+    }
+    return "Unknown";
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_main.c b/src/nfa/dm/nfa_dm_main.c
new file mode 100644
index 0000000..6829143
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_main.c
@@ -0,0 +1,517 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA device manager.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_dm_sys_reg =
+{
+    nfa_dm_sys_enable,
+    nfa_dm_evt_hdlr,
+    nfa_dm_sys_disable,
+    nfa_dm_proc_nfcc_power_mode
+};
+
+
+tNFA_DM_CB  nfa_dm_cb = {FALSE};
+
+
+#define NFA_DM_NUM_ACTIONS  (NFA_DM_MAX_EVT & 0x00ff)
+
+/* type for action functions */
+typedef BOOLEAN (*tNFA_DM_ACTION) (tNFA_DM_MSG *p_data);
+
+/* action function list */
+const tNFA_DM_ACTION nfa_dm_action[] =
+{
+    /* device manager local device API events */
+    nfa_dm_enable,                      /* NFA_DM_API_ENABLE_EVT                */
+    nfa_dm_disable,                     /* NFA_DM_API_DISABLE_EVT               */
+    nfa_dm_set_config,                  /* NFA_DM_API_SET_CONFIG_EVT            */
+    nfa_dm_get_config,                  /* NFA_DM_API_GET_CONFIG_EVT            */
+    nfa_dm_act_request_excl_rf_ctrl,    /* NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT  */
+    nfa_dm_act_release_excl_rf_ctrl,    /* NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT  */
+    nfa_dm_act_enable_polling,          /* NFA_DM_API_ENABLE_POLLING_EVT        */
+    nfa_dm_act_disable_polling,         /* NFA_DM_API_DISABLE_POLLING_EVT       */
+    nfa_dm_act_send_raw_frame,          /* NFA_DM_API_RAW_FRAME_EVT             */
+    nfa_dm_set_p2p_listen_tech,         /* NFA_DM_API_SET_P2P_LISTEN_TECH_EVT   */
+    nfa_dm_act_start_rf_discovery,      /* NFA_DM_API_START_RF_DISCOVERY_EVT    */
+    nfa_dm_act_stop_rf_discovery,       /* NFA_DM_API_STOP_RF_DISCOVERY_EVT     */
+    nfa_dm_act_set_rf_disc_duration,    /* NFA_DM_API_SET_RF_DISC_DURATION_EVT  */
+    nfa_dm_act_select,                  /* NFA_DM_API_SELECT_EVT                */
+    nfa_dm_act_update_rf_params,        /* NFA_DM_API_UPDATE_RF_PARAMS_EVT      */
+    nfa_dm_act_deactivate,              /* NFA_DM_API_DEACTIVATE_EVT            */
+    nfa_dm_act_power_off_sleep,         /* NFA_DM_API_POWER_OFF_SLEEP_EVT       */
+    nfa_dm_ndef_reg_hdlr,               /* NFA_DM_API_REG_NDEF_HDLR_EVT         */
+    nfa_dm_ndef_dereg_hdlr,             /* NFA_DM_API_DEREG_NDEF_HDLR_EVT       */
+    nfa_dm_act_reg_vsc,                 /* NFA_DM_API_REG_VSC_EVT               */
+    nfa_dm_act_send_vsc,                /* NFA_DM_API_SEND_VSC_EVT              */
+    nfa_dm_act_disable_timeout          /* NFA_DM_TIMEOUT_DISABLE_EVT           */
+};
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_dm_evt_2_str (UINT16 event);
+#endif
+/*******************************************************************************
+**
+** Function         nfa_dm_init
+**
+** Description      Initialises the NFC device manager
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_init (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_dm_init ()");
+    memset (&nfa_dm_cb, 0, sizeof (tNFA_DM_CB));
+    nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
+    nfa_dm_cb.disc_cb.disc_duration = NFA_DM_DISC_DURATION_POLL;
+    nfa_dm_cb.nfcc_pwr_mode    = NFA_DM_PWR_MODE_FULL;
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register (NFA_ID_DM, &nfa_dm_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_evt_hdlr
+**
+** Description      Event handling function for DM
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_evt_hdlr (BT_HDR *p_msg)
+{
+    BOOLEAN freebuf = TRUE;
+    UINT16  event = p_msg->event & 0x00ff;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_EVENT2 ("nfa_dm_evt_hdlr event: %s (0x%02x)", nfa_dm_evt_2_str (event), event);
+#else
+    NFA_TRACE_EVENT1 ("nfa_dm_evt_hdlr event: 0x%x", event);
+#endif
+
+    /* execute action functions */
+    if (event < NFA_DM_NUM_ACTIONS)
+    {
+        freebuf = (*nfa_dm_action[event]) ((tNFA_DM_MSG*) p_msg);
+    }
+    return freebuf;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_sys_disable
+**
+** Description      This function is called after all subsystems have been disabled.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_sys_disable (void)
+{
+    /* Disable the DM sub-system */
+    /* If discovery state is not IDLE or DEACTIVATED and graceful disable, */
+    /* then we need to deactivate link or stop discovery                   */
+
+    if (nfa_sys_is_graceful_disable ())
+    {
+        if (  (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)
+            &&((nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) == 0)  )
+        {
+            /* discovery is not started */
+            nfa_dm_disable_complete ();
+        }
+        else
+        {
+            /* probably waiting to be disabled */
+            NFA_TRACE_WARNING2 ("DM disc_state state = %d disc_flags:0x%x", nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
+        }
+
+    }
+    else
+    {
+        nfa_dm_disable_complete ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_is_protocol_supported
+**
+** Description      Check if protocol is supported by RW module
+**
+** Returns          TRUE if protocol is supported by NFA
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_is_protocol_supported (tNFC_PROTOCOL protocol, UINT8 sel_res)
+{
+    return (  (protocol == NFC_PROTOCOL_T1T)
+            ||((protocol == NFC_PROTOCOL_T2T) && (sel_res == NFC_SEL_RES_NFC_FORUM_T2T))
+            ||(protocol == NFC_PROTOCOL_T3T)
+            ||(protocol == NFC_PROTOCOL_ISO_DEP)
+            ||(protocol == NFC_PROTOCOL_NFC_DEP)
+            ||(protocol == NFC_PROTOCOL_15693)  );
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_is_active
+**
+** Description      check if all modules of NFA is done with enable process and
+**                  NFA is not restoring NFCC.
+**
+** Returns          TRUE, if NFA_DM_ENABLE_EVT is reported and it is not restoring NFCC
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_is_active (void)
+{
+    if (  (nfa_dm_cb.flags  & NFA_DM_FLAGS_DM_IS_ACTIVE)
+        &&((nfa_dm_cb.flags & (NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_NFCC_IS_RESTORING)) == 0)  )
+    {
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+/*******************************************************************************
+**
+** Function         nfa_dm_check_set_config
+**
+** Description      Update config parameters only if it's different from NFCC
+**
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_dm_check_set_config (UINT8 tlv_list_len, UINT8 *p_tlv_list, BOOLEAN app_init)
+{
+    UINT8 type, len, *p_value, *p_stored, max_len;
+    UINT8 xx = 0, updated_len = 0, *p_cur_len;
+    BOOLEAN update;
+    tNFC_STATUS nfc_status;
+    UINT32 cur_bit;
+
+    NFA_TRACE_DEBUG0 ("nfa_dm_check_set_config ()");
+
+    /* We only allow 32 pending SET_CONFIGs */
+    if (nfa_dm_cb.setcfg_pending_num >= NFA_DM_SETCONFIG_PENDING_MAX)
+    {
+        NFA_TRACE_ERROR0 ("nfa_dm_check_set_config () error: pending number of SET_CONFIG exceeded");
+        return NFA_STATUS_FAILED;
+    }
+
+    while (tlv_list_len - xx >= 2) /* at least type and len */
+    {
+        update  = FALSE;
+        type    = *(p_tlv_list + xx);
+        len     = *(p_tlv_list + xx + 1);
+        p_value = p_tlv_list + xx + 2;
+        p_cur_len = NULL;
+
+        switch (type)
+        {
+        case NFC_PMID_TOTAL_DURATION:
+            p_stored = nfa_dm_cb.params.total_duration;
+            max_len  = NCI_PARAM_LEN_TOTAL_DURATION;
+            break;
+
+        /*
+        **  Listen A Configuration
+        */
+        case NFC_PMID_LA_BIT_FRAME_SDD:
+            p_stored  = nfa_dm_cb.params.la_bit_frame_sdd;
+            max_len   = NCI_PARAM_LEN_LA_BIT_FRAME_SDD;
+            p_cur_len = &nfa_dm_cb.params.la_bit_frame_sdd_len;
+            break;
+        case NFC_PMID_LA_PLATFORM_CONFIG:
+            p_stored  = nfa_dm_cb.params.la_platform_config;
+            max_len   = NCI_PARAM_LEN_LA_PLATFORM_CONFIG;
+            p_cur_len = &nfa_dm_cb.params.la_platform_config_len;
+            break;
+        case NFC_PMID_LA_SEL_INFO:
+            p_stored  = nfa_dm_cb.params.la_sel_info;
+            max_len   = NCI_PARAM_LEN_LA_SEL_INFO;
+            p_cur_len = &nfa_dm_cb.params.la_sel_info_len;
+            break;
+        case NFC_PMID_LA_NFCID1:
+            p_stored  = nfa_dm_cb.params.la_nfcid1;
+            max_len   = NCI_NFCID1_MAX_LEN;
+            p_cur_len = &nfa_dm_cb.params.la_nfcid1_len;
+            break;
+        case NFC_PMID_LA_HIST_BY:
+            p_stored  = nfa_dm_cb.params.la_hist_by;
+            max_len   = NCI_MAX_HIS_BYTES_LEN;
+            p_cur_len = &nfa_dm_cb.params.la_hist_by_len;
+            break;
+
+        /*
+        **  Listen B Configuration
+        */
+        case NFC_PMID_LB_SENSB_INFO:
+            p_stored  = nfa_dm_cb.params.lb_sensb_info;
+            max_len   = NCI_PARAM_LEN_LB_SENSB_INFO;
+            p_cur_len = &nfa_dm_cb.params.lb_sensb_info_len;
+            break;
+        case NFC_PMID_LB_NFCID0:
+            p_stored  = nfa_dm_cb.params.lb_nfcid0;
+            max_len   = NCI_PARAM_LEN_LB_NFCID0;
+            p_cur_len = &nfa_dm_cb.params.lb_nfcid0_len;
+            break;
+        case NFC_PMID_LB_APPDATA:
+            p_stored  = nfa_dm_cb.params.lb_appdata;
+            max_len   = NCI_PARAM_LEN_LB_APPDATA;
+            p_cur_len = &nfa_dm_cb.params.lb_appdata_len;
+            break;
+        case NFC_PMID_LB_ADC_FO:
+            p_stored  = nfa_dm_cb.params.lb_adc_fo;
+            max_len   = NCI_PARAM_LEN_LB_ADC_FO;
+            p_cur_len = &nfa_dm_cb.params.lb_adc_fo_len;
+            break;
+        case NFC_PMID_LB_H_INFO:
+            p_stored  = nfa_dm_cb.params.lb_h_info;
+            max_len   = NCI_MAX_ATTRIB_LEN;
+            p_cur_len = &nfa_dm_cb.params.lb_h_info_len;
+            break;
+
+        /*
+        **  Listen F Configuration
+        */
+        case NFC_PMID_LF_PROTOCOL:
+            p_stored  = nfa_dm_cb.params.lf_protocol;
+            max_len   = NCI_PARAM_LEN_LF_PROTOCOL;
+            p_cur_len = &nfa_dm_cb.params.lf_protocol_len;
+            break;
+        case NFC_PMID_LF_T3T_FLAGS2:
+            p_stored  = nfa_dm_cb.params.lf_t3t_flags2;
+            max_len   = NCI_PARAM_LEN_LF_T3T_FLAGS2;
+            p_cur_len = &nfa_dm_cb.params.lf_t3t_flags2_len;
+            break;
+        case NFC_PMID_LF_T3T_PMM:
+            p_stored = nfa_dm_cb.params.lf_t3t_pmm;
+            max_len  = NCI_PARAM_LEN_LF_T3T_PMM;
+            break;
+
+        /*
+        **  ISO-DEP and NFC-DEP Configuration
+        */
+        case NFC_PMID_FWI:
+            p_stored = nfa_dm_cb.params.fwi;
+            max_len  = NCI_PARAM_LEN_FWI;
+            break;
+        case NFC_PMID_WT:
+            p_stored = nfa_dm_cb.params.wt;
+            max_len  = NCI_PARAM_LEN_WT;
+            break;
+        case NFC_PMID_ATR_REQ_GEN_BYTES:
+            p_stored  = nfa_dm_cb.params.atr_req_gen_bytes;
+            max_len   = NCI_MAX_GEN_BYTES_LEN;
+            p_cur_len = &nfa_dm_cb.params.atr_req_gen_bytes_len;
+            break;
+        case NFC_PMID_ATR_RES_GEN_BYTES:
+            p_stored  = nfa_dm_cb.params.atr_res_gen_bytes;
+            max_len   = NCI_MAX_GEN_BYTES_LEN;
+            p_cur_len = &nfa_dm_cb.params.atr_res_gen_bytes_len;
+            break;
+        default:
+            /*
+            **  Listen F Configuration
+            */
+            if ((type >= NFC_PMID_LF_T3T_ID1) && (type < NFC_PMID_LF_T3T_ID1 + NFA_CE_LISTEN_INFO_MAX))
+            {
+                p_stored = nfa_dm_cb.params.lf_t3t_id[type - NFC_PMID_LF_T3T_ID1];
+                max_len  = NCI_PARAM_LEN_LF_T3T_ID;
+            }
+            else
+            {
+                /* we don't stored this config items */
+                update   = TRUE;
+                p_stored = NULL;
+            }
+            break;
+        }
+
+        if ((p_stored)&&(len <= max_len))
+        {
+            if (p_cur_len)
+            {
+                if (*p_cur_len != len)
+                {
+                    *p_cur_len = len;
+                    update = TRUE;
+                }
+                else if (memcmp (p_value, p_stored, len))
+                {
+                    update = TRUE;
+                }
+            }
+            else if (len == max_len)  /* fixed length */
+            {
+                if (memcmp (p_value, p_stored, len))
+                {
+                    update = TRUE;
+                }
+            }
+        }
+
+        if (update)
+        {
+            /* we don't store this type */
+            if (p_stored)
+            {
+                memcpy (p_stored, p_value, len);
+            }
+
+            /* If need to change TLV in the original list. (Do not modify list if app_init) */
+            if ((updated_len != xx) && (!app_init))
+            {
+                memcpy (p_tlv_list + updated_len, p_tlv_list + xx, (len + 2));
+            }
+            updated_len += (len + 2);
+        }
+        xx += len + 2;  /* move to next TLV */
+    }
+
+    /* If any TVLs to update, or if the SetConfig was initiated by the application, then send the SET_CONFIG command */
+    if (updated_len || app_init)
+    {
+        if ((nfc_status = NFC_SetConfig (updated_len, p_tlv_list)) == NFC_STATUS_OK)
+        {
+            /* Keep track of whether we will need to notify NFA_DM_SET_CONFIG_EVT on NFC_SET_CONFIG_REVT */
+
+            /* Get the next available bit offset for this setconfig (based on how many SetConfigs are outstanding) */
+            cur_bit = (UINT32) (1 << nfa_dm_cb.setcfg_pending_num);
+
+            /* If setconfig is due to NFA_SetConfig: then set the bit (NFA_DM_SET_CONFIG_EVT needed on NFC_SET_CONFIG_REVT) */
+            if (app_init)
+            {
+                nfa_dm_cb.setcfg_pending_mask |= cur_bit;
+            }
+            /* Otherwise setconfig is internal: clear the bit (NFA_DM_SET_CONFIG_EVT not needed on NFC_SET_CONFIG_REVT) */
+            else
+            {
+                nfa_dm_cb.setcfg_pending_mask &= ~cur_bit;
+            }
+
+            /* Increment setcfg_pending counter */
+            nfa_dm_cb.setcfg_pending_num++;
+        }
+        return (nfc_status);
+
+    }
+    else
+    {
+        return NFA_STATUS_OK;
+    }
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_dm_nfc_revt_2_str
+**
+** Description      convert nfc revt to string
+**
+*******************************************************************************/
+static char *nfa_dm_evt_2_str (UINT16 event)
+{
+    switch (NFA_SYS_EVT_START (NFA_ID_DM) | event)
+    {
+    case NFA_DM_API_ENABLE_EVT:
+        return "NFA_DM_API_ENABLE_EVT";
+
+    case NFA_DM_API_DISABLE_EVT:
+        return "NFA_DM_API_DISABLE_EVT";
+
+    case NFA_DM_API_SET_CONFIG_EVT:
+        return "NFA_DM_API_SET_CONFIG_EVT";
+
+    case NFA_DM_API_GET_CONFIG_EVT:
+        return "NFA_DM_API_GET_CONFIG_EVT";
+
+    case NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT:
+        return "NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT";
+
+    case NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT:
+        return "NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT";
+
+    case NFA_DM_API_ENABLE_POLLING_EVT:
+        return "NFA_DM_API_ENABLE_POLLING_EVT";
+
+    case NFA_DM_API_DISABLE_POLLING_EVT:
+        return "NFA_DM_API_DISABLE_POLLING_EVT";
+
+    case NFA_DM_API_RAW_FRAME_EVT:
+        return "NFA_DM_API_RAW_FRAME_EVT";
+
+    case NFA_DM_API_SET_P2P_LISTEN_TECH_EVT:
+        return "NFA_DM_API_SET_P2P_LISTEN_TECH_EVT";
+
+    case NFA_DM_API_START_RF_DISCOVERY_EVT:
+        return "NFA_DM_API_START_RF_DISCOVERY_EVT";
+
+    case NFA_DM_API_STOP_RF_DISCOVERY_EVT:
+        return "NFA_DM_API_STOP_RF_DISCOVERY_EVT";
+
+    case NFA_DM_API_SET_RF_DISC_DURATION_EVT:
+        return "NFA_DM_API_SET_RF_DISC_DURATION_EVT";
+
+    case NFA_DM_API_SELECT_EVT:
+        return "NFA_DM_API_SELECT_EVT";
+
+    case NFA_DM_API_UPDATE_RF_PARAMS_EVT:
+        return "NFA_DM_API_UPDATE_RF_PARAMS_EVT";
+
+    case NFA_DM_API_DEACTIVATE_EVT:
+        return "NFA_DM_API_DEACTIVATE_EVT";
+
+    case NFA_DM_API_POWER_OFF_SLEEP_EVT:
+        return "NFA_DM_API_POWER_OFF_SLEEP_EVT";
+
+    case NFA_DM_API_REG_NDEF_HDLR_EVT:
+        return "NFA_DM_API_REG_NDEF_HDLR_EVT";
+
+    case NFA_DM_API_DEREG_NDEF_HDLR_EVT:
+        return "NFA_DM_API_DEREG_NDEF_HDLR_EVT";
+
+    case NFA_DM_TIMEOUT_DISABLE_EVT:
+        return "NFA_DM_TIMEOUT_DISABLE_EVT";
+
+    }
+
+    return "Unknown or Vendor Specific";
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/dm/nfa_dm_ndef.c b/src/nfa/dm/nfa_dm_ndef.c
new file mode 100644
index 0000000..c3e63b2
--- /dev/null
+++ b/src/nfa/dm/nfa_dm_ndef.c
@@ -0,0 +1,532 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Handle ndef messages
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfc_api.h"
+#include "ndef_utils.h"
+
+/*******************************************************************************
+* URI Well-known-type prefixes
+*******************************************************************************/
+const UINT8 *nfa_dm_ndef_wkt_uri_str_tbl[] = {
+    NULL,           /* 0x00 */
+    (const UINT8*) "http://www.",  /* 0x01 */
+    (const UINT8*) "https://www.", /* 0x02 */
+    (const UINT8*) "http://",      /* 0x03 */
+    (const UINT8*) "https://",     /* 0x04 */
+    (const UINT8*) "tel:",         /* 0x05 */
+    (const UINT8*) "mailto:",      /* 0x06 */
+    (const UINT8*) "ftp://anonymous:anonymous@",   /* 0x07 */
+    (const UINT8*) "ftp://ftp.",   /* 0x08 */
+    (const UINT8*) "ftps://",      /* 0x09 */
+    (const UINT8*) "sftp://",      /* 0x0A */
+    (const UINT8*) "smb://",       /* 0x0B */
+    (const UINT8*) "nfs://",       /* 0x0C */
+    (const UINT8*) "ftp://",       /* 0x0D */
+    (const UINT8*) "dav://",       /* 0x0E */
+    (const UINT8*) "news:",        /* 0x0F */
+    (const UINT8*) "telnet://",    /* 0x10 */
+    (const UINT8*) "imap:",        /* 0x11 */
+    (const UINT8*) "rtsp://",      /* 0x12 */
+    (const UINT8*) "urn:",         /* 0x13 */
+    (const UINT8*) "pop:",         /* 0x14 */
+    (const UINT8*) "sip:",         /* 0x15 */
+    (const UINT8*) "sips:",        /* 0x16 */
+    (const UINT8*) "tftp:",        /* 0x17 */
+    (const UINT8*) "btspp://",     /* 0x18 */
+    (const UINT8*) "btl2cap://",   /* 0x19 */
+    (const UINT8*) "btgoep://",    /* 0x1A */
+    (const UINT8*) "tcpobex://",   /* 0x1B */
+    (const UINT8*) "irdaobex://",  /* 0x1C */
+    (const UINT8*) "file://",      /* 0x1D */
+    (const UINT8*) "urn:epc:id:",  /* 0x1E */
+    (const UINT8*) "urn:epc:tag:", /* 0x1F */
+    (const UINT8*) "urn:epc:pat:", /* 0x20 */
+    (const UINT8*) "urn:epc:raw:", /* 0x21 */
+    (const UINT8*) "urn:epc:",     /* 0x22 */
+    (const UINT8*) "urn:nfc:"      /* 0x23 */
+};
+#define NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE (sizeof (nfa_dm_ndef_wkt_uri_str_tbl) / sizeof (UINT8 *))
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_dereg_hdlr_by_handle
+**
+** Description      Deregister NDEF record type handler
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+void nfa_dm_ndef_dereg_hdlr_by_handle (tNFA_HANDLE ndef_type_handle)
+{
+    tNFA_DM_CB *p_cb = &nfa_dm_cb;
+    UINT16 hdlr_idx;
+    hdlr_idx = (UINT16) (ndef_type_handle & NFA_HANDLE_MASK);
+
+    if (p_cb->p_ndef_handler[hdlr_idx])
+    {
+        GKI_freebuf (p_cb->p_ndef_handler[hdlr_idx]);
+        p_cb->p_ndef_handler[hdlr_idx] = NULL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_dereg_all
+**
+** Description      Deregister all NDEF record type handlers (called during
+**                  shutdown(.
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_dm_ndef_dereg_all (void)
+{
+    tNFA_DM_CB *p_cb = &nfa_dm_cb;
+    UINT32 i;
+
+    for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++)
+    {
+        /* If this is a free slot, then remember it */
+        if (p_cb->p_ndef_handler[i] != NULL)
+        {
+            GKI_freebuf (p_cb->p_ndef_handler[i]);
+            p_cb->p_ndef_handler[i] = NULL;
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_reg_hdlr
+**
+** Description      Register NDEF record type handler
+**
+** Returns          TRUE if message buffer is to be freed by caller
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_ndef_reg_hdlr (tNFA_DM_MSG *p_data)
+{
+    tNFA_DM_CB *p_cb = &nfa_dm_cb;
+    UINT32 hdlr_idx, i;
+    tNFA_DM_API_REG_NDEF_HDLR *p_reg_info = (tNFA_DM_API_REG_NDEF_HDLR *) p_data;
+    tNFA_NDEF_REGISTER ndef_register;
+
+    /* If registering default handler, check to see if one is already registered */
+    if (p_reg_info->tnf == NFA_TNF_DEFAULT)
+    {
+        /* check if default handler is already registered */
+        if (p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX])
+        {
+            NFA_TRACE_WARNING0 ("Default NDEF handler being changed.");
+
+            /* Free old registration info */
+            nfa_dm_ndef_dereg_hdlr_by_handle ((tNFA_HANDLE) NFA_NDEF_DEFAULT_HANDLER_IDX);
+        }
+        NFA_TRACE_DEBUG0 ("Default NDEF handler successfully registered.");
+        hdlr_idx = NFA_NDEF_DEFAULT_HANDLER_IDX;
+    }
+    /* Get available entry in ndef_handler table, and check if requested type is already registered */
+    else
+    {
+        hdlr_idx = NFA_HANDLE_INVALID;
+
+        /* Check if this type is already registered */
+        for (i = (NFA_NDEF_DEFAULT_HANDLER_IDX+1); i < NFA_NDEF_MAX_HANDLERS; i++)
+        {
+            /* If this is a free slot, then remember it */
+            if (p_cb->p_ndef_handler[i] == NULL)
+            {
+                hdlr_idx = i;
+                break;
+            }
+        }
+    }
+
+    if (hdlr_idx != NFA_HANDLE_INVALID)
+    {
+        /* Update the table */
+        p_cb->p_ndef_handler[hdlr_idx] = p_reg_info;
+
+        p_reg_info->ndef_type_handle = (tNFA_HANDLE) (NFA_HANDLE_GROUP_NDEF_HANDLER | hdlr_idx);
+
+        ndef_register.ndef_type_handle = p_reg_info->ndef_type_handle;
+        ndef_register.status = NFA_STATUS_OK;
+
+        NFA_TRACE_DEBUG1 ("NDEF handler successfully registered. Handle=0x%08x", p_reg_info->ndef_type_handle);
+        (*(p_reg_info->p_ndef_cback)) (NFA_NDEF_REGISTER_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_register);
+
+        return FALSE;       /* indicate that we will free message buffer when type_handler is deregistered */
+    }
+    else
+    {
+        /* Error */
+        NFA_TRACE_ERROR0 ("NDEF handler failed to register.");
+        ndef_register.ndef_type_handle = NFA_HANDLE_INVALID;
+        ndef_register.status = NFA_STATUS_FAILED;
+        (*(p_reg_info->p_ndef_cback)) (NFA_NDEF_REGISTER_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_register);
+
+        return TRUE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_dereg_hdlr
+**
+** Description      Deregister NDEF record type handler
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_dm_ndef_dereg_hdlr (tNFA_DM_MSG *p_data)
+{
+    tNFA_DM_API_DEREG_NDEF_HDLR *p_dereginfo = (tNFA_DM_API_DEREG_NDEF_HDLR *) p_data;
+
+    /* Make sure this is a NDEF_HDLR handle */
+    if (  ((p_dereginfo->ndef_type_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_NDEF_HANDLER)
+        ||((p_dereginfo->ndef_type_handle & NFA_HANDLE_MASK) >= NFA_NDEF_MAX_HANDLERS)  )
+    {
+        NFA_TRACE_ERROR1 ("Invalid handle for NDEF type handler: 0x%08x", p_dereginfo->ndef_type_handle);
+    }
+    else
+    {
+        nfa_dm_ndef_dereg_hdlr_by_handle (p_dereginfo->ndef_type_handle);
+    }
+
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_find_next_handler
+**
+** Description      Find next ndef handler for a given record type
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFA_DM_API_REG_NDEF_HDLR *nfa_dm_ndef_find_next_handler (tNFA_DM_API_REG_NDEF_HDLR *p_init_handler,
+                                                          UINT8                     tnf,
+                                                          UINT8                     *p_type_name,
+                                                          UINT8                     type_name_len,
+                                                          UINT8                     *p_payload,
+                                                          UINT32                    payload_len)
+{
+    tNFA_DM_CB *p_cb = &nfa_dm_cb;
+    UINT8 i;
+
+    /* if init_handler is NULL, then start with the first non-default handler */
+    if (!p_init_handler)
+        i=NFA_NDEF_DEFAULT_HANDLER_IDX+1;
+    else
+    {
+        /* Point to handler index after p_init_handler */
+        i = (p_init_handler->ndef_type_handle & NFA_HANDLE_MASK) + 1;
+    }
+
+
+    /* Look for next handler */
+    for (; i < NFA_NDEF_MAX_HANDLERS; i++)
+    {
+        /* Check if TNF matches */
+        if (  (p_cb->p_ndef_handler[i])
+            &&(p_cb->p_ndef_handler[i]->tnf == tnf)  )
+        {
+            /* TNF matches. */
+            /* If handler is for a specific URI type, check if type is WKT URI, */
+            /* and that the URI prefix abrieviation for this handler matches */
+            if (p_cb->p_ndef_handler[i]->flags & NFA_NDEF_FLAGS_WKT_URI)
+            {
+                /* This is a handler for a specific URI type */
+                /* Check if this recurd is WKT URI */
+                if ((type_name_len == 1) && (*p_type_name == 'U'))
+                {
+                    /* Check if URI prefix abrieviation matches */
+                    if ((payload_len>1) && (p_payload[0] == p_cb->p_ndef_handler[i]->uri_id))
+                    {
+                        /* URI prefix abrieviation matches */
+                        /* If handler does not specify an absolute URI, then match found. */
+                        /* If absolute URI, then compare URI for match (skip over uri_id in ndef payload) */
+                        if (  (p_cb->p_ndef_handler[i]->uri_id != NFA_NDEF_URI_ID_ABSOLUTE)
+                            ||(memcmp (&p_payload[1], p_cb->p_ndef_handler[i]->name, p_cb->p_ndef_handler[i]->name_len) == 0)  )
+                        {
+                            /* Handler found. */
+                            break;
+                        }
+                    }
+                    /* Check if handler is absolute URI but NDEF is using prefix abrieviation */
+                    else if ((p_cb->p_ndef_handler[i]->uri_id == NFA_NDEF_URI_ID_ABSOLUTE) && (p_payload[0] != NFA_NDEF_URI_ID_ABSOLUTE))
+                    {
+                        /* Handler is absolute URI but NDEF is using prefix abrieviation. Compare URI prefix */
+                        if (  (p_payload[0]<NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE)
+                            &&(memcmp (p_cb->p_ndef_handler[i]->name, (char *) nfa_dm_ndef_wkt_uri_str_tbl[p_payload[0]], p_cb->p_ndef_handler[i]->name_len) == 0)  )
+                        {
+                            /* Handler found. */
+                            break;
+                        }
+                    }
+                    /* Check if handler is using prefix abrieviation, but NDEF is using absolute URI */
+                    else if ((p_cb->p_ndef_handler[i]->uri_id != NFA_NDEF_URI_ID_ABSOLUTE) && (p_payload[0] == NFA_NDEF_URI_ID_ABSOLUTE))
+                    {
+                        /* Handler is using prefix abrieviation, but NDEF is using absolute URI. Compare URI prefix */
+                        if (  (p_cb->p_ndef_handler[i]->uri_id<NFA_DM_NDEF_WKT_URI_STR_TBL_SIZE)
+                            &&(memcmp (&p_payload[1], nfa_dm_ndef_wkt_uri_str_tbl[p_cb->p_ndef_handler[i]->uri_id], strlen ((const char*) nfa_dm_ndef_wkt_uri_str_tbl[p_cb->p_ndef_handler[i]->uri_id])) == 0)  )
+                        {
+                            /* Handler found. */
+                            break;
+                        }
+                    }
+                }
+            }
+            /* Not looking for specific URI. Check if type_name for this handler matches the NDEF record's type_name */
+            else if (p_cb->p_ndef_handler[i]->name_len == type_name_len)
+            {
+                if (  (type_name_len == 0)
+                    ||(memcmp(p_cb->p_ndef_handler[i]->name, p_type_name, type_name_len) == 0)  )
+                {
+                    /* Handler found */
+                    break;
+                }
+            }
+        }
+
+    }
+
+    if (i < NFA_NDEF_MAX_HANDLERS)
+        return (p_cb->p_ndef_handler[i]);
+    else
+        return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_clear_notified_flag
+**
+** Description      Clear 'whole_message_notified' flag for all the handlers
+**                  (flag used to indicate that this handler has already
+**                  handled the entire incoming NDEF message)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_ndef_clear_notified_flag (void)
+{
+    tNFA_DM_CB *p_cb = &nfa_dm_cb;
+    UINT8 i;
+
+    for (i = 0; i < NFA_NDEF_MAX_HANDLERS; i++)
+    {
+        if (p_cb->p_ndef_handler[i])
+        {
+            p_cb->p_ndef_handler[i]->flags &= ~NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED;
+        }
+    }
+
+
+}
+
+/*******************************************************************************
+**
+** Function         nfa_dm_ndef_handle_message
+**
+** Description      Handle incoming ndef message
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_dm_ndef_handle_message (tNFA_STATUS status, UINT8 *p_msg_buf, UINT32 len)
+{
+    tNFA_DM_CB *p_cb = &nfa_dm_cb;
+    tNDEF_STATUS ndef_status;
+    UINT8 *p_rec, *p_ndef_start, *p_type, *p_payload, *p_rec_end;
+    UINT32 payload_len;
+    UINT8 tnf, type_len, rec_hdr_flags, id_len;
+    tNFA_DM_API_REG_NDEF_HDLR *p_handler;
+    tNFA_NDEF_DATA ndef_data;
+    UINT8 rec_count = 0;
+    BOOLEAN record_handled, entire_message_handled;
+
+    NFA_TRACE_DEBUG3 ("nfa_dm_ndef_handle_message status=%i, msgbuf=%08x, len=%i", status, p_msg_buf, len);
+
+    if (status != NFA_STATUS_OK)
+    {
+        /* If problem reading NDEF message, then exit (no action required) */
+        return;
+    }
+
+    /* If in exclusive RF mode is activer, then route NDEF message callback registered with NFA_StartExclusiveRfControl */
+    if ((p_cb->flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) && (p_cb->p_excl_ndef_cback))
+    {
+        ndef_data.ndef_type_handle = 0;     /* No ndef-handler handle, since this callback is not from RegisterNDefHandler */
+        ndef_data.p_data = p_msg_buf;
+        ndef_data.len = len;
+        (*p_cb->p_excl_ndef_cback) (NFA_NDEF_DATA_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_data);
+        return;
+    }
+
+    /* Handle zero length - notify default handler */
+    if (len == 0)
+    {
+        if ((p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]) != NULL)
+        {
+            NFA_TRACE_DEBUG0 ("Notifying default handler of zero-length NDEF message...");
+            ndef_data.ndef_type_handle = p_handler->ndef_type_handle;
+            ndef_data.p_data = NULL;   /* Start of record */
+            ndef_data.len = 0;
+            (*p_handler->p_ndef_cback) (NFA_NDEF_DATA_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_data);
+        }
+        return;
+    }
+
+    /* Validate the NDEF message */
+    if ((ndef_status = NDEF_MsgValidate (p_msg_buf, len, TRUE)) != NDEF_OK)
+    {
+        NFA_TRACE_ERROR1 ("Received invalid NDEF message. NDEF status=0x%x", ndef_status);
+        return;
+    }
+
+    /* NDEF message received from backgound polling. Pass the NDEF message to the NDEF handlers */
+
+    /* New NDEF message. Clear 'notified' flag for all the handlers */
+    nfa_dm_ndef_clear_notified_flag ();
+
+    /* Indicate that no handler has handled this entire NDEF message (e.g. connection-handover handler *) */
+    entire_message_handled = FALSE;
+
+    /* Get first record in message */
+    p_rec = p_ndef_start = p_msg_buf;
+
+    /* Check each record in the NDEF message */
+    while (p_rec != NULL)
+    {
+        /* Get record type */
+        p_type = NDEF_RecGetType (p_rec, &tnf, &type_len);
+
+        /* Indicate record not handled yet */
+        record_handled = FALSE;
+
+        /* Get pointer to record payload */
+        p_payload = NDEF_RecGetPayload (p_rec, &payload_len);
+
+        /* Find first handler for this type */
+        if ((p_handler = nfa_dm_ndef_find_next_handler (NULL, tnf, p_type, type_len, p_payload, payload_len)) == NULL)
+        {
+            /* Not a registered NDEF type. Use default handler */
+            if ((p_handler = p_cb->p_ndef_handler[NFA_NDEF_DEFAULT_HANDLER_IDX]) != NULL)
+            {
+                NFA_TRACE_DEBUG0 ("No handler found. Using default handler...");
+            }
+        }
+
+        while (p_handler)
+        {
+            /* If handler is for whole NDEF message, and it has already been notified, then skip notification */
+            if (p_handler->flags & NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED)
+            {
+                /* Look for next handler */
+                p_handler = nfa_dm_ndef_find_next_handler (p_handler, tnf, p_type, type_len, p_payload, payload_len);
+                continue;
+            }
+
+            /* Get pointer to record payload */
+            NFA_TRACE_DEBUG1 ("Calling ndef type handler (%x)", p_handler->ndef_type_handle);
+
+            ndef_data.ndef_type_handle = p_handler->ndef_type_handle;
+            ndef_data.p_data = p_rec;   /* Start of record */
+
+            /* Calculate length of NDEF record */
+            if (p_payload != NULL)
+                ndef_data.len = payload_len + (UINT32) (p_payload - p_rec);
+            else
+            {
+                /* If no payload, calculate length of ndef record header */
+                p_rec_end = p_rec;
+
+                /* First byte is the header flags */
+                rec_hdr_flags = *p_rec_end++;
+
+                /* Next byte is the type field length */
+                type_len = *p_rec_end++;
+
+                /* Next is the payload length (1 or 4 bytes) */
+                if (rec_hdr_flags & NDEF_SR_MASK)
+                {
+                    p_rec_end++;
+                }
+                else
+                {
+                    p_rec_end+=4;
+                }
+
+                /* ID field Length */
+                if (rec_hdr_flags & NDEF_IL_MASK)
+                    id_len = *p_rec_end++;
+                else
+                    id_len = 0;
+                p_rec_end+=id_len;
+
+                ndef_data.len = (UINT32) (p_rec_end - p_rec);
+            }
+
+            /* If handler wants entire ndef message, then pass pointer to start of message and  */
+            /* set 'notified' flag so handler won't get notified on subsequent records for this */
+            /* NDEF message.                                                                    */
+            if (p_handler->flags & NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE)
+            {
+                ndef_data.p_data = p_ndef_start;   /* Start of NDEF message */
+                ndef_data.len = len;
+                p_handler->flags |= NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED;
+
+                /* Indicate that at least one handler has received entire NDEF message */
+                entire_message_handled = TRUE;
+            }
+
+            /* Notify NDEF type handler */
+            (*p_handler->p_ndef_cback) (NFA_NDEF_DATA_EVT, (tNFA_NDEF_EVT_DATA *) &ndef_data);
+
+            /* Indicate that at lease one handler has received this record */
+            record_handled = TRUE;
+
+            /* Look for next handler */
+            p_handler = nfa_dm_ndef_find_next_handler (p_handler, tnf, p_type, type_len, p_payload, payload_len);
+        }
+
+
+        /* Check if at least one handler was notified of this record (only happens if no default handler was register) */
+        if ((!record_handled) && (!entire_message_handled))
+        {
+            /* Unregistered NDEF record type; no default handler */
+            NFA_TRACE_WARNING1 ("Unhandled NDEF record (#%i)", rec_count);
+        }
+
+        rec_count++;
+        p_rec = NDEF_MsgGetNextRec (p_rec);
+    }
+}
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
new file mode 100644
index 0000000..ebe7a7b
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_act.c
@@ -0,0 +1,1903 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions for NFA-EE
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfc_api.h"
+#include "nfa_ee_int.h"
+
+
+/* the de-bounce timer:
+ * The NFA-EE API functions are called to set the routing and VS configuration.
+ * When this timer expires, the configuration is sent to NFCC all at once.
+ * This is the timeout value for the de-bounce timer. */
+#ifndef NFA_EE_ROUT_TIMEOUT_VAL
+#define NFA_EE_ROUT_TIMEOUT_VAL         1000
+#endif
+
+#define NFA_EE_ROUT_BUF_SIZE            540
+#define NFA_EE_ROUT_ONE_TECH_CFG_LEN    4
+#define NFA_EE_ROUT_ONE_PROTO_CFG_LEN   4
+#define NFA_EE_ROUT_MAX_TLV_SIZE        0xFD
+
+
+/* the following 2 tables convert the technology mask in API and control block to the command for NFCC */
+#define NFA_EE_NUM_TECH     3
+const UINT8 nfa_ee_tech_mask_list[NFA_EE_NUM_TECH] =
+{
+    NFA_TECHNOLOGY_MASK_A,
+    NFA_TECHNOLOGY_MASK_B,
+    NFA_TECHNOLOGY_MASK_F
+};
+
+const UINT8 nfa_ee_tech_list[NFA_EE_NUM_TECH] =
+{
+    NFC_RF_TECHNOLOGY_A,
+    NFC_RF_TECHNOLOGY_B,
+    NFC_RF_TECHNOLOGY_F
+};
+
+/* the following 2 tables convert the protocol mask in API and control block to the command for NFCC */
+#define NFA_EE_NUM_PROTO     5
+const UINT8 nfa_ee_proto_mask_list[NFA_EE_NUM_PROTO] =
+{
+    NFA_PROTOCOL_MASK_T1T,
+    NFA_PROTOCOL_MASK_T2T,
+    NFA_PROTOCOL_MASK_T3T,
+    NFA_PROTOCOL_MASK_ISO_DEP,
+    NFA_PROTOCOL_MASK_NFC_DEP
+};
+
+const UINT8 nfa_ee_proto_list[NFA_EE_NUM_PROTO] =
+{
+    NFC_PROTOCOL_T1T,
+    NFC_PROTOCOL_T2T,
+    NFC_PROTOCOL_T3T,
+    NFC_PROTOCOL_ISO_DEP,
+    NFC_PROTOCOL_NFC_DEP
+};
+
+static void nfa_ee_check_restore_complete(void);
+static void nfa_ee_report_discover_req_evt(void);
+
+/*******************************************************************************
+**
+** Function         nfa_ee_conn_cback
+**
+** Description      process connection callback event from stack
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    BT_HDR             *p_msg;
+    tNFA_EE_NCI_CONN    cbk;
+
+    NFA_TRACE_DEBUG2("nfa_ee_conn_cback: conn_id: %d, event=0x%02x", conn_id, event);
+
+    cbk.hdr.event   = NFA_EE_NCI_CONN_EVT;
+    if (event == NFC_DATA_CEVT)
+    {
+        /* Treat data event specially to avoid potential memory leak */
+        cbk.hdr.event   = NFA_EE_NCI_DATA_EVT;
+    }
+    cbk.conn_id     = conn_id;
+    cbk.event       = event;
+    cbk.p_data      = p_data;
+    p_msg           = (BT_HDR *)&cbk;
+
+    nfa_ee_evt_hdlr (p_msg);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_total_aid_len
+**
+** Description      Find the total len in aid_cfg from start_entry to the last
+**
+** Returns          void
+**
+*******************************************************************************/
+int nfa_ee_find_total_aid_len(tNFA_EE_ECB *p_cb, int start_entry)
+{
+    int len = 0, xx;
+
+    if (p_cb->aid_entries > start_entry)
+    {
+        for (xx = start_entry; xx < p_cb->aid_entries; xx++)
+        {
+            len += p_cb->aid_len[xx];
+        }
+    }
+    return len;
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_aid_offset
+**
+** Description      Given the AID, find the associated tNFA_EE_ECB and the
+**                  offset in aid_cfg[]. *p_entry is the index.
+**
+** Returns          void
+**
+*******************************************************************************/
+tNFA_EE_ECB * nfa_ee_find_aid_offset(UINT8 aid_len, UINT8 *p_aid, int *p_offset, int *p_entry)
+{
+    int  xx, yy, aid_len_offset, offset;
+    tNFA_EE_ECB *p_ret = NULL, *p_ecb;
+
+    p_ecb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+    aid_len_offset = 1; /* skip the tag */
+    for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_ecb++)
+    {
+        if (p_ecb->aid_entries)
+        {
+            offset = 0;
+            for (xx = 0; xx < p_ecb->aid_entries; xx++)
+            {
+                if (  (p_ecb->aid_cfg[offset + aid_len_offset] == aid_len)
+                    &&(memcmp(&p_ecb->aid_cfg[offset + aid_len_offset + 1], p_aid, aid_len) == 0)  )
+                {
+                    p_ret = p_ecb;
+                    if (p_offset)
+                        *p_offset = offset;
+                    if (p_entry)
+                        *p_entry  = xx;
+                    break;
+                }
+                offset += p_ecb->aid_len[xx];
+            }
+
+            if (p_ret)
+            {
+                /* found the entry already */
+                break;
+            }
+        }
+        p_ecb = &nfa_ee_cb.ecb[yy];
+    }
+
+    return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_event
+**
+** Description      report the given event to the callback
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_report_event(tNFA_EE_CBACK *p_cback, tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data)
+{
+    int xx;
+
+    /* use the given callback, if not NULL */
+    if (p_cback)
+    {
+        (*p_cback)(event, p_data);
+        return;
+    }
+    /* if the given is NULL, report to all registered ones */
+    for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+    {
+        if (nfa_ee_cb.p_ee_cback[xx] != NULL)
+        {
+            (*nfa_ee_cb.p_ee_cback[xx])(event, p_data);
+        }
+    }
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_start_timer
+**
+** Description      start the de-bounce timer
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_start_timer(void)
+{
+    nfa_sys_start_timer(&nfa_ee_cb.timer, NFA_EE_ROUT_TIMEOUT_EVT, NFA_EE_ROUT_TIMEOUT_VAL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_discover
+**
+** Description      process discover command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_discover(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_CBACK *p_cback = p_data->ee_discover.p_cback;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+
+    NFA_TRACE_DEBUG1 ("nfa_ee_api_discover() in_use:%d", nfa_ee_cb.discv_timer.in_use);
+    if (nfa_ee_cb.discv_timer.in_use)
+    {
+        nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+        NFC_NfceeDiscover(FALSE);
+    }
+    if (nfa_ee_cb.p_ee_disc_cback == NULL && NFC_NfceeDiscover(TRUE) == NFC_STATUS_OK)
+    {
+        nfa_ee_cb.p_ee_disc_cback   = p_cback;
+    }
+    else
+    {
+        evt_data.status = NFA_STATUS_FAILED;
+        nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_register
+**
+** Description      process register command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_register(tNFA_EE_MSG *p_data)
+{
+    int xx;
+    tNFA_EE_CBACK *p_cback = p_data->ee_register.p_cback;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+    BOOLEAN found = FALSE;
+
+    evt_data.ee_register = NFA_STATUS_FAILED;
+    /* loop through all entries to see if there's a matching callback */
+    for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+    {
+        if (nfa_ee_cb.p_ee_cback[xx] == p_cback)
+        {
+            evt_data.ee_register        = NFA_STATUS_OK;
+            found                       = TRUE;
+            break;
+        }
+    }
+
+    /* If no matching callback, allocated an entry */
+    if (!found)
+    {
+        for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+        {
+            if (nfa_ee_cb.p_ee_cback[xx] == NULL)
+        {
+            nfa_ee_cb.p_ee_cback[xx]    = p_cback;
+            evt_data.ee_register        = NFA_STATUS_OK;
+            break;
+        }
+    }
+    }
+    /* This callback is verified (not NULL) in NFA_EeRegister() */
+    (*p_cback)(NFA_EE_REGISTER_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_deregister
+**
+** Description      process de-register command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_deregister(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_CBACK *p_cback = NULL;
+    int                 index  = p_data->deregister.index;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+
+    NFA_TRACE_DEBUG0 ("nfa_ee_api_deregister");
+    p_cback = nfa_ee_cb.p_ee_cback[index];
+    nfa_ee_cb.p_ee_cback[index] = NULL;
+    if (p_cback)
+        (*p_cback)(NFA_EE_DEREGISTER_EVT, &evt_data);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_mode_set
+**
+** Description      process mode set command from user
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_mode_set(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB *p_cb= p_data->cfg_hdr.p_cb;
+
+    NFA_TRACE_DEBUG2 ("nfa_ee_api_mode_set() handle:0x%02x mode:%d", p_cb->nfcee_id, p_data->mode_set.mode);
+    NFC_NfceeModeSet (p_cb->nfcee_id, p_data->mode_set.mode);
+    /* set the NFA_EE_STATUS_PENDING bit to indicate the status is not exactly active */
+    if (p_data->mode_set.mode == NFC_MODE_ACTIVATE)
+        p_cb->ee_status = NFA_EE_STATUS_PENDING | NFA_EE_STATUS_ACTIVE;
+    else
+    {
+        p_cb->ee_status = NFA_EE_STATUS_INACTIVE;
+        /* DH should release the NCI connection before deactivate the NFCEE */
+        if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+        {
+            p_cb->conn_st = NFA_EE_CONN_ST_DISC;
+            NFC_ConnClose(p_cb->conn_id);
+        }
+    }
+    /* report the NFA_EE_MODE_SET_EVT status on the response from NFCC */
+}
+
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_set_tech_cfg
+**
+** Description      process set technology routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+
+    p_cb->tech_switch_on   = p_data->set_tech.technologies_switch_on;
+    p_cb->tech_switch_off  = p_data->set_tech.technologies_switch_off;
+    p_cb->tech_battery_off = p_data->set_tech.technologies_battery_off;
+    p_cb->ecb_flags       |= NFA_EE_ECB_FLAGS_TECH;
+    if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off)
+    {
+        /* if any technology in any power mode is configured, mark this entry as configured */
+        nfa_ee_cb.ee_cfged    |= nfa_ee_ecb_to_mask(p_cb);
+    }
+    nfa_ee_start_timer();
+    nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_TECH_CFG_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_set_proto_cfg
+**
+** Description      process set protocol routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+
+    p_cb->proto_switch_on       = p_data->set_proto.protocols_switch_on;
+    p_cb->proto_switch_off      = p_data->set_proto.protocols_switch_off;
+    p_cb->proto_battery_off     = p_data->set_proto.protocols_battery_off;
+    p_cb->ecb_flags            |= NFA_EE_ECB_FLAGS_PROTO;
+    if (p_cb->proto_switch_on | p_cb->proto_switch_off | p_cb->proto_battery_off)
+    {
+        /* if any protocol in any power mode is configured, mark this entry as configured */
+        nfa_ee_cb.ee_cfged         |= nfa_ee_ecb_to_mask(p_cb);
+    }
+    nfa_ee_start_timer();
+    nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_SET_PROTO_CFG_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_add_aid
+**
+** Description      process add an AID routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_API_ADD_AID *p_add = &p_data->add_aid;
+    tNFA_EE_ECB *p_cb = p_data->cfg_hdr.p_cb;
+    tNFA_EE_ECB *p_chk_cb;
+    UINT8   *p, *p_start;
+    int     len, len_needed;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+    int offset = 0, entry = 0;
+
+    NFA_TRACE_DEBUG3 ("nfa_ee_api_add_aid nfcee_id:0x%x %02x%02x",
+        p_cb->nfcee_id, p_add->p_aid[0], p_add->p_aid[1]);
+    p_chk_cb = nfa_ee_find_aid_offset(p_add->aid_len, p_add->p_aid, &offset, &entry);
+    if (p_chk_cb)
+    {
+        NFA_TRACE_DEBUG0 ("nfa_ee_api_add_aid The AID entry is already in the database");
+        if (p_chk_cb == p_cb)
+        {
+            p_cb->aid_rt_info[entry]    |= NFA_EE_AE_ROUTE;
+            p_cb->aid_pwr_cfg[entry]     = p_add->power_state;
+        }
+        else
+        {
+            NFA_TRACE_ERROR1 ("The AID entry is already in the database for different NFCEE ID:0x%02x", p_chk_cb->nfcee_id);
+            evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
+        }
+    }
+    else
+    {
+        /* Find the total length so far */
+        len = nfa_ee_find_total_aid_len(p_cb, 0);
+
+        /* make sure the control block has enough room to hold this entry */
+        len_needed  = p_add->aid_len + 2; /* tag/len */
+
+        if ((len_needed + len) > NFA_EE_MAX_AID_CFG_LEN)
+        {
+            evt_data.status = NFA_STATUS_BUFFER_FULL;
+        }
+        else
+        {
+            /* add AID */
+            p_cb->aid_pwr_cfg[p_cb->aid_entries]    = p_add->power_state;
+            p_cb->aid_rt_info[p_cb->aid_entries]    = NFA_EE_AE_ROUTE;
+            p       = p_cb->aid_cfg + len;
+            p_start = p;
+            *p++    = NFA_EE_AID_CFG_TAG_NAME;
+            *p++    = p_add->aid_len;
+            memcpy(p, p_add->p_aid, p_add->aid_len);
+            p      += p_add->aid_len;
+
+            p_cb->aid_len[p_cb->aid_entries++]     = (UINT8)(p - p_start);
+        }
+    }
+
+    if (evt_data.status == NFA_STATUS_OK)
+    {
+        /* mark AID changed */
+        p_cb->ecb_flags                       |= NFA_EE_ECB_FLAGS_AID;
+        nfa_ee_cb.ee_cfged                    |= nfa_ee_ecb_to_mask(p_cb);
+        nfa_ee_start_timer();
+    }
+    NFA_TRACE_DEBUG2 ("status:%d ee_cfged:0x%02x ",evt_data.status, nfa_ee_cb.ee_cfged);
+    /* report the status of this operation */
+    nfa_ee_report_event (p_cb->p_ee_cback, NFA_EE_ADD_AID_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_remove_aid
+**
+** Description      process remove an AID routing configuration from user
+**                  start a 1 second timer. When the timer expires,
+**                  the configuration collected in control block is sent to NFCC
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB  *p_cb;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+    int offset = 0, entry = 0, len;
+    int rest_len;
+    tNFA_EE_CBACK *p_cback = NULL;
+
+    NFA_TRACE_DEBUG0 ("nfa_ee_api_remove_aid");
+    p_cb = nfa_ee_find_aid_offset(p_data->rm_aid.aid_len, p_data->rm_aid.p_aid, &offset, &entry);
+    if (p_cb && p_cb->aid_entries)
+    {
+        NFA_TRACE_DEBUG2 ("aid_rt_info[%d]: 0x%02x", entry, p_cb->aid_rt_info[entry]);
+        /* mark routing and VS changed */
+        if (p_cb->aid_rt_info[entry] & NFA_EE_AE_ROUTE)
+            p_cb->ecb_flags         |= NFA_EE_ECB_FLAGS_AID;
+
+        if (p_cb->aid_rt_info[entry] & NFA_EE_AE_VS)
+            p_cb->ecb_flags         |= NFA_EE_ECB_FLAGS_VS;
+
+        /* remove the aid */
+        if ((entry+1) < p_cb->aid_entries)
+        {
+            /* not the last entry, move the aid entries in control block */
+            /* Find the total len from the next entry to the last one */
+            rest_len = nfa_ee_find_total_aid_len(p_cb, entry + 1);
+
+            len = p_cb->aid_len[entry];
+            NFA_TRACE_DEBUG2 ("nfa_ee_api_remove_aid len:%d, rest_len:%d", len, rest_len);
+            GKI_shiftup (&p_cb->aid_cfg[offset], &p_cb->aid_cfg[offset+ len], rest_len);
+            rest_len = p_cb->aid_entries - entry;
+            GKI_shiftup (&p_cb->aid_len[entry], &p_cb->aid_len[entry + 1], rest_len);
+            GKI_shiftup (&p_cb->aid_pwr_cfg[entry], &p_cb->aid_pwr_cfg[entry + 1], rest_len);
+            GKI_shiftup (&p_cb->aid_rt_info[entry], &p_cb->aid_rt_info[entry + 1], rest_len);
+        }
+        /* else the last entry, just reduce the aid_entries by 1 */
+        p_cb->aid_entries--;
+        nfa_ee_cb.ee_cfged      |= nfa_ee_ecb_to_mask(p_cb);
+        nfa_ee_start_timer();
+        /* report NFA_EE_REMOVE_AID_EVT to the callback associated the NFCEE */
+        p_cback = p_cb->p_ee_cback;
+    }
+    else
+    {
+        NFA_TRACE_ERROR0 ("nfa_ee_api_remove_aid The AID entry is not in the database");
+        evt_data.status = NFA_STATUS_INVALID_PARAM;
+    }
+    nfa_ee_report_event (p_cback, NFA_EE_REMOVE_AID_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_update_now
+**
+** Description      Initiates connection creation process to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_update_now(tNFA_EE_MSG *p_data)
+{
+    nfa_sys_stop_timer(&nfa_ee_cb.timer);
+    nfa_ee_cb.ee_cfged  |= NFA_EE_CFGED_UPDATE_NOW;
+    nfa_ee_rout_timeout(p_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_connect
+**
+** Description      Initiates connection creation process to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_connect(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB  *p_cb = p_data->connect.p_cb;
+    int xx;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+
+    evt_data.connect.status       = NFA_STATUS_FAILED;
+    if (p_cb->conn_st == NFA_EE_CONN_ST_NONE)
+    {
+        for (xx = 0; xx < p_cb->num_interface; xx++)
+        {
+            if (p_data->connect.ee_interface == p_cb->ee_interface[xx])
+            {
+                p_cb->p_ee_cback        = p_data->connect.p_cback;
+                p_cb->conn_st           = NFA_EE_CONN_ST_WAIT;
+                p_cb->use_interface     = p_data->connect.ee_interface;
+                evt_data.connect.status = NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_data->connect.nfcee_id,
+                    p_data->connect.ee_interface, nfa_ee_conn_cback);
+                /* report the NFA_EE_CONNECT_EVT status on the response from NFCC */
+                break;
+            }
+        }
+    }
+
+    if (evt_data.connect.status != NCI_STATUS_OK)
+    {
+        evt_data.connect.ee_handle    = (tNFA_HANDLE)p_data->connect.nfcee_id | NFA_HANDLE_GROUP_EE;
+        evt_data.connect.status       = NFA_STATUS_INVALID_PARAM;
+        evt_data.connect.ee_interface = p_data->connect.ee_interface;
+        nfa_ee_report_event (p_data->connect.p_cback, NFA_EE_CONNECT_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_send_data
+**
+** Description      Send the given data packet to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_send_data(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB  *p_cb = p_data->send_data.p_cb;
+    BT_HDR *p_pkt;
+    UINT16 size = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + p_data->send_data.data_len + BT_HDR_SIZE;
+    UINT8  *p;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+
+    if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+    {
+        p_pkt = (BT_HDR *)GKI_getbuf(size);
+        if (p_pkt)
+        {
+            p_pkt->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p_pkt->len      = p_data->send_data.data_len;
+            p               = (UINT8 *)(p_pkt+1) + p_pkt->offset;
+            memcpy(p, p_data->send_data.p_data, p_pkt->len);
+            NFC_SendData (p_cb->conn_id, p_pkt);
+        }
+        else
+        {
+            nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
+        }
+    }
+    else
+    {
+        nfa_ee_report_event( p_cb->p_ee_cback, NFA_EE_NO_CB_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_api_disconnect
+**
+** Description      Initiates closing of the connection to the given NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_api_disconnect(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB  *p_cb = p_data->disconnect.p_cb;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+
+    if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+    {
+        p_cb->conn_st = NFA_EE_CONN_ST_DISC;
+        NFC_ConnClose(p_cb->conn_id);
+    }
+    evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+    nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_DISCONNECT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_disc_done
+**
+** Description      Process the callback for NFCEE discovery response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_report_disc_done(BOOLEAN notify_enable_done)
+{
+    tNFA_EE_CBACK           *p_cback;
+    tNFA_EE_CBACK_DATA      evt_data = {0};
+
+    NFA_TRACE_DEBUG3("nfa_ee_report_disc_done() em_state:%d num_ee_expecting:%d notify_enable_done:%d", nfa_ee_cb.em_state, nfa_ee_cb.num_ee_expecting, notify_enable_done);
+    if (nfa_ee_cb.num_ee_expecting == 0)
+    {
+        if (notify_enable_done)
+        {
+            if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE)
+            {
+                nfa_sys_cback_notify_enable_complete (NFA_ID_EE);
+                if (nfa_ee_cb.p_enable_cback)
+                    (*nfa_ee_cb.p_enable_cback)(FALSE);
+            }
+            else if ((nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING) && (nfa_ee_cb.ee_flags & NFA_EE_FLAG_NOTIFY_HCI) )
+            {
+                nfa_ee_cb.ee_flags   &= ~NFA_EE_FLAG_NOTIFY_HCI;
+                if (nfa_ee_cb.p_enable_cback)
+                    (*nfa_ee_cb.p_enable_cback)(FALSE);
+            }
+        }
+
+
+        if (nfa_ee_cb.p_ee_disc_cback)
+        {
+            /* notify API callback */
+            p_cback                         = nfa_ee_cb.p_ee_disc_cback;
+            nfa_ee_cb.p_ee_disc_cback       = NULL;
+            evt_data.status                         = NFA_STATUS_OK;
+            evt_data.ee_discover.num_ee             = NFA_EE_MAX_EE_SUPPORTED;
+            NFA_EeGetInfo(&evt_data.ee_discover.num_ee, evt_data.ee_discover.ee_info);
+            nfa_ee_report_event (p_cback, NFA_EE_DISCOVER_EVT, &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_restore_ntf_done
+**
+** Description      check if any ee_status still has NFA_EE_STATUS_PENDING bit
+**
+** Returns          TRUE, if all NFA_EE_STATUS_PENDING bits are removed
+**
+*******************************************************************************/
+static BOOLEAN nfa_ee_restore_ntf_done(void)
+{
+    tNFA_EE_ECB     *p_cb;
+    BOOLEAN         is_done = TRUE;
+    int             xx;
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING))
+        {
+            is_done = FALSE;
+            break;
+        }
+    }
+    return is_done;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_remove_pending
+**
+** Description      check if any ee_status still has NFA_EE_STATUS_RESTORING bit
+**
+** Returns          TRUE, if all NFA_EE_STATUS_RESTORING bits are removed
+**
+*******************************************************************************/
+static void nfa_ee_remove_pending(void)
+{
+    tNFA_EE_ECB     *p_cb;
+    tNFA_EE_ECB     *p_cb_n, *p_cb_end;
+    int             xx, num_removed = 0;
+    int             first_removed = NFA_EE_MAX_EE_SUPPORTED;
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING))
+        {
+            p_cb->nfcee_id  = NFA_EE_INVALID;
+            num_removed ++;
+            if (first_removed == NFA_EE_MAX_EE_SUPPORTED)
+                first_removed   = xx;
+        }
+    }
+
+    NFA_TRACE_DEBUG3("nfa_ee_remove_pending() cur_ee:%d, num_removed:%d first_removed:%d", nfa_ee_cb.cur_ee, num_removed, first_removed);
+    if (num_removed && (first_removed != (nfa_ee_cb.cur_ee - num_removed)))
+    {
+        /* if the removes ECB entried are not at the end, move the entries up */
+        p_cb_end = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+        p_cb = &nfa_ee_cb.ecb[first_removed];
+        for (p_cb_n = p_cb + 1; p_cb_n <= p_cb_end;)
+        {
+            while ((p_cb_n->nfcee_id == NFA_EE_INVALID) && (p_cb_n <= p_cb_end))
+            {
+                p_cb_n++;
+            }
+
+            if (p_cb_n <= p_cb_end)
+            {
+                memcpy(p_cb, p_cb_n, sizeof(tNFA_EE_ECB));
+                p_cb_n->nfcee_id = NFA_EE_INVALID;
+            }
+            p_cb++;
+            p_cb_n++;
+        }
+    }
+    nfa_ee_cb.cur_ee -= (UINT8)num_removed;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_disc_rsp
+**
+** Description      Process the callback for NFCEE discovery response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data)
+{
+    tNFC_NFCEE_DISCOVER_REVT    *p_evt = p_data->disc_rsp.p_data;
+    tNFA_EE_ECB              *p_cb;
+    UINT8   xx;
+    UINT8   num_nfcee = p_evt->num_nfcee;
+    BOOLEAN notify_enable_done = FALSE;
+
+    NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d, num_nfcee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, num_nfcee);
+    switch (nfa_ee_cb.em_state)
+    {
+    case NFA_EE_EM_STATE_INIT:
+        nfa_ee_cb.cur_ee            = 0;
+        nfa_ee_cb.num_ee_expecting  = 0;
+        if (num_nfcee == 0)
+        {
+            nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+            notify_enable_done = TRUE;
+            if (p_evt->status != NFC_STATUS_OK)
+            {
+                nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+            }
+        }
+        break;
+
+    case NFA_EE_EM_STATE_INIT_DONE:
+        if (num_nfcee)
+        {
+            /* if this is initiated by api function,
+             * check if the number of NFCEE expected is more than what's currently in CB */
+            if (num_nfcee > NFA_EE_MAX_EE_SUPPORTED)
+                num_nfcee = NFA_EE_MAX_EE_SUPPORTED;
+            if (nfa_ee_cb.cur_ee < num_nfcee)
+            {
+                p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee];
+                for (xx = nfa_ee_cb.cur_ee; xx < num_nfcee; xx++, p_cb++)
+                {
+                    /* mark the new entries as a new one */
+                    p_cb->nfcee_id = NFA_EE_INVALID;
+                }
+            }
+            nfa_ee_cb.cur_ee = num_nfcee;
+        }
+        break;
+
+    case NFA_EE_EM_STATE_RESTORING:
+        if (num_nfcee == 0)
+        {
+            nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+            nfa_ee_remove_pending();
+            nfa_ee_check_restore_complete();
+            if (p_evt->status != NFC_STATUS_OK)
+            {
+                nfa_sys_stop_timer(&nfa_ee_cb.discv_timer);
+            }
+        }
+        break;
+    }
+
+    if (p_evt->status == NFC_STATUS_OK)
+    {
+        nfa_ee_cb.num_ee_expecting = p_evt->num_nfcee;
+        if (nfa_ee_cb.num_ee_expecting > NFA_EE_MAX_EE_SUPPORTED)
+        {
+            NFA_TRACE_ERROR2 ("NFA-EE num_ee_expecting:%d > max:%d", nfa_ee_cb.num_ee_expecting, NFA_EE_MAX_EE_SUPPORTED);
+        }
+    }
+    nfa_ee_report_disc_done(notify_enable_done);
+    NFA_TRACE_DEBUG3("nfa_ee_nci_disc_rsp() em_state:%d cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_disc_ntf
+**
+** Description      Process the callback for NFCEE discovery notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data)
+{
+    tNFC_NFCEE_INFO_REVT    *p_ee = p_data->disc_ntf.p_data;
+    tNFA_EE_ECB             *p_cb = NULL;
+    BOOLEAN                 notify_enable_done = FALSE;
+    BOOLEAN                 notify_new_ee = FALSE;
+    tNFA_EE_CBACK_DATA      evt_data = {0};
+    tNFA_EE_INFO            *p_info;
+    tNFA_EE_EM_STATE        new_em_state = NFA_EE_EM_STATE_MAX;
+
+    NFA_TRACE_DEBUG4("nfa_ee_nci_disc_ntf() em_state:%d ee_flags:0x%x cur_ee:%d num_ee_expecting:%d", nfa_ee_cb.em_state, nfa_ee_cb.ee_flags, nfa_ee_cb.cur_ee, nfa_ee_cb.num_ee_expecting);
+    if (nfa_ee_cb.num_ee_expecting)
+    {
+        nfa_ee_cb.num_ee_expecting--;
+        if ((nfa_ee_cb.num_ee_expecting == 0) && (nfa_ee_cb.p_ee_disc_cback != NULL))
+        {
+            /* Discovery triggered by API function */
+            NFC_NfceeDiscover(FALSE);
+        }
+    }
+    switch (nfa_ee_cb.em_state)
+    {
+    case NFA_EE_EM_STATE_INIT:
+        if (nfa_ee_cb.cur_ee < NFA_EE_MAX_EE_SUPPORTED)
+        {
+            /* the cb can collect up to NFA_EE_MAX_EE_SUPPORTED ee_info */
+            p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee++];
+        }
+
+        if (nfa_ee_cb.num_ee_expecting == 0)
+        {
+            /* notify init_done callback */
+            nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+            notify_enable_done = TRUE;
+        }
+        break;
+
+    case NFA_EE_EM_STATE_INIT_DONE:
+        p_cb = nfa_ee_find_ecb (p_ee->nfcee_id);
+        if (p_cb == NULL)
+        {
+            /* the NFCEE ID is not in the last NFCEE discovery
+             * maybe it's a new one */
+            p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
+            if (p_cb)
+            {
+                nfa_ee_cb.cur_ee++;
+                notify_new_ee = TRUE;
+            }
+        }
+        else if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER)
+        {
+            nfa_ee_cb.cur_ee++;
+            notify_new_ee = TRUE;
+        }
+        else
+        {
+            NFA_TRACE_DEBUG3 ("cur_ee:%d ecb_flags=0x%02x  ee_status=0x%x", nfa_ee_cb.cur_ee, p_cb->ecb_flags, p_cb->ee_status);
+        }
+        break;
+
+    case NFA_EE_EM_STATE_RESTORING:
+        p_cb = nfa_ee_find_ecb (p_ee->nfcee_id);
+        if (p_cb == NULL)
+        {
+            /* the NFCEE ID is not in the last NFCEE discovery
+             * maybe it's a new one */
+            p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
+            if (p_cb)
+            {
+                nfa_ee_cb.cur_ee++;
+                notify_new_ee = TRUE;
+            }
+        }
+        if (nfa_ee_cb.num_ee_expecting == 0)
+        {
+            /* notify init_done callback */
+            notify_enable_done = TRUE;
+            if (nfa_ee_restore_ntf_done())
+            {
+                new_em_state       = NFA_EE_EM_STATE_INIT_DONE;
+            }
+        }
+        break;
+    }
+    NFA_TRACE_DEBUG1 ("nfa_ee_nci_disc_ntf cur_ee:%d", nfa_ee_cb.cur_ee);
+
+    if (p_cb)
+    {
+        p_cb->nfcee_id      = p_ee->nfcee_id;
+        p_cb->ee_status     = p_ee->ee_status;
+        p_cb->num_interface = p_ee->num_interface;
+        memcpy(p_cb->ee_interface, p_ee->ee_interface, p_ee->num_interface);
+        p_cb->num_tlvs      = p_ee->num_tlvs;
+        memcpy(p_cb->ee_tlv, p_ee->ee_tlv, p_ee->num_tlvs * sizeof(tNFA_EE_TLV));
+
+        if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_RESTORING)
+        {
+            /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access"
+             * SHALL NOT contain any other additional Protocol
+             * i.e. check only first supported NFCEE interface is HCI access */
+            /* NFA_HCI module handles restoring configurations for HCI access */
+            if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+            {
+                if ((nfa_ee_cb.ee_flags & NFA_EE_FLAG_WAIT_HCI) == 0)
+                {
+                    nfa_ee_restore_one_ecb (p_cb);
+                }
+                /* else wait for NFA-HCI module to restore the HCI network information before enabling the NFCEE */
+            }
+        }
+
+        if ((nfa_ee_cb.p_ee_disc_cback == NULL) && (notify_new_ee == TRUE))
+        {
+            if (nfa_dm_is_active() && (p_cb->ee_status != NFA_EE_STATUS_REMOVED))
+            {
+                /* report this NFA_EE_NEW_EE_EVT only after NFA_DM_ENABLE_EVT is reported */
+                p_info                  = &evt_data.new_ee;
+                p_info->ee_handle       = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+                p_info->ee_status       = p_cb->ee_status;
+                p_info->num_interface   = p_cb->num_interface;
+                p_info->num_tlvs        = p_cb->num_tlvs;
+                memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
+                memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
+                nfa_ee_report_event (NULL, NFA_EE_NEW_EE_EVT, &evt_data);
+            }
+        }
+        else
+            nfa_ee_report_disc_done(notify_enable_done);
+
+        if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER)
+        {
+            NFA_TRACE_DEBUG0 ("NFA_EE_ECB_FLAGS_ORDER");
+            p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_ORDER;
+            nfa_ee_report_discover_req_evt();
+        }
+    }
+
+    if (new_em_state != NFA_EE_EM_STATE_MAX)
+    {
+        nfa_ee_cb.em_state = new_em_state;
+        nfa_ee_check_restore_complete();
+    }
+
+    if ((nfa_ee_cb.cur_ee == nfa_ee_max_ee_cfg) && (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) )
+    {
+        if (nfa_ee_cb.discv_timer.in_use)
+        {
+            nfa_sys_stop_timer (&nfa_ee_cb.discv_timer);
+            p_data->hdr.event = NFA_EE_DISCV_TIMEOUT_EVT;
+            nfa_ee_evt_hdlr((BT_HDR *)p_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_check_restore_complete
+**
+** Description      Check if restore the NFA-EE related configuration to the
+**                  state prior to low power mode is complete.
+**                  If complete, notify sys.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_check_restore_complete(void)
+{
+    UINT32  xx;
+    tNFA_EE_ECB     *p_cb;
+    BOOLEAN         proc_complete = TRUE;
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
+        {
+            /* NFA_HCI module handles restoring configurations for HCI access.
+             * ignore the restoring status for HCI Access */
+            if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+            {
+                proc_complete = FALSE;
+                break;
+            }
+        }
+    }
+
+    NFA_TRACE_DEBUG2 ("nfa_ee_check_restore_complete nfa_ee_cb.ee_cfg_sts:0x%02x proc_complete:%d", nfa_ee_cb.ee_cfg_sts, proc_complete);
+    if (proc_complete)
+    {
+        /* update routing table when NFA_EE_ROUT_TIMEOUT_EVT is received */
+        if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
+            nfa_ee_api_update_now(NULL);
+
+        nfa_ee_cb.em_state = NFA_EE_EM_STATE_INIT_DONE;
+        nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_report_discover_req_evt
+**
+** Description      Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_ee_report_discover_req_evt(void)
+{
+    tNFA_EE_DISCOVER_REQ    evt_data;
+    tNFA_EE_DISCOVER_INFO   *p_info;
+    UINT8                   xx;
+    tNFA_EE_ECB  *p_cb = nfa_ee_cb.ecb;
+
+    /* if this is restoring NFCC */
+    if (!nfa_dm_is_active ())
+    {
+        NFA_TRACE_DEBUG0 ("nfa_ee_report_discover_req_evt DM is not active");
+        return;
+    }
+
+    evt_data.num_ee = 0;
+    p_cb            = nfa_ee_cb.ecb;
+    p_info          = evt_data.ee_disc_info;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) || (p_cb->ee_status != NFA_EE_STATUS_ACTIVE) || ((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_DISC_REQ) == 0))
+        {
+            continue;
+        }
+        p_info->la_protocol     = p_cb->la_protocol;
+        p_info->lb_protocol     = p_cb->lb_protocol;
+        p_info->lf_protocol     = p_cb->lf_protocol;
+        p_info->lbp_protocol    = p_cb->lbp_protocol;
+        evt_data.num_ee++;
+        p_info++;
+
+        NFA_TRACE_DEBUG6 ("[%d] ee_handle:0x%x, listen protocol A:%d, B:%d, F:%d, BP:%d",
+                          evt_data.num_ee, p_cb->nfcee_id,
+                          p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol, p_cb->lbp_protocol);
+    }
+
+    evt_data.status     = NFA_STATUS_OK;
+    nfa_ee_report_event(NULL, NFA_EE_DISCOVER_REQ_EVT, (tNFA_EE_CBACK_DATA *)&evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_mode_set_rsp
+**
+** Description      Process the result for NFCEE ModeSet response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB *p_cb;
+    tNFA_EE_MODE_SET    mode_set;
+    tNFC_NFCEE_MODE_SET_REVT    *p_rsp = p_data->mode_set_rsp.p_data;
+
+    NFA_TRACE_DEBUG2 ("nfa_ee_nci_mode_set_rsp() handle:0x%02x mode:%d", p_rsp->nfcee_id, p_rsp->mode);
+    p_cb = nfa_ee_find_ecb (p_rsp->nfcee_id);
+    if (p_cb == NULL)
+    {
+        NFA_TRACE_ERROR1 ("nfa_ee_nci_mode_set_rsp() Can not find cb for handle:0x%02x", p_rsp->nfcee_id);
+        return;
+    }
+
+    /* update routing table and vs on mode change */
+    nfa_ee_start_timer();
+
+    if (p_rsp->status == NFA_STATUS_OK)
+    {
+
+        if (p_rsp->mode == NFA_EE_MD_ACTIVATE)
+        {
+            p_cb->ee_status = NFC_NFCEE_STATUS_ACTIVE;
+        }
+        else
+        {
+            if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
+                p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off |
+                p_cb->aid_entries)
+            {
+                /* this NFCEE still has configuration when deactivated. clear the configuration */
+                nfa_ee_cb.ee_cfged  &= ~nfa_ee_ecb_to_mask(p_cb);
+                nfa_ee_cb.ee_cfg_sts|= NFA_EE_STS_CHANGED_ROUTING;
+                NFA_TRACE_DEBUG0("deactivating/still configured. Force update");
+            }
+            p_cb->tech_switch_on    = p_cb->tech_switch_off = p_cb->tech_battery_off    = 0;
+            p_cb->proto_switch_on   = p_cb->proto_switch_off= p_cb->proto_battery_off   = 0;
+            p_cb->aid_entries       = 0;
+            p_cb->ee_status = NFC_NFCEE_STATUS_INACTIVE;
+        }
+    }
+    NFA_TRACE_DEBUG4 ("status:%d ecb_flags  :0x%02x ee_cfged:0x%02x ee_status:%d",
+        p_rsp->status, p_cb->ecb_flags  , nfa_ee_cb.ee_cfged, p_cb->ee_status);
+    if (p_cb->ecb_flags   & NFA_EE_ECB_FLAGS_RESTORE)
+    {
+        if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+        {
+            /* NFA_HCI module handles restoring configurations for HCI access */
+            if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+            {
+                NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, p_cb->nfcee_id,  p_cb->use_interface, nfa_ee_conn_cback);
+            }
+        }
+        else
+        {
+            p_cb->ecb_flags   &= ~NFA_EE_ECB_FLAGS_RESTORE;
+            nfa_ee_check_restore_complete();
+        }
+    }
+    else
+    {
+        mode_set.status     = p_rsp->status;
+        mode_set.ee_handle  = (tNFA_HANDLE)p_rsp->nfcee_id | NFA_HANDLE_GROUP_EE;
+        mode_set.ee_status  = p_cb->ee_status;
+
+        nfa_ee_report_event(p_cb->p_ee_cback, NFA_EE_MODE_SET_EVT, (tNFA_EE_CBACK_DATA *)&mode_set);
+        if (p_cb->ee_status == NFC_NFCEE_STATUS_INACTIVE)
+        {
+            /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
+            nfa_ee_report_discover_req_evt();
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_conn
+**
+** Description      process the connection callback events
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_conn(tNFA_EE_MSG *p_data)
+{
+    tNFA_EE_ECB      *p_cb;
+    tNFA_EE_NCI_CONN    *p_cbk   = &p_data->conn;
+    tNFC_CONN           *p_conn  = p_data->conn.p_data;
+    BT_HDR              *p_pkt   = NULL;
+    tNFA_EE_CBACK_DATA  evt_data = {0};
+    tNFA_EE_EVT         event    = NFA_EE_INVALID;
+    tNFA_EE_CBACK       *p_cback = NULL;
+
+    if (p_cbk->event == NFC_CONN_CREATE_CEVT)
+    {
+        p_cb = nfa_ee_find_ecb (p_cbk->p_data->conn_create.id);
+    }
+    else
+    {
+        p_cb = nfa_ee_find_ecb_by_conn_id (p_cbk->conn_id);
+        if (p_cbk->event == NFC_DATA_CEVT)
+            p_pkt = p_conn->data.p_data;
+    }
+
+    if (p_cb)
+    {
+        p_cback         = p_cb->p_ee_cback;
+        evt_data.handle = (tNFA_HANDLE)p_cb->nfcee_id | NFA_HANDLE_GROUP_EE;
+        switch (p_cbk->event)
+        {
+        case NFC_CONN_CREATE_CEVT:
+            if (p_conn->conn_create.status == NFC_STATUS_OK)
+            {
+                p_cb->conn_id = p_cbk->conn_id;
+                p_cb->conn_st = NFA_EE_CONN_ST_CONN;
+            }
+            else
+            {
+                p_cb->conn_st = NFA_EE_CONN_ST_NONE;
+            }
+            if (p_cb->ecb_flags & NFA_EE_ECB_FLAGS_RESTORE)
+            {
+                p_cb->ecb_flags &= ~NFA_EE_ECB_FLAGS_RESTORE;
+                nfa_ee_check_restore_complete();
+            }
+            else
+            {
+                evt_data.connect.status       = p_conn->conn_create.status;
+                evt_data.connect.ee_interface = p_cb->use_interface;
+                event = NFA_EE_CONNECT_EVT;
+            }
+            break;
+
+        case NFC_CONN_CLOSE_CEVT:
+            if (p_cb->conn_st != NFA_EE_CONN_ST_DISC)
+                event = NFA_EE_DISCONNECT_EVT;
+            p_cb->conn_st    = NFA_EE_CONN_ST_NONE;
+            p_cb->p_ee_cback = NULL;
+            p_cb->conn_id    = 0;
+            if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLING)
+                nfa_ee_sys_disable();
+            break;
+
+        case NFC_DATA_CEVT:
+            if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+            {
+                /* report data event only in connected state */
+                if (p_cb->p_ee_cback && p_pkt)
+                {
+                    evt_data.data.len   = p_pkt->len;
+                    evt_data.data.p_buf = (UINT8 *)(p_pkt+1) + p_pkt->offset;
+                    event               = NFA_EE_DATA_EVT;
+                    p_pkt               = NULL; /* so this function does not free this GKI buffer */
+                }
+            }
+            break;
+        }
+
+        if ((event != NFA_EE_INVALID) && (p_cback))
+            (*p_cback)(event, &evt_data);
+    }
+    if (p_pkt)
+        GKI_freebuf (p_pkt);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_action_ntf
+**
+** Description      process the NFCEE action callback event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data)
+{
+    tNFC_EE_ACTION_REVT *p_cbk = p_data->act.p_data;
+    tNFA_EE_ACTION      evt_data;
+
+    evt_data.ee_handle  = (tNFA_HANDLE)p_cbk->nfcee_id | NFA_HANDLE_GROUP_EE;
+    evt_data.trigger    = p_cbk->act_data.trigger;
+    memcpy (&(evt_data.param), &(p_cbk->act_data.param), sizeof (tNFA_EE_ACTION_PARAM));
+    nfa_ee_report_event(NULL, NFA_EE_ACTION_EVT, (tNFA_EE_CBACK_DATA *)&evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_nci_disc_req_ntf
+**
+** Description      process the NFCEE discover request callback event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data)
+{
+    tNFC_EE_DISCOVER_REQ_REVT   *p_cbk = p_data->disc_req.p_data;
+    tNFA_HANDLE         ee_handle;
+    tNFA_EE_ECB         *p_cb = NULL;
+    UINT8 xx;
+
+    NFA_TRACE_DEBUG2 ("nfa_ee_nci_disc_req_ntf () num_info: %d cur_ee:%d", p_cbk->num_info, nfa_ee_cb.cur_ee );
+
+    for (xx = 0; xx < p_cbk->num_info; xx++)
+    {
+        ee_handle = NFA_HANDLE_GROUP_EE|p_cbk->info[xx].nfcee_id;
+
+        p_cb = nfa_ee_find_ecb (p_cbk->info[xx].nfcee_id);
+        if (!p_cb)
+        {
+            NFA_TRACE_DEBUG1 ("Cannot find cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
+            p_cb = nfa_ee_find_ecb (NFA_EE_INVALID);
+            if (p_cb)
+            {
+                p_cb->nfcee_id   = p_cbk->info[xx].nfcee_id;
+                p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ORDER;
+            }
+            else
+            {
+                NFA_TRACE_ERROR1 ("Cannot allocate cb for NFCEE: 0x%x", p_cbk->info[xx].nfcee_id);
+                continue;
+            }
+        }
+
+        p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_DISC_REQ;
+        if (p_cbk->info[xx].op == NFC_EE_DISC_OP_ADD)
+        {
+            if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
+            {
+                p_cb->la_protocol = p_cbk->info[xx].protocol;
+            }
+            else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
+            {
+                p_cb->lb_protocol = p_cbk->info[xx].protocol;
+            }
+            else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
+            {
+                p_cb->lf_protocol = p_cbk->info[xx].protocol;
+            }
+            else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
+            {
+                p_cb->lbp_protocol = p_cbk->info[xx].protocol;
+            }
+            NFA_TRACE_DEBUG6 ("nfcee_id=0x%x ee_status=0x%x ecb_flags=0x%x la_protocol=0x%x la_protocol=0x%x la_protocol=0x%x",
+                p_cb->nfcee_id, p_cb->ee_status, p_cb->ecb_flags,
+                p_cb->la_protocol, p_cb->lb_protocol, p_cb->lf_protocol);
+        }
+        else
+            {
+                if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)
+                {
+                    p_cb->la_protocol = 0;
+                }
+                else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B)
+                {
+                    p_cb->lb_protocol = 0;
+                }
+                else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F)
+                {
+                    p_cb->lf_protocol = 0;
+                }
+                else if (p_cbk->info[xx].tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)
+                {
+                    p_cb->lbp_protocol = 0;
+            }
+        }
+    }
+
+    /* Report NFA_EE_DISCOVER_REQ_EVT for all active NFCEE */
+    if ((p_cb->ecb_flags & NFA_EE_ECB_FLAGS_ORDER) == 0)
+        nfa_ee_report_discover_req_evt();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_is_active
+**
+** Description      Check if the given NFCEE is active
+**
+** Returns          TRUE if the given NFCEE is active
+**
+*******************************************************************************/
+BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id)
+{
+    BOOLEAN is_active = FALSE;
+    int     xx;
+    tNFA_EE_ECB  *p_cb = nfa_ee_cb.ecb;
+
+    if ((NFA_HANDLE_GROUP_MASK & nfcee_id) == NFA_HANDLE_GROUP_EE)
+        nfcee_id    &= NFA_HANDLE_MASK;
+
+    /* compose output */
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if ((tNFA_HANDLE)p_cb->nfcee_id == nfcee_id)
+        {
+            if (p_cb->ee_status == NFA_EE_STATUS_ACTIVE)
+            {
+                is_active = TRUE;
+            }
+            break;
+        }
+    }
+    return is_active;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_get_tech_route
+**
+** Description      Given a power state, find the technology routing destination.
+**                  The result is filled in the given p_handles
+**                  in the order of A, B, F, Bprime
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles)
+{
+    int     xx, yy;
+    tNFA_EE_ECB *p_cb;
+    UINT8   tech_mask_list[NFA_EE_MAX_TECH_ROUTE] =
+    {
+        NFA_TECHNOLOGY_MASK_A,
+        NFA_TECHNOLOGY_MASK_B,
+        NFA_TECHNOLOGY_MASK_F,
+        NFA_TECHNOLOGY_MASK_B_PRIME
+    };
+
+    NFA_TRACE_DEBUG1("nfa_ee_get_tech_route(): %d", power_state);
+
+    for (xx = 0; xx < NFA_EE_MAX_TECH_ROUTE; xx++)
+    {
+        p_handles[xx] = NFC_DH_ID;
+        p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+        for (yy = 0; yy < nfa_ee_cb.cur_ee; yy++, p_cb--)
+        {
+            if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+            {
+                switch (power_state)
+                {
+                case NFA_EE_PWR_STATE_ON:
+                    if (p_cb->tech_switch_on & tech_mask_list[xx])
+                        p_handles[xx] = p_cb->nfcee_id;
+                    break;
+                case NFA_EE_PWR_STATE_SWITCH_OFF:
+                    if (p_cb->tech_switch_off & tech_mask_list[xx])
+                        p_handles[xx] = p_cb->nfcee_id;
+                    break;
+                case NFA_EE_PWR_STATE_BATT_OFF:
+                    if (p_cb->tech_battery_off & tech_mask_list[xx])
+                        p_handles[xx] = p_cb->nfcee_id;
+                    break;
+                }
+            }
+        }
+    }
+    NFA_TRACE_DEBUG4("0x%x, 0x%x, 0x%x, 0x%x", p_handles[0], p_handles[1], p_handles[2], p_handles[3]);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_route_add_one_ecb
+**
+** Description      Add the routing entries for one NFCEE/DH
+**
+** Returns          NFA_STATUS_OK, if ok to continue
+**
+*******************************************************************************/
+tNFA_STATUS nfa_ee_route_add_one_ecb(tNFA_EE_ECB *p_cb, int max_len, BOOLEAN more, UINT8 *ps, int *p_cur_offset)
+{
+    UINT8   *p, tlv_size, *pa;
+    UINT8   num_tlv, len;
+    int     xx;
+    int     start_offset;
+    UINT8   power_cfg = 0;
+    UINT8   *pp = ps + *p_cur_offset;
+    UINT8   entry_size;
+    UINT8   max_tlv = (UINT8)((max_len > NFA_EE_ROUT_MAX_TLV_SIZE)?NFA_EE_ROUT_MAX_TLV_SIZE:max_len);
+    tNFA_STATUS status = NFA_STATUS_OK;
+
+    /* use the first byte of the buffer (ps) to keep the num_tlv */
+    num_tlv  = *ps;
+    NFA_TRACE_DEBUG5 ("nfa_ee_route_add_one_ecb max_len:%d, max_tlv:%d, cur_offset:%d, more:%d, num_tlv:%d",
+        max_len, max_tlv, *p_cur_offset, more, num_tlv);
+    pp       = ps + 1 + *p_cur_offset;
+    p        = pp;
+    tlv_size = (UINT8)*p_cur_offset;
+    /* add the Technology based routing */
+    for (xx = 0; xx < NFA_EE_NUM_TECH; xx++)
+    {
+        power_cfg = 0;
+        if (p_cb->tech_switch_on & nfa_ee_tech_mask_list[xx])
+            power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+        if (p_cb->tech_switch_off & nfa_ee_tech_mask_list[xx])
+            power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+        if (p_cb->tech_battery_off & nfa_ee_tech_mask_list[xx])
+            power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+        if (power_cfg)
+        {
+            *pp++   = NFC_ROUTE_TAG_TECH;
+            *pp++   = 3;
+            *pp++   = p_cb->nfcee_id;
+            *pp++   = power_cfg;
+            *pp++   = nfa_ee_tech_list[xx];
+            num_tlv++;
+            if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+                nfa_ee_cb.ee_cfged  |= NFA_EE_CFGED_OFF_ROUTING;
+        }
+    }
+
+    /* add the Protocol based routing */
+    for (xx = 0; xx < NFA_EE_NUM_PROTO; xx++)
+    {
+        power_cfg = 0;
+        if (p_cb->proto_switch_on & nfa_ee_proto_mask_list[xx])
+            power_cfg |= NCI_ROUTE_PWR_STATE_ON;
+        if (p_cb->proto_switch_off & nfa_ee_proto_mask_list[xx])
+            power_cfg |= NCI_ROUTE_PWR_STATE_SWITCH_OFF;
+        if (p_cb->proto_battery_off & nfa_ee_proto_mask_list[xx])
+            power_cfg |= NCI_ROUTE_PWR_STATE_BATT_OFF;
+        if (power_cfg)
+        {
+            *pp++   = NFC_ROUTE_TAG_PROTO;
+            *pp++   = 3;
+            *pp++   = p_cb->nfcee_id;
+            *pp++   = power_cfg;
+            *pp++   = nfa_ee_proto_list[xx];
+            num_tlv++;
+            if (power_cfg != NCI_ROUTE_PWR_STATE_ON)
+                nfa_ee_cb.ee_cfged  |= NFA_EE_CFGED_OFF_ROUTING;
+        }
+    }
+
+    /* add the AID routing */
+    if (p_cb->aid_entries)
+    {
+        start_offset = 0;
+        for (xx = 0; xx < p_cb->aid_entries; xx++)
+        {
+            /* add one AID entry */
+            if (p_cb->aid_rt_info[xx] & NFA_EE_AE_ROUTE)
+            {
+                num_tlv++;
+                pa      = &p_cb->aid_cfg[start_offset];
+                pa ++; /* EMV tag */
+                len     = *pa++; /* aid_len */
+                *pp++   = NFC_ROUTE_TAG_AID;
+                *pp++   = len + 2;
+                *pp++   = p_cb->nfcee_id;
+                *pp++   = p_cb->aid_pwr_cfg[xx];
+                /* copy the AID */
+                memcpy(pp, pa, len);
+                pp     += len;
+            }
+            start_offset += p_cb->aid_len[xx];
+        }
+    }
+    entry_size = (UINT8)(pp - p);
+    tlv_size  += entry_size;
+    if (entry_size)
+    {
+        nfa_ee_cb.ee_cfged |= nfa_ee_ecb_to_mask(p_cb);
+    }
+    if (p_cb->ecb_flags   & NFA_EE_ECB_FLAGS_ROUTING)
+    {
+        nfa_ee_cb.ee_cfg_sts   |= NFA_EE_STS_CHANGED_ROUTING;
+    }
+    NFA_TRACE_DEBUG3 ("ee_cfg_sts:0x%02x entry_size:%d, tlv_size:%d", nfa_ee_cb.ee_cfg_sts, entry_size, tlv_size);
+
+    if (tlv_size > max_tlv)
+    {
+        /* exceeds routing table size - report ERROR */
+        status  = NFA_STATUS_BUFFER_FULL;
+    }
+
+    else if (more == FALSE)
+    {
+        /* last entry. update routing table now */
+        if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED_ROUTING)
+        {
+            if (tlv_size)
+            {
+                nfa_ee_cb.ee_cfg_sts       |= NFA_EE_STS_PREV_ROUTING;
+            }
+            else
+            {
+                nfa_ee_cb.ee_cfg_sts       &= ~NFA_EE_STS_PREV_ROUTING;
+            }
+            NFC_SetRouting(more, p_cb->nfcee_id, num_tlv, tlv_size, ps + 1);
+        }
+        else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_PREV_ROUTING)
+        {
+            if (tlv_size == 0)
+            {
+                nfa_ee_cb.ee_cfg_sts       &= ~NFA_EE_STS_PREV_ROUTING;
+                /* indicated routing is configured to NFCC */
+                nfa_ee_cb.ee_cfg_sts       |= NFA_EE_STS_CHANGED_ROUTING;
+                NFC_SetRouting(more, p_cb->nfcee_id, 0, 0, ps + 1);
+            }
+        }
+    }
+    else
+    {
+        /* update the total num_tlv current offset */
+        *ps              = num_tlv;
+        *p_cur_offset   += entry_size;
+    }
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_need_recfg
+**
+** Description      Check if any API function to configure the routing table or
+**                  VS is called since last update
+**
+**                  The algorithm for the NFCEE configuration handling is as follows:
+**
+**                  Each NFCEE_ID/DH has its own control block - tNFA_EE_ECB
+**                  Each control block uses ecb_flags to keep track if an API
+**                  that changes routing/VS is invoked.
+**                  This ecb_flags is cleared at the end of nfa_ee_update_rout().
+**
+**                  nfa_ee_cb.ee_cfged is the bitmask of the control blocks with
+**                  routing/VS configuration and NFA_EE_CFGED_UPDATE_NOW.
+**                  nfa_ee_cb.ee_cfged is cleared and re-calculated at the end of
+**                  nfa_ee_update_rout().
+**
+**                  nfa_ee_cb.ee_cfg_sts is used to check is any status is changed
+**                  and the associated command is issued to NFCC.
+**                  nfa_ee_cb.ee_cfg_sts is AND with NFA_EE_STS_PREV at the end of
+**                  nfa_ee_update_rout() to clear the NFA_EE_STS_CHANGED bits
+**                  (except NFA_EE_STS_CHANGED_CANNED_VS is cleared in nfa_ee_vs_cback)
+**
+** Returns          TRUE if any configuration is changed
+**
+*******************************************************************************/
+static BOOLEAN nfa_ee_need_recfg(void)
+{
+    BOOLEAN needed = FALSE;
+    UINT32  xx;
+    tNFA_EE_ECB  *p_cb;
+    UINT8   mask;
+
+    NFA_TRACE_DEBUG2("nfa_ee_need_recfg() ee_cfged: 0x%02x ee_cfg_sts: 0x%02x", nfa_ee_cb.ee_cfged, nfa_ee_cb.ee_cfg_sts);
+    /* if no routing/vs is configured, do not need to send the info to NFCC */
+    if (nfa_ee_cb.ee_cfged || nfa_ee_cb.ee_cfg_sts)
+    {
+        if (nfa_ee_cb.ee_cfged & NFA_EE_CFGED_UPDATE_NOW)
+        {
+            needed = TRUE;
+        }
+        else if (nfa_ee_cb.ee_cfg_sts & NFA_EE_STS_CHANGED)
+        {
+            needed = TRUE;
+        }
+        else
+        {
+            p_cb = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+            mask = 1 << NFA_EE_CB_4_DH;
+            for (xx = 0; xx <= nfa_ee_cb.cur_ee; xx++)
+            {
+                NFA_TRACE_DEBUG3("%d: ecb_flags  : 0x%02x, mask: 0x%02x", xx, p_cb->ecb_flags  , mask);
+                if ((p_cb->ecb_flags  ) && (nfa_ee_cb.ee_cfged & mask))
+                {
+                    needed = TRUE;
+                    break;
+                }
+                p_cb = &nfa_ee_cb.ecb[xx];
+                mask = 1 << xx;
+            }
+        }
+    }
+
+    return needed;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_rout_timeout
+**
+** Description      Anytime VS or routing entries are changed,
+**                  a 1 second timer is started. This function is called when
+**                  the timer expires or NFA_EeUpdateNow() is called.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data)
+{
+    NFA_TRACE_DEBUG0("nfa_ee_rout_timeout()");
+    if (nfa_ee_need_recfg())
+    {
+        /* discovery is not started */
+        nfa_ee_update_rout();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_discv_timeout
+**
+** Description
+**
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data)
+{
+    NFC_NfceeDiscover(FALSE);
+    if (nfa_ee_cb.p_enable_cback)
+        (*nfa_ee_cb.p_enable_cback)(TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_lmrt_to_nfcc
+**
+** Description      This function would set the listen mode routing table
+**                  to NFCC.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data)
+{
+    int xx;
+    tNFA_EE_ECB          *p_cb;
+    UINT8   *p = NULL;
+    BOOLEAN more = TRUE;
+    UINT8   last_active = NFA_EE_INVALID;
+    int     max_len, len;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    int     cur_offset;
+
+    /* update routing table: DH and the activated NFCEEs */
+    p = (UINT8 *)GKI_getbuf(NFA_EE_ROUT_BUF_SIZE);
+    if (p == NULL)
+    {
+        NFA_TRACE_ERROR0 ("nfa_ee_lmrt_to_nfcc() no buffer to send routing info.");
+        nfa_ee_report_event( NULL, NFA_EE_NO_MEM_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
+        return;
+    }
+
+    /* find the last active NFCEE. */
+    p_cb = &nfa_ee_cb.ecb[nfa_ee_cb.cur_ee - 1];
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb--)
+    {
+        if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+        {
+            if (last_active == NFA_EE_INVALID)
+            {
+                last_active = p_cb->nfcee_id;
+                NFA_TRACE_DEBUG1 ("last_active: 0x%x", last_active);
+            }
+        }
+    }
+    if (last_active == NFA_EE_INVALID)
+    {
+        more = FALSE;
+    }
+
+    /* add the routing for DH first */
+    status  = NFA_STATUS_OK;
+    max_len = NFC_GetLmrtSize();
+    cur_offset  = 0;
+    /* use the first byte of the buffer (p) to keep the num_tlv */
+    *p          = 0;
+    status = nfa_ee_route_add_one_ecb(&nfa_ee_cb.ecb[NFA_EE_CB_4_DH], max_len, more, p, &cur_offset);
+
+    /* add only what is supported by NFCC. report overflow */
+    if (status == NFA_STATUS_OK)
+    {
+        /* add the routing for NFCEEs */
+        p_cb = &nfa_ee_cb.ecb[0];
+        for (xx = 0; (xx < nfa_ee_cb.cur_ee) && more; xx++, p_cb++)
+        {
+            len = 0;
+            if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+            {
+                NFA_TRACE_DEBUG2 ("nfcee_id:0x%x, last_active: 0x%x", p_cb->nfcee_id, last_active);
+                if (last_active == p_cb->nfcee_id)
+                    more = FALSE;
+                status = nfa_ee_route_add_one_ecb(p_cb, max_len, more, p, &cur_offset);
+                if (status != NFA_STATUS_OK)
+                {
+                    more    = FALSE;
+                }
+            }
+        }
+    }
+    if (status != NFA_STATUS_OK)
+    {
+        nfa_ee_report_event( NULL, NFA_EE_ROUT_ERR_EVT, (tNFA_EE_CBACK_DATA *)&status);
+    }
+    GKI_freebuf(p);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_update_rout
+**
+** Description      This function would set the VS and listen mode routing table
+**                  to NFCC.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_ee_update_rout(void)
+{
+    int xx;
+    tNFA_EE_ECB          *p_cb;
+    UINT8   mask;
+    BT_HDR  msg;
+
+    NFA_TRACE_DEBUG1 ("nfa_ee_update_rout ee_cfg_sts:0x%02x", nfa_ee_cb.ee_cfg_sts);
+
+    /* use action function to send routing and VS configuration to NFCC */
+    msg.event = NFA_EE_CFG_TO_NFCC_EVT;
+    nfa_ee_evt_hdlr (&msg);
+
+    /* all configuration is updated to NFCC, clear the status mask */
+    nfa_ee_cb.ee_cfg_sts   &= NFA_EE_STS_PREV;
+    nfa_ee_cb.ee_cfged  = 0;
+    p_cb                = &nfa_ee_cb.ecb[0];
+    for (xx = 0; xx < NFA_EE_NUM_ECBS; xx++, p_cb++)
+    {
+        p_cb->ecb_flags     = 0;
+        mask                = (1 << xx);
+        if (p_cb->tech_switch_on | p_cb->tech_switch_off | p_cb->tech_battery_off |
+            p_cb->proto_switch_on| p_cb->proto_switch_off| p_cb->proto_battery_off |
+            p_cb->aid_entries)
+        {
+            /* this entry has routing configuration. mark it configured */
+            nfa_ee_cb.ee_cfged  |= mask;
+        }
+    }
+    NFA_TRACE_DEBUG2 ("ee_cfg_sts:0x%02x ee_cfged:0x%02x", nfa_ee_cb.ee_cfg_sts, nfa_ee_cb.ee_cfged);
+}
+
+
diff --git a/src/nfa/ee/nfa_ee_api.c b/src/nfa/ee/nfa_ee_api.c
new file mode 100644
index 0000000..dceacec
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_api.c
@@ -0,0 +1,657 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface to NFCEE - API functions
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function         NFA_EeDiscover
+**
+** Description      This function retrieves the NFCEE information from NFCC.
+**                  The NFCEE information is reported in NFA_EE_DISCOVER_EVT.
+**
+**                  This function may be called when a system supports removable
+**                  NFCEEs,
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDiscover(tNFA_EE_CBACK *p_cback)
+{
+    tNFA_EE_API_DISCOVER *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+
+    NFA_TRACE_API0 ("NFA_EeDiscover()");
+
+    if (nfa_ee_cb.em_state != NFA_EE_EM_STATE_INIT_DONE)
+    {
+        NFA_TRACE_ERROR1 ("NFA_EeDiscover bad em state: %d", nfa_ee_cb.em_state);
+        status = NFA_STATUS_FAILED;
+    }
+    else if ((nfa_ee_cb.p_ee_disc_cback != NULL) || (p_cback == NULL))
+    {
+        NFA_TRACE_ERROR0 ("NFA_EeDiscover() in progress or NULL callback function");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_DISCOVER *) GKI_getbuf (sizeof(tNFA_EE_API_DISCOVER))) != NULL)
+    {
+        p_msg->hdr.event    = NFA_EE_API_DISCOVER_EVT;
+        p_msg->p_cback      = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeGetInfo
+**
+** Description      This function retrieves the NFCEE information from NFA.
+**                  The actual number of NFCEE is returned in p_num_nfcee
+**                  and NFCEE information is returned in p_info
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeGetInfo(UINT8        *p_num_nfcee,
+                          tNFA_EE_INFO *p_info)
+{
+    int   xx, ret = nfa_ee_cb.cur_ee;
+    tNFA_EE_ECB  *p_cb = nfa_ee_cb.ecb;
+    UINT8   max_ret;
+    UINT8   num_ret  = 0;
+
+    NFA_TRACE_DEBUG2 ("NFA_EeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee);
+    /* validate parameters */
+    if (p_info == NULL || p_num_nfcee == NULL)
+    {
+        NFA_TRACE_ERROR0 ("NFA_EeGetInfo bad parameter");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+    max_ret         = *p_num_nfcee;
+    *p_num_nfcee = 0;
+    if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT)
+    {
+        NFA_TRACE_ERROR1 ("NFA_EeGetInfo bad em state: %d", nfa_ee_cb.em_state);
+        return (NFA_STATUS_FAILED);
+    }
+
+    /* compose output */
+    for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++)
+    {
+        NFA_TRACE_DEBUG4 ("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x", xx, max_ret, num_ret, p_cb->ee_status);
+        if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) || (p_cb->ee_status == NFA_EE_STATUS_REMOVED))
+        {
+            continue;
+        }
+        p_info->ee_handle       = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id;
+        p_info->ee_status       = p_cb->ee_status;
+        p_info->num_interface   = p_cb->num_interface;
+        p_info->num_tlvs        = p_cb->num_tlvs;
+        memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface);
+        memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV));
+        p_info++;
+        num_ret++;
+    }
+    NFA_TRACE_DEBUG1 ("num_ret:%d", num_ret);
+    *p_num_nfcee = num_ret;
+    return (NFA_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeRegister
+**
+** Description      This function registers a callback function to receive the
+**                  events from NFA-EE module.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeRegister(tNFA_EE_CBACK *p_cback)
+{
+    tNFA_EE_API_REGISTER *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+
+    NFA_TRACE_API0 ("NFA_EeRegister()");
+
+    if (p_cback == NULL)
+    {
+        NFA_TRACE_ERROR0 ("NFA_EeRegister(): with NULL callback function");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_REGISTER *) GKI_getbuf (sizeof(tNFA_EE_API_REGISTER))) != NULL)
+    {
+        p_msg->hdr.event    = NFA_EE_API_REGISTER_EVT;
+        p_msg->p_cback      = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeDeregister
+**
+** Description      This function de-registers the callback function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDeregister(tNFA_EE_CBACK *p_cback)
+{
+    tNFA_EE_API_DEREGISTER *p_msg;
+    tNFA_STATUS status = NFA_STATUS_INVALID_PARAM;
+    int         index  = NFA_EE_MAX_CBACKS;
+    int         xx;
+
+    for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+    {
+        if (nfa_ee_cb.p_ee_cback[xx] == p_cback)
+        {
+            index   = xx;
+            status  = NFA_STATUS_FAILED;
+            break;
+        }
+    }
+
+    NFA_TRACE_API2 ("NFA_EeDeregister() %d, status:%d", index, status);
+    if ((status != NFA_STATUS_INVALID_PARAM) &&
+        (p_msg = (tNFA_EE_API_DEREGISTER *) GKI_getbuf (sizeof(tNFA_EE_API_DEREGISTER))) != NULL)
+    {
+        p_msg->hdr.event = NFA_EE_API_DEREGISTER_EVT;
+        p_msg->index     = index;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeModeSet
+**
+** Description      This function is called to activate (mode = NFA_EE_MD_ACTIVATE)
+**                  or deactivate (mode = NFA_EE_MD_DEACTIVATE) the NFCEE
+**                  identified by the given ee_handle. The result of this
+**                  operation is reported with the NFA_EE_MODE_SET_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeModeSet(tNFA_HANDLE    ee_handle,
+                          tNFA_EE_MD     mode)
+{
+    tNFA_EE_API_MODE_SET *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    tNFA_EE_ECB *p_cb, *p_found = NULL;
+    UINT32  xx;
+    UINT8   nfcee_id = (ee_handle & 0xFF);
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if (nfcee_id == p_cb->nfcee_id)
+        {
+            p_found = p_cb;
+            break;
+        }
+    }
+    NFA_TRACE_API2 ("NFA_EeModeSet(): handle:<0x%x>, mode:0x%02X", ee_handle, mode);
+
+    if (p_found == NULL)
+    {
+        NFA_TRACE_ERROR1 ("NFA_EeModeSet() invalid NFCEE:0x%04x", ee_handle);
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_MODE_SET *) GKI_getbuf (sizeof(tNFA_EE_API_MODE_SET))) != NULL)
+    {
+        p_msg->hdr.event        = NFA_EE_API_MODE_SET_EVT;
+        p_msg->nfcee_id         = nfcee_id;
+        p_msg->mode             = mode;
+        p_msg->p_cb             = p_found;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultTechRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on RF technology in the listen mode
+**                  routing table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSetDefaultTechRouting(tNFA_HANDLE          ee_handle,
+                                        tNFA_TECHNOLOGY_MASK technologies_switch_on,
+                                        tNFA_TECHNOLOGY_MASK technologies_switch_off,
+                                        tNFA_TECHNOLOGY_MASK technologies_battery_off)
+{
+    tNFA_EE_API_SET_TECH_CFG *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT8       nfcee_id = (UINT8)(ee_handle & 0xFF);
+    tNFA_EE_ECB *p_cb;
+
+    NFA_TRACE_API4 ("NFA_EeSetDefaultTechRouting(): handle:<0x%x>technology_mask:<0x%x>/<0x%x>/<0x%x>",
+        ee_handle, technologies_switch_on, technologies_switch_off, technologies_battery_off);
+    p_cb = nfa_ee_find_ecb (nfcee_id);
+
+    if (p_cb == NULL)
+    {
+        NFA_TRACE_ERROR0 ("Bad ee_handle");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_SET_TECH_CFG *) GKI_getbuf (sizeof(tNFA_EE_API_SET_TECH_CFG))) != NULL)
+    {
+        p_msg->hdr.event                = NFA_EE_API_SET_TECH_CFG_EVT;
+        p_msg->nfcee_id                 = nfcee_id;
+        p_msg->p_cb                     = p_cb;
+        p_msg->technologies_switch_on   = technologies_switch_on;
+        p_msg->technologies_switch_off  = technologies_switch_off;
+        p_msg->technologies_battery_off = technologies_battery_off;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultProtoRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on Protocol in the listen mode routing
+**                  table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_PROTO_CFG_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSetDefaultProtoRouting(tNFA_HANDLE         ee_handle,
+                                         tNFA_PROTOCOL_MASK  protocols_switch_on,
+                                         tNFA_PROTOCOL_MASK  protocols_switch_off,
+                                         tNFA_PROTOCOL_MASK  protocols_battery_off)
+{
+    tNFA_EE_API_SET_PROTO_CFG *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT8       nfcee_id = (UINT8)(ee_handle & 0xFF);
+    tNFA_EE_ECB *p_cb;
+
+    NFA_TRACE_API4 ("NFA_EeSetDefaultProtoRouting(): handle:<0x%x>protocol_mask:<0x%x>/<0x%x>/<0x%x>",
+        ee_handle, protocols_switch_on, protocols_switch_off, protocols_battery_off);
+    p_cb = nfa_ee_find_ecb (nfcee_id);
+
+    if (p_cb == NULL)
+    {
+        NFA_TRACE_ERROR0 ("Bad ee_handle");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_SET_PROTO_CFG *) GKI_getbuf (sizeof(tNFA_EE_API_SET_PROTO_CFG))) != NULL)
+    {
+        p_msg->hdr.event                = NFA_EE_API_SET_PROTO_CFG_EVT;
+        p_msg->nfcee_id                 = nfcee_id;
+        p_msg->p_cb                     = p_cb;
+        p_msg->protocols_switch_on      = protocols_switch_on;
+        p_msg->protocols_switch_off     = protocols_switch_off;
+        p_msg->protocols_battery_off    = protocols_battery_off;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeAddAidRouting
+**
+** Description      This function is called to add an AID entry in the
+**                  listen mode routing table in NFCC. The status of this
+**                  operation is reported as the NFA_EE_ADD_AID_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeAddAidRouting(tNFA_HANDLE          ee_handle,
+                                UINT8                aid_len,
+                                UINT8               *p_aid,
+                                tNFA_EE_PWR_STATE    power_state)
+{
+    tNFA_EE_API_ADD_AID *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT16 size = sizeof(tNFA_EE_API_ADD_AID) + aid_len;
+    UINT8       nfcee_id = (UINT8)(ee_handle & 0xFF);
+    tNFA_EE_ECB *p_cb;
+
+    NFA_TRACE_API1 ("NFA_EeAddAidRouting(): handle:<0x%x>", ee_handle);
+    p_cb = nfa_ee_find_ecb (nfcee_id);
+
+    /* validate parameters - make sure the AID is in valid length range */
+    if ((p_cb == NULL) || (aid_len == 0) || (p_aid == NULL) || (aid_len < NFA_MIN_AID_LEN) || (aid_len > NFA_MAX_AID_LEN))
+    {
+        NFA_TRACE_ERROR1 ("Bad ee_handle or AID (len=%d)", aid_len);
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_ADD_AID *) GKI_getbuf (size)) != NULL)
+    {
+        NFA_TRACE_DEBUG2 ("aid:<%02x%02x>", p_aid[0], p_aid[1]);
+        p_msg->hdr.event        = NFA_EE_API_ADD_AID_EVT;
+        p_msg->nfcee_id         = nfcee_id;
+        p_msg->p_cb             = p_cb;
+        p_msg->aid_len          = aid_len;
+        p_msg->power_state      = power_state;
+        p_msg->p_aid            = (UINT8 *)(p_msg + 1);
+        memcpy(p_msg->p_aid, p_aid, aid_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_EeRemoveAidRouting
+**
+** Description      This function is called to remove the given AID entry from the
+**                  listen mode routing table. If the entry configures VS,
+**                  it is also removed. The status of this operation is reported
+**                  as the NFA_EE_REMOVE_AID_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeRemoveAidRouting(UINT8     aid_len,
+                                   UINT8    *p_aid)
+{
+    tNFA_EE_API_REMOVE_AID *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT16 size = sizeof(tNFA_EE_API_REMOVE_AID) + aid_len;
+
+    NFA_TRACE_API0 ("NFA_EeRemoveAidRouting()");
+    if ((aid_len == 0) || (p_aid == NULL) || (aid_len > NFA_MAX_AID_LEN))
+    {
+        NFA_TRACE_ERROR0 ("Bad AID");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_REMOVE_AID *) GKI_getbuf (size)) != NULL)
+    {
+        p_msg->hdr.event        = NFA_EE_API_REMOVE_AID_EVT;
+        p_msg->aid_len          = aid_len;
+        p_msg->p_aid            = (UINT8 *)(p_msg + 1);
+        memcpy(p_msg->p_aid, p_aid, aid_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeUpdateNow
+**
+** Description      This function is called to send the current listen mode
+**                  routing table and VS configuration to the NFCC (without waiting
+**                  for NFA_EE_ROUT_TIMEOUT_VAL).
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeUpdateNow(void)
+{
+    BT_HDR *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+
+    NFA_TRACE_API0 ("NFA_EeUpdateNow()");
+    if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
+    {
+        p_msg->event    = NFA_EE_API_UPDATE_NOW_EVT;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_EeConnect
+**
+** Description      Open connection to an NFCEE attached to the NFCC
+**
+**                  The status of this operation is
+**                  reported with the NFA_EE_CONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeConnect(tNFA_HANDLE    ee_handle,
+                          UINT8          ee_interface,
+                          tNFA_EE_CBACK *p_cback)
+{
+    tNFA_EE_API_CONNECT *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT8       nfcee_id = (UINT8)(ee_handle & 0xFF);
+    tNFA_EE_ECB *p_cb;
+
+    NFA_TRACE_API2 ("NFA_EeConnect(): handle:<0x%x> ee_interface:0x%x", ee_handle, ee_interface);
+    p_cb = nfa_ee_find_ecb (nfcee_id);
+
+    if ((p_cb == NULL) || (p_cback == NULL))
+    {
+        NFA_TRACE_ERROR0 ("Bad ee_handle or NULL callback function");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_CONNECT *) GKI_getbuf (sizeof(tNFA_EE_API_CONNECT))) != NULL)
+    {
+        p_msg->hdr.event        = NFA_EE_API_CONNECT_EVT;
+        p_msg->nfcee_id         = nfcee_id;
+        p_msg->p_cb             = p_cb;
+        p_msg->ee_interface     = ee_interface;
+        p_msg->p_cback          = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeSendData
+**
+** Description      Send data to the given NFCEE.
+**                  This function shall be called after NFA_EE_CONNECT_EVT is reported
+**                  and before NFA_EeDisconnect is called on the given ee_handle.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeSendData (tNFA_HANDLE  ee_handle,
+                            UINT16       data_len,
+                            UINT8       *p_data)
+{
+    tNFA_EE_API_SEND_DATA *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT8       nfcee_id = (UINT8)(ee_handle & 0xFF);
+    tNFA_EE_ECB *p_cb;
+
+    NFA_TRACE_API1 ("NFA_EeSendData(): handle:<0x%x>", ee_handle);
+
+    p_cb = nfa_ee_find_ecb (nfcee_id);
+
+    if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN) || (p_data == NULL))
+    {
+        NFA_TRACE_ERROR0 ("Bad ee_handle or NULL data");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_SEND_DATA *) GKI_getbuf ((UINT16)(sizeof(tNFA_EE_API_SEND_DATA) + data_len))) != NULL)
+    {
+        p_msg->hdr.event        = NFA_EE_API_SEND_DATA_EVT;
+        p_msg->nfcee_id         = nfcee_id;
+        p_msg->p_cb             = p_cb;
+        p_msg->data_len         = data_len;
+        p_msg->p_data           = (UINT8 *)(p_msg + 1);
+        memcpy(p_msg->p_data, p_data, data_len);
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFA_EeDisconnect
+**
+** Description      Disconnect (if a connection is currently open) from an
+**                  NFCEE interface. The result of this operation is reported
+**                  with the NFA_EE_DISCONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+tNFA_STATUS NFA_EeDisconnect(tNFA_HANDLE ee_handle)
+{
+    tNFA_EE_API_DISCONNECT *p_msg;
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+    UINT8       nfcee_id = (UINT8)(ee_handle & 0xFF);
+    tNFA_EE_ECB *p_cb;
+
+    NFA_TRACE_API1 ("NFA_EeDisconnect(): handle:<0x%x>", ee_handle);
+    p_cb = nfa_ee_find_ecb (nfcee_id);
+
+    if ((p_cb == NULL) || (p_cb->conn_st != NFA_EE_CONN_ST_CONN))
+    {
+        NFA_TRACE_ERROR0 ("NFA_EeDisconnect() Bad ee_handle");
+        status = NFA_STATUS_INVALID_PARAM;
+    }
+    else if ((p_msg = (tNFA_EE_API_DISCONNECT *) GKI_getbuf (sizeof(tNFA_EE_API_DISCONNECT))) != NULL)
+    {
+        p_msg->hdr.event        = NFA_EE_API_DISCONNECT_EVT;
+        p_msg->nfcee_id         = nfcee_id;
+        p_msg->p_cb             = p_cb;
+
+        nfa_sys_sendmsg (p_msg);
+
+        status = NFA_STATUS_OK;
+    }
+
+    return status;
+}
diff --git a/src/nfa/ee/nfa_ee_main.c b/src/nfa/ee/nfa_ee_main.c
new file mode 100644
index 0000000..6b0c289
--- /dev/null
+++ b/src/nfa/ee/nfa_ee_main.c
@@ -0,0 +1,648 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA EE.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_ee_int.h"
+
+extern void nfa_ee_vs_cback (tNFC_VS_EVT event, BT_HDR *p_data);
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_EE_CB nfa_ee_cb;
+#endif
+
+#ifndef NFA_EE_DISCV_TIMEOUT_VAL
+#define NFA_EE_DISCV_TIMEOUT_VAL    2000
+#endif
+
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_ee_sys_reg =
+{
+    nfa_ee_sys_enable,
+    nfa_ee_evt_hdlr,
+    nfa_ee_sys_disable,
+    nfa_ee_proc_nfcc_power_mode
+};
+
+
+#define NFA_EE_NUM_ACTIONS  (NFA_EE_MAX_EVT & 0x00ff)
+
+
+const tNFA_EE_SM_ACT nfa_ee_actions[] =
+{
+    /* NFA-EE action function/ internal events */
+    nfa_ee_api_discover     ,   /* NFA_EE_API_DISCOVER_EVT      */
+    nfa_ee_api_register     ,   /* NFA_EE_API_REGISTER_EVT      */
+    nfa_ee_api_deregister   ,   /* NFA_EE_API_DEREGISTER_EVT    */
+    nfa_ee_api_mode_set     ,   /* NFA_EE_API_MODE_SET_EVT      */
+    nfa_ee_api_set_tech_cfg ,   /* NFA_EE_API_SET_TECH_CFG_EVT  */
+    nfa_ee_api_set_proto_cfg,   /* NFA_EE_API_SET_PROTO_CFG_EVT */
+    nfa_ee_api_add_aid      ,   /* NFA_EE_API_ADD_AID_EVT       */
+    nfa_ee_api_remove_aid   ,   /* NFA_EE_API_REMOVE_AID_EVT    */
+    nfa_ee_api_update_now   ,   /* NFA_EE_API_UPDATE_NOW_EVT    */
+    nfa_ee_api_connect      ,   /* NFA_EE_API_CONNECT_EVT       */
+    nfa_ee_api_send_data    ,   /* NFA_EE_API_SEND_DATA_EVT     */
+    nfa_ee_api_disconnect   ,   /* NFA_EE_API_DISCONNECT_EVT    */
+    nfa_ee_nci_disc_rsp     ,   /* NFA_EE_NCI_DISC_RSP_EVT      */
+    nfa_ee_nci_disc_ntf     ,   /* NFA_EE_NCI_DISC_NTF_EVT      */
+    nfa_ee_nci_mode_set_rsp ,   /* NFA_EE_NCI_MODE_SET_RSP_EVT  */
+    nfa_ee_nci_conn         ,   /* NFA_EE_NCI_CONN_EVT          */
+    nfa_ee_nci_conn         ,   /* NFA_EE_NCI_DATA_EVT          */
+    nfa_ee_nci_action_ntf   ,   /* NFA_EE_NCI_ACTION_NTF_EVT    */
+    nfa_ee_nci_disc_req_ntf ,   /* NFA_EE_NCI_DISC_REQ_NTF_EVT  */
+    nfa_ee_rout_timeout     ,   /* NFA_EE_ROUT_TIMEOUT_EVT      */
+    nfa_ee_discv_timeout    ,   /* NFA_EE_DISCV_TIMEOUT_EVT     */
+    nfa_ee_lmrt_to_nfcc         /* NFA_EE_CFG_TO_NFCC_EVT       */
+};
+
+
+/*******************************************************************************
+**
+** Function         nfa_ee_init
+**
+** Description      Initialize NFA EE control block
+**                  register to NFA SYS
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_init (void)
+{
+    int xx;
+
+    NFA_TRACE_DEBUG0 ("nfa_ee_init ()");
+
+    /* initialize control block */
+    memset (&nfa_ee_cb, 0, sizeof (tNFA_EE_CB));
+    for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++)
+    {
+        nfa_ee_cb.ecb[xx].nfcee_id       = NFA_EE_INVALID;
+        nfa_ee_cb.ecb[xx].ee_status      = NFC_NFCEE_STATUS_INACTIVE;
+    }
+
+    nfa_ee_cb.ecb[NFA_EE_CB_4_DH].ee_status       = NFC_NFCEE_STATUS_ACTIVE;
+    nfa_ee_cb.ecb[NFA_EE_CB_4_DH].nfcee_id        = NFC_DH_ID;
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register (NFA_ID_EE,  &nfa_ee_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_sys_enable
+**
+** Description      Enable NFA EE
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_sys_enable (void)
+{
+    /* collect NFCEE information */
+    NFC_NfceeDiscover (TRUE);
+    nfa_sys_start_timer (&nfa_ee_cb.discv_timer, NFA_EE_DISCV_TIMEOUT_EVT, NFA_EE_DISCV_TIMEOUT_VAL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_restore_one_ecb
+**
+** Description      activate the NFCEE and restore the routing when
+**                  changing power state from low power mode to full power mode
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_restore_one_ecb (tNFA_EE_ECB *p_cb)
+{
+    UINT8   mask;
+    tNFC_NFCEE_MODE_SET_REVT    rsp;
+    tNFA_EE_NCI_MODE_SET        ee_msg;
+
+    NFA_TRACE_DEBUG4 ("nfa_ee_restore_one_ecb () nfcee_id:0x%x, ecb_flags:0x%x ee_status:0x%x ee_old_status: 0x%x", p_cb->nfcee_id, p_cb->ecb_flags, p_cb->ee_status, p_cb->ee_old_status);
+    if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_status & NFA_EE_STATUS_RESTORING) == 0 && (p_cb->ee_old_status & NFA_EE_STATUS_RESTORING) != 0)
+    {
+        p_cb->ee_old_status &= ~NFA_EE_STATUS_RESTORING;
+        mask = nfa_ee_ecb_to_mask(p_cb);
+        if (p_cb->ee_status != p_cb->ee_old_status)
+        {
+            p_cb->ecb_flags   |= NFA_EE_ECB_FLAGS_RESTORE;
+            if (p_cb->ee_old_status == NFC_NFCEE_STATUS_ACTIVE)
+            {
+                NFC_NfceeModeSet (p_cb->nfcee_id, NFC_MODE_ACTIVATE);
+
+                if (nfa_ee_cb.ee_cfged & mask)
+                {
+                    /* if any routing is configured on this NFCEE. need to mark this NFCEE as changed
+                     * to cause the configuration to be sent to NFCC again */
+                    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
+                    p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+                }
+            }
+            else
+            {
+                NFC_NfceeModeSet (p_cb->nfcee_id, NFC_MODE_DEACTIVATE);
+            }
+        }
+        else if (p_cb->ee_status == NFC_NFCEE_STATUS_ACTIVE)
+        {
+            /* the initial NFCEE status after start up is the same as the current status and it's active:
+             * process the same as the host gets activate rsp */
+            p_cb->ecb_flags   |= NFA_EE_ECB_FLAGS_RESTORE;
+            if (nfa_ee_cb.ee_cfged & mask)
+            {
+                /* if any routing is configured on this NFCEE. need to mark this NFCEE as changed
+                 * to cause the configuration to be sent to NFCC again */
+                p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_ROUTING;
+                p_cb->ecb_flags |= NFA_EE_ECB_FLAGS_VS;
+            }
+            rsp.mode        = NFA_EE_MD_ACTIVATE;
+            rsp.nfcee_id    = p_cb->nfcee_id;
+            rsp.status      = NFA_STATUS_OK;
+            ee_msg.p_data   = &rsp;
+            nfa_ee_nci_mode_set_rsp ((tNFA_EE_MSG *) &ee_msg);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_proc_nfcc_power_mode
+**
+** Description      Restore NFA EE sub-module
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+    UINT32          xx;
+    tNFA_EE_ECB     *p_cb;
+    BOOLEAN         proc_complete = TRUE;
+
+    NFA_TRACE_DEBUG1 ("nfa_ee_proc_nfcc_power_mode (): nfcc_power_mode=%d", nfcc_power_mode);
+    /* if NFCC power state is change to full power */
+    if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
+    {
+        p_cb = nfa_ee_cb.ecb;
+        for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++)
+        {
+            p_cb->ee_old_status = 0;
+            if (xx >= nfa_ee_cb.cur_ee)
+                p_cb->nfcee_id = NFA_EE_INVALID;
+
+            if ((p_cb->nfcee_id != NFA_EE_INVALID) && (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) && (p_cb->ee_status  != NFA_EE_STATUS_REMOVED))
+            {
+                proc_complete       = FALSE;
+                /* NFA_EE_STATUS_RESTORING bit makes sure the ee_status restore to ee_old_status
+                 * NFA_EE_STATUS_RESTORING bit is cleared in ee_status at NFCEE_DISCOVER NTF.
+                 * NFA_EE_STATUS_RESTORING bit is cleared in ee_old_status at restoring the activate/inactive status after NFCEE_DISCOVER NTF */
+                p_cb->ee_status    |= NFA_EE_STATUS_RESTORING;
+                p_cb->ee_old_status = p_cb->ee_status;
+                /* NFA_EE_FLAGS_RESTORE bit makes sure the routing/nci logical connection is restore to prior to entering low power mode */
+                p_cb->ecb_flags    |= NFA_EE_ECB_FLAGS_RESTORE;
+            }
+        }
+        nfa_ee_cb.em_state      = NFA_EE_EM_STATE_RESTORING;
+        if (nfa_sys_is_register (NFA_ID_HCI))
+        {
+            nfa_ee_cb.ee_flags   |= NFA_EE_FLAG_WAIT_HCI;
+            nfa_ee_cb.ee_flags   |= NFA_EE_FLAG_NOTIFY_HCI;
+        }
+        NFC_NfceeDiscover (TRUE);
+        nfa_sys_start_timer (&nfa_ee_cb.discv_timer, NFA_EE_DISCV_TIMEOUT_EVT, NFA_EE_DISCV_TIMEOUT_VAL);
+    }
+    else
+    {
+        nfa_sys_stop_timer (&nfa_ee_cb.timer);
+        nfa_sys_stop_timer (&nfa_ee_cb.discv_timer);
+        nfa_ee_cb.num_ee_expecting = 0;
+    }
+
+    if (proc_complete)
+        nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_EE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_proc_hci_info_cback
+**
+** Description      HCI initialization complete from power off sleep mode
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_proc_hci_info_cback (void)
+{
+    UINT32          xx;
+    tNFA_EE_ECB     *p_cb;
+
+    NFA_TRACE_DEBUG0 ("nfa_ee_proc_hci_info_cback ()");
+    /* if NFCC power state is change to full power */
+    nfa_ee_cb.ee_flags   &= ~NFA_EE_FLAG_WAIT_HCI;
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++)
+    {
+        /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access"
+         * SHALL NOT contain any other additional Protocol
+         * i.e. check only first supported NFCEE interface is HCI access */
+        /* NFA_HCI module handles restoring configurations for HCI access */
+        if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS)
+        {
+            nfa_ee_restore_one_ecb (p_cb);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_proc_evt
+**
+** Description      Process NFCEE related events from NFC stack
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_proc_evt (tNFC_RESPONSE_EVT event, void *p_data)
+{
+    tNFA_EE_INT_EVT         int_event=0;
+    tNFA_EE_NCI_RESPONSE    cbk;
+    BT_HDR                  *p_hdr;
+
+    switch (event)
+    {
+    case NFC_NFCEE_DISCOVER_REVT:                /* 4  NFCEE Discover response */
+        int_event   = NFA_EE_NCI_DISC_RSP_EVT;
+        break;
+
+    case NFC_NFCEE_INFO_REVT:                    /* 5  NFCEE Discover Notification */
+        int_event    = NFA_EE_NCI_DISC_NTF_EVT;
+        break;
+
+    case NFC_NFCEE_MODE_SET_REVT:                /* 6  NFCEE Mode Set response */
+        int_event   = NFA_EE_NCI_MODE_SET_RSP_EVT;
+        break;
+
+    case NFC_EE_ACTION_REVT:
+        int_event   = NFA_EE_NCI_ACTION_NTF_EVT;
+        break;
+
+    case NFC_EE_DISCOVER_REQ_REVT:               /* 10 EE Discover Req notification */
+        int_event   = NFA_EE_NCI_DISC_REQ_NTF_EVT;
+        break;
+
+    }
+
+    NFA_TRACE_DEBUG2 ("nfa_ee_proc_evt: event=0x%02x int_event:0x%x", event, int_event);
+    if (int_event)
+    {
+        p_hdr           = (BT_HDR *) &cbk;
+        cbk.hdr.event   = int_event;
+        cbk.p_data      = p_data;
+
+        nfa_ee_evt_hdlr (p_hdr);
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_ecb_to_mask
+**
+** Description      Given a ecb, return the bit mask to be used in nfa_ee_cb.ee_cfged
+**
+** Returns          the bitmask for the given ecb.
+**
+*******************************************************************************/
+UINT8 nfa_ee_ecb_to_mask (tNFA_EE_ECB *p_cb)
+{
+    UINT8   mask;
+    UINT8   index;
+
+    index = (UINT8) (p_cb - nfa_ee_cb.ecb);
+    mask  = 1 << index;
+
+    return mask;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_ecb
+**
+** Description      Return the ecb associated with the given nfcee_id
+**
+** Returns          tNFA_EE_ECB
+**
+*******************************************************************************/
+tNFA_EE_ECB * nfa_ee_find_ecb (UINT8 nfcee_id)
+{
+    UINT32  xx;
+    tNFA_EE_ECB *p_ret = NULL, *p_cb;
+    NFA_TRACE_DEBUG0 ("nfa_ee_find_ecb ()");
+
+    if (nfcee_id == NFC_DH_ID)
+    {
+        p_ret = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH];
+    }
+    else
+    {
+        p_cb = nfa_ee_cb.ecb;
+        for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++)
+        {
+            if (nfcee_id == p_cb->nfcee_id)
+            {
+                p_ret = p_cb;
+                break;
+            }
+        }
+    }
+
+    return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_find_ecb_by_conn_id
+**
+** Description      Return the ecb associated with the given connection id
+**
+** Returns          tNFA_EE_ECB
+**
+*******************************************************************************/
+tNFA_EE_ECB * nfa_ee_find_ecb_by_conn_id (UINT8 conn_id)
+{
+    UINT32  xx;
+    tNFA_EE_ECB *p_ret = NULL, *p_cb;
+    NFA_TRACE_DEBUG0 ("nfa_ee_find_ecb_by_conn_id ()");
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if (conn_id == p_cb->conn_id)
+        {
+            p_ret = p_cb;
+            break;
+        }
+    }
+
+    return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_sys_disable
+**
+** Description      Deregister NFA EE from NFA SYS/DM
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_sys_disable (void)
+{
+    UINT32  xx;
+    tNFA_EE_ECB *p_cb;
+    tNFA_EE_MSG     msg;
+    NFA_TRACE_DEBUG0 ("nfa_ee_sys_disable ()");
+
+    nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED;
+    /* report NFA_EE_DEREGISTER_EVT to all registered to EE */
+    for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++)
+    {
+        if (nfa_ee_cb.p_ee_cback[xx])
+        {
+            msg.deregister.index     = xx;
+            nfa_ee_api_deregister (&msg);
+        }
+    }
+
+    p_cb = nfa_ee_cb.ecb;
+    for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++)
+    {
+        if (p_cb->conn_st == NFA_EE_CONN_ST_CONN)
+        {
+            if (nfa_sys_is_graceful_disable ())
+            {
+                /* Disconnect NCI connection on graceful shutdown */
+                msg.disconnect.p_cb = p_cb;
+                nfa_ee_api_disconnect (&msg);
+                nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLING;
+            }
+            else
+            {
+                /* fake NFA_EE_DISCONNECT_EVT on ungraceful shutdown */
+                msg.conn.conn_id    = p_cb->conn_id;
+                msg.conn.event      = NFC_CONN_CLOSE_CEVT;
+                nfa_ee_nci_conn (&msg);
+            }
+        }
+    }
+    nfa_sys_stop_timer (&nfa_ee_cb.timer);
+    nfa_sys_stop_timer (&nfa_ee_cb.discv_timer);
+
+    /* If Application initiated NFCEE discovery, fake/report the event */
+    nfa_ee_cb.num_ee_expecting = 0;
+    nfa_ee_report_disc_done (FALSE);
+
+    /* deregister message handler on NFA SYS */
+    if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLED)
+        nfa_sys_deregister (NFA_ID_EE);
+
+}
+/*******************************************************************************
+**
+** Function         nfa_ee_reg_cback_enable_done
+**
+** Description      Allow a module to register to EE to be notified when NFA-EE
+**                  finishes enable process
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_ee_reg_cback_enable_done (tNFA_EE_ENABLE_DONE_CBACK *p_cback)
+{
+    nfa_ee_cb.p_enable_cback = p_cback;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_ee_sm_st_2_str
+**
+** Description      convert nfa-ee state to string
+**
+*******************************************************************************/
+static char *nfa_ee_sm_st_2_str (UINT8 state)
+{
+    switch (state)
+    {
+    case NFA_EE_EM_STATE_INIT:
+        return "INIT";
+
+    case NFA_EE_EM_STATE_INIT_DONE:
+        return "INIT_DONE";
+
+    case NFA_EE_EM_STATE_RESTORING:
+        return "RESTORING";
+
+    case NFA_EE_EM_STATE_DISABLING:
+        return "DISABLING";
+
+    case NFA_EE_EM_STATE_DISABLED:
+        return "DISABLED";
+
+    default:
+        return "Unknown";
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_ee_sm_evt_2_str
+**
+** Description      convert nfa-ee evt to string
+**
+*******************************************************************************/
+static char *nfa_ee_sm_evt_2_str (UINT16 event)
+{
+    switch (event)
+    {
+    case NFA_EE_API_DISCOVER_EVT:
+        return "API_DISCOVER";
+    case NFA_EE_API_REGISTER_EVT:
+        return "API_REGISTER";
+    case NFA_EE_API_DEREGISTER_EVT:
+        return "API_DEREGISTER";
+    case NFA_EE_API_MODE_SET_EVT:
+        return "API_MODE_SET";
+    case NFA_EE_API_SET_TECH_CFG_EVT:
+        return "API_SET_TECH_CFG";
+    case NFA_EE_API_SET_PROTO_CFG_EVT:
+        return "API_SET_PROTO_CFG";
+    case NFA_EE_API_ADD_AID_EVT:
+        return "API_ADD_AID";
+    case NFA_EE_API_REMOVE_AID_EVT:
+        return "API_REMOVE_AID";
+    case NFA_EE_API_UPDATE_NOW_EVT:
+        return "API_UPDATE_NOW";
+    case NFA_EE_API_CONNECT_EVT:
+        return "API_CONNECT";
+    case NFA_EE_API_SEND_DATA_EVT:
+        return "API_SEND_DATA";
+    case NFA_EE_API_DISCONNECT_EVT:
+        return "API_DISCONNECT";
+    case NFA_EE_NCI_DISC_RSP_EVT:
+        return "NCI_DISC_RSP";
+    case NFA_EE_NCI_DISC_NTF_EVT:
+        return "NCI_DISC_NTF";
+    case NFA_EE_NCI_MODE_SET_RSP_EVT:
+        return "NCI_MODE_SET";
+    case NFA_EE_NCI_CONN_EVT:
+        return "NCI_CONN";
+    case NFA_EE_NCI_DATA_EVT:
+        return "NCI_DATA";
+    case NFA_EE_NCI_ACTION_NTF_EVT:
+        return "NCI_ACTION";
+    case NFA_EE_NCI_DISC_REQ_NTF_EVT:
+        return "NCI_DISC_REQ";
+    case NFA_EE_ROUT_TIMEOUT_EVT:
+        return "ROUT_TIMEOUT";
+    case NFA_EE_DISCV_TIMEOUT_EVT:
+        return "NFA_EE_DISCV_TIMEOUT_EVT";
+    case NFA_EE_CFG_TO_NFCC_EVT:
+        return "CFG_TO_NFCC";
+    default:
+        return "Unknown";
+    }
+}
+#endif /* BT_TRACE_VERBOSE */
+
+/*******************************************************************************
+**
+** Function         nfa_ee_evt_hdlr
+**
+** Description      Processing event for NFA EE
+**
+**
+** Returns          TRUE if p_msg needs to be deallocated
+**
+*******************************************************************************/
+BOOLEAN nfa_ee_evt_hdlr (BT_HDR *p_msg)
+{
+    tNFA_EE_MSG *p_evt_data = (tNFA_EE_MSG *) p_msg;
+    UINT16  event = p_msg->event & 0x00ff;
+    BOOLEAN act = FALSE;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG4 ("nfa_ee_evt_hdlr (): Event %s(0x%02x), State: %s(%d)",
+        nfa_ee_sm_evt_2_str (p_evt_data->hdr.event), p_evt_data->hdr.event,
+        nfa_ee_sm_st_2_str (nfa_ee_cb.em_state), nfa_ee_cb.em_state);
+#else
+    NFA_TRACE_DEBUG2 ("nfa_ee_evt_hdlr (): Event 0x%02x, State: %d", p_evt_data->hdr.event, nfa_ee_cb.em_state);
+#endif
+
+    switch (nfa_ee_cb.em_state)
+    {
+    case NFA_EE_EM_STATE_INIT_DONE:
+    case NFA_EE_EM_STATE_RESTORING:
+        act = TRUE;
+        break;
+    case NFA_EE_EM_STATE_INIT:
+        if ((p_msg->event == NFA_EE_NCI_DISC_NTF_EVT) || (p_msg->event == NFA_EE_NCI_DISC_RSP_EVT))
+            act = TRUE;
+        break;
+    case NFA_EE_EM_STATE_DISABLING:
+        if (p_msg->event == NFA_EE_NCI_CONN_EVT)
+            act = TRUE;
+        break;
+    }
+    if (act)
+    {
+        if (event < NFA_EE_NUM_ACTIONS)
+        {
+            (*nfa_ee_actions[event]) (p_evt_data);
+        }
+    }
+    else
+    {
+        /* if the data event is not handled by action function, free the data packet */
+        if (p_msg->event == NFA_EE_NCI_DATA_EVT)
+            GKI_freebuf (p_evt_data->conn.p_data);
+    }
+
+    return TRUE;
+}
+
+
diff --git a/src/nfa/hci/nfa_hci_act.c b/src/nfa/hci/nfa_hci_act.c
new file mode 100644
index 0000000..f89061c
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_act.c
@@ -0,0 +1,2054 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions for the NFA HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "trace_api.h"
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+
+
+/* Static local functions       */
+static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_get_gate_pipe_list (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data);
+static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
+
+static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_generic_gate_cmd (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_generic_gate_rsp (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
+static void nfa_hci_handle_generic_gate_evt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
+
+
+/*******************************************************************************
+**
+** Function         nfa_hci_check_pending_api_requests
+**
+** Description      This function handles pending API requests
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_check_pending_api_requests (void)
+{
+    BT_HDR              *p_msg;
+    tNFA_HCI_EVENT_DATA *p_evt_data;
+    BOOLEAN             b_free;
+    UINT8               b_cmd_flag = 0;
+
+    /* If busy, or API queue is empty, then exit */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE)
+        ||((p_msg = (BT_HDR *) GKI_dequeue (&nfa_hci_cb.hci_host_reset_api_q)) == NULL) )
+        return;
+
+    /* Process API request */
+    p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
+
+    /* Save the application handle */
+    nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
+
+    b_free = TRUE;
+    switch (p_msg->event)
+    {
+    case NFA_HCI_API_CREATE_PIPE_EVT:
+        if (nfa_hci_api_create_pipe (p_evt_data) == FALSE)
+            b_free = FALSE;
+        break;
+
+    case NFA_HCI_API_GET_REGISTRY_EVT:
+        if (nfa_hci_api_get_reg_value (p_evt_data) == FALSE)
+            b_free = FALSE;
+        break;
+
+    case NFA_HCI_API_SET_REGISTRY_EVT:
+        if (nfa_hci_api_set_reg_value (p_evt_data) == FALSE)
+            b_free = FALSE;
+        break;
+
+    case NFA_HCI_API_SEND_CMD_EVT:
+        if (nfa_hci_api_send_cmd (p_evt_data) == FALSE)
+            b_free = FALSE;
+        break;
+    case NFA_HCI_API_SEND_EVENT_EVT:
+        if (nfa_hci_api_send_event (p_evt_data) == FALSE)
+            b_free = FALSE;
+        break;
+    }
+
+    if (b_free)
+        GKI_freebuf (p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_check_api_requests
+**
+** Description      This function handles API requests
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_check_api_requests (void)
+{
+    BT_HDR              *p_msg;
+    tNFA_HCI_EVENT_DATA *p_evt_data;
+
+    for ( ; ; )
+    {
+        /* If busy, or API queue is empty, then exit */
+        if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE)
+            ||((p_msg = (BT_HDR *) GKI_dequeue (&nfa_hci_cb.hci_api_q)) == NULL) )
+            break;
+
+        /* Process API request */
+        p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
+
+        /* Save the application handle */
+        nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
+
+        switch (p_msg->event)
+        {
+        case NFA_HCI_API_REGISTER_APP_EVT:
+            nfa_hci_api_register (p_evt_data);
+            break;
+
+        case NFA_HCI_API_DEREGISTER_APP_EVT:
+            nfa_hci_api_deregister (p_evt_data);
+            break;
+
+        case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
+            nfa_hci_api_get_gate_pipe_list (p_evt_data);
+            break;
+
+        case NFA_HCI_API_ALLOC_GATE_EVT:
+            nfa_hci_api_alloc_gate (p_evt_data);
+            break;
+
+        case NFA_HCI_API_DEALLOC_GATE_EVT:
+            nfa_hci_api_dealloc_gate (p_evt_data);
+            break;
+
+        case NFA_HCI_API_GET_HOST_LIST_EVT:
+            nfa_hci_api_get_host_list (p_evt_data);
+            break;
+
+        case NFA_HCI_API_GET_REGISTRY_EVT:
+            if (nfa_hci_api_get_reg_value (p_evt_data) == FALSE)
+                continue;
+            break;
+
+        case NFA_HCI_API_SET_REGISTRY_EVT:
+            if (nfa_hci_api_set_reg_value (p_evt_data) == FALSE)
+                continue;
+            break;
+
+        case NFA_HCI_API_CREATE_PIPE_EVT:
+           if (nfa_hci_api_create_pipe (p_evt_data) == FALSE)
+               continue;
+            break;
+
+        case NFA_HCI_API_OPEN_PIPE_EVT:
+            nfa_hci_api_open_pipe (p_evt_data);
+            break;
+
+        case NFA_HCI_API_CLOSE_PIPE_EVT:
+            nfa_hci_api_close_pipe (p_evt_data);
+            break;
+
+        case NFA_HCI_API_DELETE_PIPE_EVT:
+            nfa_hci_api_delete_pipe (p_evt_data);
+            break;
+
+        case NFA_HCI_API_SEND_CMD_EVT:
+            if (nfa_hci_api_send_cmd (p_evt_data) == FALSE)
+                continue;
+            break;
+
+        case NFA_HCI_API_SEND_RSP_EVT:
+            nfa_hci_api_send_rsp (p_evt_data);
+            break;
+
+        case NFA_HCI_API_SEND_EVENT_EVT:
+            if (nfa_hci_api_send_event (p_evt_data) == FALSE)
+                continue;
+            break;
+
+        case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
+            nfa_hci_api_add_static_pipe (p_evt_data);
+            break;
+
+        default:
+            NFA_TRACE_ERROR1 ("nfa_hci_check_api_requests ()  Unknown event: 0x%04x", p_msg->event);
+            break;
+        }
+
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_register
+**
+** Description      action function to register the events for the given AID
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    char                *p_app_name  = p_evt_data->app_info.app_name;
+    tNFA_HCI_CBACK      *p_cback     = p_evt_data->app_info.p_cback;
+    int                 xx,yy;
+    UINT8               num_gates    = 0,num_pipes = 0;
+    tNFA_HCI_DYN_GATE   *pg = nfa_hci_cb.cfg.dyn_gates;
+
+    /* First, see if the application was already registered */
+    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+    {
+        if (  (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+            && !strncmp (p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], strlen (p_app_name)) )
+        {
+            NFA_TRACE_EVENT2 ("nfa_hci_api_register (%s)  Reusing: %u", p_app_name, xx);
+            break;
+        }
+    }
+
+    if (xx != NFA_HCI_MAX_APP_CB)
+    {
+        nfa_hci_cb.app_in_use = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+        /* The app was registered, find the number of gates and pipes associated to the app */
+
+        for ( yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++)
+        {
+            if (pg->gate_owner == nfa_hci_cb.app_in_use)
+            {
+                num_gates++;
+                num_pipes += nfa_hciu_count_pipes_on_gate (pg);
+            }
+        }
+    }
+    else
+    {
+        /* Not registered, look for a free entry */
+        for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+        {
+            if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0)
+            {
+                memset (&nfa_hci_cb.cfg.reg_app_names[xx][0], 0, sizeof (nfa_hci_cb.cfg.reg_app_names[xx]));
+                BCM_STRNCPY_S (&nfa_hci_cb.cfg.reg_app_names[xx][0], sizeof (nfa_hci_cb.cfg.reg_app_names[xx]), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+                nfa_hci_cb.nv_write_needed = TRUE;
+                NFA_TRACE_EVENT2 ("nfa_hci_api_register (%s)  Allocated: %u", p_app_name, xx);
+                break;
+            }
+        }
+
+        if (xx == NFA_HCI_MAX_APP_CB)
+        {
+            NFA_TRACE_ERROR1 ("nfa_hci_api_register (%s)  NO ENTRIES", p_app_name);
+
+            evt_data.hci_register.status = NFA_STATUS_FAILED;
+            p_evt_data->app_info.p_cback (NFA_HCI_REGISTER_EVT, &evt_data);
+            return;
+        }
+    }
+
+    evt_data.hci_register.num_pipes = num_pipes;
+    evt_data.hci_register.num_gates = num_gates;
+    nfa_hci_cb.p_app_cback[xx]      = p_cback;
+
+    nfa_hci_cb.cfg.b_send_conn_evts[xx]  = p_evt_data->app_info.b_send_conn_evts;
+
+    evt_data.hci_register.hci_handle = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+
+    evt_data.hci_register.status = NFA_STATUS_OK;
+
+    /* notify NFA_HCI_REGISTER_EVT to the application */
+    p_evt_data->app_info.p_cback (NFA_HCI_REGISTER_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_deregister
+**
+** Description      action function to deregister the given application
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_api_deregister (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HCI_CBACK      *p_cback = NULL;
+    int                 xx;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    tNFA_HCI_DYN_GATE   *p_gate;
+
+    /* If needed, find the application registration handle */
+    if (p_evt_data != NULL)
+    {
+        for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+        {
+            if (  (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+                && !strncmp (p_evt_data->app_info.app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], strlen (p_evt_data->app_info.app_name)) )
+            {
+                NFA_TRACE_EVENT2 ("nfa_hci_api_deregister (%s) inx: %u", p_evt_data->app_info.app_name, xx);
+                break;
+            }
+        }
+
+        if (xx == NFA_HCI_MAX_APP_CB)
+        {
+            NFA_TRACE_WARNING1 ("nfa_hci_api_deregister () Unknown app: %s", p_evt_data->app_info.app_name);
+            return;
+        }
+        nfa_hci_cb.app_in_use = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+        p_cback               = nfa_hci_cb.p_app_cback[xx];
+    }
+    else
+    {
+        nfa_sys_stop_timer (&nfa_hci_cb.timer);
+        /* We are recursing through deleting all the app's pipes and gates */
+        p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
+    }
+
+    /* See if any pipe is owned by this app */
+    if ((p_pipe = nfa_hciu_find_pipe_by_owner (nfa_hci_cb.app_in_use)) == NULL)
+    {
+        /* No pipes, release all gates owned by this app */
+        while ((p_gate = nfa_hciu_find_gate_by_owner (nfa_hci_cb.app_in_use)) != NULL)
+            nfa_hciu_release_gate (p_gate->gate_id);
+
+        memset (&nfa_hci_cb.cfg.reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0], 0, NFA_MAX_HCI_APP_NAME_LEN + 1);
+        nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK]  = NULL;
+
+        nfa_hci_cb.nv_write_needed = TRUE;
+
+        evt_data.hci_deregister.status = NFC_STATUS_OK;
+
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+            nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+        /* notify NFA_HCI_DEREGISTER_EVT to the application */
+        if (p_cback)
+            p_cback (NFA_HCI_DEREGISTER_EVT, &evt_data);
+    }
+    else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner (nfa_hci_cb.app_in_use)) == NULL)
+    {
+        /* No pipes, release all gates owned by this app */
+        while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner (nfa_hci_cb.app_in_use)) != NULL)
+            nfa_hciu_release_gate (p_gate->gate_id);
+
+        nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK]  = NULL;
+
+        nfa_hci_cb.nv_write_needed = TRUE;
+
+        evt_data.hci_deregister.status = NFC_STATUS_FAILED;
+
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+            nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+        /* notify NFA_HCI_DEREGISTER_EVT to the application */
+        if (p_cback)
+            p_cback (NFA_HCI_DEREGISTER_EVT, &evt_data);
+    }
+    else
+    {
+        /* Delete all active pipes created for the application before de registering
+        **/
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;
+
+        nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_gate_pipe_list
+**
+** Description      action function to get application allocated gates and
+**                  application created pipes
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_get_gate_pipe_list (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    int                 xx,yy;
+    tNFA_HCI_DYN_GATE   *pg = nfa_hci_cb.cfg.dyn_gates;
+    tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
+
+    evt_data.gates_pipes.num_gates = 0;
+    evt_data.gates_pipes.num_pipes = 0;
+
+    for ( xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+    {
+        if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle)
+        {
+            evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;
+
+            pp = nfa_hci_cb.cfg.dyn_pipes;
+
+            /* Loop through looking for a match */
+            for ( yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++)
+            {
+                if (pp->local_gate == pg->gate_id)
+                    evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] = *(tNFA_HCI_PIPE_INFO*)pp;
+            }
+        }
+    }
+    evt_data.gates_pipes.status = NFA_STATUS_OK;
+
+    /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
+    nfa_hciu_send_to_app (NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, p_evt_data->get_gate_pipe_list.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_alloc_gate
+**
+** Description      action function to allocate a generic gate
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HANDLE         app_handle = p_evt_data->comm.hci_handle;
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HCI_DYN_GATE   *p_gate;
+
+    p_gate = nfa_hciu_alloc_gate (0, app_handle);
+
+    evt_data.allocated.gate   = p_gate ? p_gate->gate_id : 0;
+    evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+    /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
+    nfa_hciu_send_to_app (NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_dealloc_gate
+**
+** Description      action function to deallocate the given generic gate
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    UINT8               gate_id;
+    tNFA_HCI_DYN_GATE   *p_gate;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    tNFA_HANDLE         app_handle;
+
+    /* p_evt_data may be NULL if we are recursively deleting pipes */
+    if (p_evt_data)
+    {
+        gate_id    = p_evt_data->gate_dealloc.gate;
+        app_handle = p_evt_data->gate_dealloc.hci_handle;
+
+    }
+    else
+    {
+        nfa_sys_stop_timer (&nfa_hci_cb.timer);
+        gate_id    = nfa_hci_cb.local_gate_in_use;
+        app_handle = nfa_hci_cb.app_in_use;
+    }
+
+    evt_data.deallocated.gate = gate_id;;
+
+    p_gate = nfa_hciu_find_gate_by_gid (gate_id);
+
+    if (p_gate == NULL)
+    {
+        evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
+    }
+    else if (p_gate->gate_owner != app_handle)
+    {
+        evt_data.deallocated.status = NFA_STATUS_FAILED;
+    }
+    else
+    {
+        /* See if any pipe is owned by this app */
+        if ((p_pipe = nfa_hciu_find_pipe_on_gate (p_gate->gate_id)) == NULL)
+        {
+            nfa_hciu_release_gate (p_gate->gate_id);
+
+            nfa_hci_cb.nv_write_needed  = TRUE;
+            evt_data.deallocated.status = NFA_STATUS_OK;
+
+            if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+                nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+        }
+        else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate (p_gate->gate_id)) == NULL)
+        {
+            /* UICC is not active at the moment and cannot delete the pipe */
+            nfa_hci_cb.nv_write_needed  = TRUE;
+            evt_data.deallocated.status = NFA_STATUS_FAILED;
+
+            if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+                nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+        }
+        else
+        {
+            /* Delete pipes on the gate */
+            nfa_hci_cb.local_gate_in_use = gate_id;
+            nfa_hci_cb.app_in_use        = app_handle;
+            nfa_hci_cb.hci_state         = NFA_HCI_STATE_REMOVE_GATE;
+
+            nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id);
+            return;
+        }
+    }
+
+    nfa_hciu_send_to_app (NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_host_list
+**
+** Description      action function to get the host list from HCI network
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    UINT8               app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
+
+    nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
+
+    /* First, check if the application handle is valid */
+    if (  ((nfa_hci_cb.app_in_use & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI)
+        ||(app_inx >= NFA_HCI_MAX_APP_CB)
+        ||(nfa_hci_cb.p_app_cback[app_inx] == NULL) )
+    {
+        return;
+    }
+
+    nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_create_pipe
+**
+** Description      action function to create a pipe
+**
+** Returns          TRUE, if the command is processed
+**                  FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_DYN_GATE   *p_gate = nfa_hciu_find_gate_by_gid (p_evt_data->create_pipe.source_gate);
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    /* Verify that the app owns the gate that the pipe is being created on */
+    if ((p_gate == NULL) || (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle))
+    {
+        evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
+        evt_data.created.status = NFA_STATUS_FAILED;
+
+        NFA_TRACE_ERROR2 ("nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own the gate:0x%x", p_evt_data->create_pipe.hci_handle, p_evt_data->create_pipe.source_gate);
+        nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
+    }
+    else
+    {
+        if (nfa_hciu_is_host_reseting (p_evt_data->create_pipe.dest_gate))
+        {
+            GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+            return FALSE;
+        }
+
+        nfa_hci_cb.local_gate_in_use  = p_evt_data->create_pipe.source_gate;
+        nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
+        nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
+        nfa_hci_cb.app_in_use         = p_evt_data->create_pipe.hci_handle;
+
+        nfa_hciu_send_create_pipe_cmd (p_evt_data->create_pipe.source_gate, p_evt_data->create_pipe.dest_host, p_evt_data->create_pipe.dest_gate);
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_open_pipe
+**
+** Description      action function to open a pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->open_pipe.pipe);
+    tNFA_HCI_DYN_GATE   *p_gate = NULL;
+
+    if (p_pipe != NULL)
+        p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+    if (  (p_pipe != NULL)
+        &&(p_gate != NULL)
+        &&(nfa_hciu_is_active_host (p_pipe->dest_host))
+        &&(p_gate->gate_owner == p_evt_data->open_pipe.hci_handle))
+    {
+        if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
+        {
+            nfa_hciu_send_open_pipe_cmd (p_evt_data->open_pipe.pipe);
+        }
+        else
+        {
+            evt_data.opened.pipe   = p_evt_data->open_pipe.pipe;
+            evt_data.opened.status = NFA_STATUS_OK;
+
+            nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
+        }
+    }
+    else
+    {
+        evt_data.opened.pipe   = p_evt_data->open_pipe.pipe;
+        evt_data.opened.status = NFA_STATUS_FAILED;
+
+        nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_get_reg_value
+**
+** Description      action function to get the reg value of the specified index
+**
+** Returns          TRUE, if the command is processed
+**                  FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->get_registry.pipe);
+    tNFA_HCI_DYN_GATE   *p_gate;
+    tNFA_STATUS         status = NFA_STATUS_FAILED;
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    if (p_pipe != NULL)
+    {
+        p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+        if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->get_registry.hci_handle))
+        {
+            nfa_hci_cb.app_in_use        = p_evt_data->get_registry.hci_handle;
+
+            if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
+            {
+                GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+                return FALSE;
+            }
+
+            if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
+            {
+                NFA_TRACE_WARNING1 ("nfa_hci_api_get_reg_value pipe:%d not open", p_evt_data->get_registry.pipe);
+            }
+            else
+            {
+                if ((status = nfa_hciu_send_get_param_cmd (p_evt_data->get_registry.pipe, p_evt_data->get_registry.reg_inx)) == NFA_STATUS_OK)
+                    return TRUE;
+            }
+        }
+    }
+
+    evt_data.cmd_sent.status = status;
+
+    /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+    nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->get_registry.hci_handle);
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_set_reg_value
+**
+** Description      action function to set the reg value at specified index
+**
+** Returns          TRUE, if the command is processed
+**                  FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->set_registry.pipe);
+    tNFA_HCI_DYN_GATE   *p_gate;
+    tNFA_STATUS         status = NFA_STATUS_FAILED;
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    if (p_pipe != NULL)
+    {
+        p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+        if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->set_registry.hci_handle))
+        {
+            nfa_hci_cb.app_in_use        = p_evt_data->set_registry.hci_handle;
+
+            if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
+            {
+                GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+                return FALSE;
+            }
+
+            if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
+            {
+                NFA_TRACE_WARNING1 ("nfa_hci_api_set_reg_value pipe:%d not open", p_evt_data->set_registry.pipe);
+            }
+            else
+            {
+                if ((status = nfa_hciu_send_set_param_cmd (p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx, p_evt_data->set_registry.size, p_evt_data->set_registry.data)) == NFA_STATUS_OK)
+                    return TRUE;
+            }
+        }
+    }
+    evt_data.cmd_sent.status = status;
+
+    /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+    nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->set_registry.hci_handle);
+    return TRUE;
+
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_close_pipe
+**
+** Description      action function to close a pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->close_pipe.pipe);
+    tNFA_HCI_DYN_GATE   *p_gate = NULL;
+
+    if (p_pipe != NULL)
+        p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+
+    if (  (p_pipe != NULL)
+        &&(p_gate != NULL)
+        &&(nfa_hciu_is_active_host (p_pipe->dest_host))
+        &&(p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)  )
+    {
+        if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+        {
+            nfa_hciu_send_close_pipe_cmd (p_evt_data->close_pipe.pipe);
+        }
+        else
+        {
+            evt_data.closed.status = NFA_STATUS_OK;
+            evt_data.closed.pipe   = p_evt_data->close_pipe.pipe;
+
+            nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
+        }
+    }
+    else
+    {
+        evt_data.closed.status = NFA_STATUS_FAILED;
+        evt_data.closed.pipe   = 0x00;
+
+        nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_delete_pipe
+**
+** Description      action function to delete a pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->delete_pipe.pipe);
+    tNFA_HCI_DYN_GATE   *p_gate = NULL;
+
+    if (p_pipe != NULL)
+    {
+        p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+        if (  (p_gate != NULL)
+            &&(p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle)
+            &&(nfa_hciu_is_active_host (p_pipe->dest_host))  )
+        {
+            nfa_hciu_send_delete_pipe_cmd (p_evt_data->delete_pipe.pipe);
+            return;
+        }
+    }
+
+    evt_data.deleted.status = NFA_STATUS_FAILED;
+    evt_data.deleted.pipe   = 0x00;
+    nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_send_cmd
+**
+** Description      action function to send command on the given pipe
+**
+** Returns          TRUE, if the command is processed
+**                  FALSE, if command is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_STATUS         status = NFA_STATUS_FAILED;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HANDLE         app_handle;
+
+    if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_cmd.pipe)) != NULL)
+    {
+        app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_cmd.pipe);
+
+        if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
+            &&(app_handle == p_evt_data->send_cmd.hci_handle)  )
+        {
+            if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
+            {
+                GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+                return FALSE;
+            }
+
+            if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+            {
+                nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
+                if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, p_evt_data->send_cmd.cmd_code,
+                                            p_evt_data->send_cmd.cmd_len, p_evt_data->send_cmd.data)) == NFA_STATUS_OK)
+                    return TRUE;
+            }
+            else
+            {
+                NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not open", p_pipe->pipe_id);
+            }
+        }
+        else
+        {
+            NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d Owned by different application or Destination host is not active",
+                                p_pipe->pipe_id);
+        }
+    }
+    else
+    {
+        NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not found", p_evt_data->send_cmd.pipe);
+    }
+
+    evt_data.cmd_sent.status = status;
+
+    /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
+    nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->send_cmd.hci_handle);
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_send_rsp
+**
+** Description      action function to send response on the given pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_STATUS         status = NFA_STATUS_FAILED;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HANDLE         app_handle;
+
+    if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_rsp.pipe)) != NULL)
+    {
+        app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_rsp.pipe);
+
+        if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
+            &&(app_handle == p_evt_data->send_rsp.hci_handle)  )
+        {
+            if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+            {
+                if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, p_evt_data->send_rsp.response,
+                                            p_evt_data->send_rsp.size, p_evt_data->send_rsp.data)) == NFA_STATUS_OK)
+                    return;
+            }
+            else
+            {
+                NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not open", p_pipe->pipe_id);
+            }
+        }
+        else
+        {
+            NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d Owned by different application or Destination host is not active",
+                                p_pipe->pipe_id);
+        }
+    }
+    else
+    {
+        NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not found", p_evt_data->send_rsp.pipe);
+    }
+
+    evt_data.rsp_sent.status = status;
+
+    /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
+    nfa_hciu_send_to_app (NFA_HCI_RSP_SENT_EVT, &evt_data, p_evt_data->send_rsp.hci_handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_send_event
+**
+** Description      action function to send an event to the given pipe
+**
+** Returns          TRUE, if the event is processed
+**                  FALSE, if event is queued for processing later
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_STATUS         status = NFA_STATUS_FAILED;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HANDLE         app_handle;
+
+    if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_evt.pipe)) != NULL)
+    {
+        app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_evt.pipe);
+
+        if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
+            &&(app_handle == p_evt_data->send_evt.hci_handle)  )
+        {
+            if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
+            {
+                GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
+                return FALSE;
+            }
+
+            if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+            {
+                status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
+                                            p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
+
+                if (status == NFA_STATUS_OK)
+                {
+                    if (p_evt_data->send_evt.rsp_len)
+                    {
+                        nfa_hci_cb.pipe_in_use  = p_evt_data->send_evt.pipe;
+                        nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
+                        nfa_hci_cb.p_rsp_buf    = p_evt_data->send_evt.p_rsp_buf;
+                        if (p_evt_data->send_evt.rsp_timeout)
+                        {
+                            nfa_hci_cb.w4_rsp_evt   = TRUE;
+                            nfa_hci_cb.hci_state    = NFA_HCI_STATE_WAIT_RSP;
+                            nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_evt_data->send_evt.rsp_timeout);
+                        }
+                    }
+                    else
+                    {
+                        nfa_hci_cb.rsp_buf_size = 0;
+                        nfa_hci_cb.p_rsp_buf    = NULL;
+                    }
+                }
+            }
+            else
+            {
+                NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not open", p_pipe->pipe_id);
+            }
+        }
+        else
+        {
+            NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d Owned by different application or Destination host is not active",
+                                p_pipe->pipe_id);
+        }
+    }
+    else
+    {
+        NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not found", p_evt_data->send_evt.pipe);
+    }
+
+    evt_data.evt_sent.status = status;
+
+    /* Send NFC_HCI_EVENT_SENT_EVT to notify failure */
+    nfa_hciu_send_to_app (NFA_HCI_EVENT_SENT_EVT, &evt_data, p_evt_data->send_evt.hci_handle);
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_api_add_static_pipe
+**
+** Description      action function to add static pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    tNFA_HCI_DYN_PIPE   *pp;
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    /* Allocate a proprietary gate */
+    if ((pg = nfa_hciu_alloc_gate (p_evt_data->add_static_pipe.gate, p_evt_data->add_static_pipe.hci_handle)) != NULL)
+    {
+        /* Assign new owner to the gate */
+        pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
+
+        /* Add the dynamic pipe to the proprietary gate */
+        if (nfa_hciu_add_pipe_to_gate (p_evt_data->add_static_pipe.pipe,pg->gate_id, p_evt_data->add_static_pipe.host, p_evt_data->add_static_pipe.gate) != NFA_HCI_ANY_OK)
+        {
+            /* Unable to add the dynamic pipe, so release the gate */
+            nfa_hciu_release_gate (pg->gate_id);
+            evt_data.pipe_added.status = NFA_STATUS_FAILED;
+            nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
+            return;
+        }
+        if ((pp = nfa_hciu_find_pipe_by_pid (p_evt_data->add_static_pipe.pipe)) != NULL)
+        {
+            /* This pipe is always opened */
+            pp->pipe_state = NFA_HCI_PIPE_OPENED;
+            evt_data.pipe_added.status = NFA_STATUS_OK;
+            nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
+            return;
+        }
+    }
+    /* Unable to add static pipe */
+    evt_data.pipe_added.status = NFA_STATUS_FAILED;
+    nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
+
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_link_mgm_gate_cmd
+**
+** Description      This function handles incoming link management gate hci
+**                  commands
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data)
+{
+    UINT8       index;
+    UINT8       data[2];
+    UINT8       rsp_len = 0;
+    UINT8       response = NFA_HCI_ANY_OK;
+
+    if (  (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED)
+        &&(nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE) )
+    {
+        nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
+        return;
+    }
+
+    switch (nfa_hci_cb.inst)
+    {
+    case NFA_HCI_ANY_SET_PARAMETER:
+        STREAM_TO_UINT8 (index, p_data);
+
+        if (index == 1)
+        {
+            STREAM_TO_UINT16 (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
+        }
+        else
+            response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
+        break;
+
+    case NFA_HCI_ANY_GET_PARAMETER:
+        STREAM_TO_UINT8 (index, p_data);
+        if (index == 1)
+        {
+            data[0] = (UINT8) ((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
+            data[1] = (UINT8) (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
+            rsp_len = 2;
+        }
+        else
+            response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
+        break;
+
+    case NFA_HCI_ANY_OPEN_PIPE:
+        data[0]  = 0;
+        rsp_len  = 1;
+        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
+        break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+        nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+        break;
+
+    default:
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+    }
+
+    nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_pipe_open_close_cmd
+**
+** Description      This function handles all generic gates (excluding
+**                  connectivity gate) commands
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    UINT8               data[1];
+    UINT8               rsp_len = 0;
+    tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
+    tNFA_HCI_DYN_GATE   *p_gate;
+
+    if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
+    {
+        if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
+            data[0] = nfa_hciu_count_open_pipes_on_gate (p_gate);
+        else
+            data[0] = 0;
+
+        p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+        rsp_len = 1;
+    }
+    else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
+    {
+        p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+    }
+
+    nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_admin_gate_cmd
+**
+** Description      This function handles incoming commands on ADMIN gate
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data)
+{
+    UINT8               source_host, source_gate, dest_host, dest_gate, pipe;
+    UINT8               data = 0;
+    UINT8               rsp_len = 0;
+    tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
+    tNFA_HCI_DYN_GATE   *pgate;
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    switch (nfa_hci_cb.inst)
+    {
+    case NFA_HCI_ANY_OPEN_PIPE:
+        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
+        data    = 0;
+        rsp_len = 1;
+        break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+        nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+        /* Reopen the pipe immediately */
+        nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
+        nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
+        nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+        return;
+        break;
+
+    case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
+        STREAM_TO_UINT8 (source_host, p_data);
+        STREAM_TO_UINT8 (source_gate, p_data);
+        STREAM_TO_UINT8 (dest_host,   p_data);
+        STREAM_TO_UINT8 (dest_gate,   p_data);
+        STREAM_TO_UINT8 (pipe,        p_data);
+
+        if (  (dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+            ||(dest_gate == NFA_HCI_LOOP_BACK_GATE) )
+        {
+            response = nfa_hciu_add_pipe_to_static_gate (dest_gate, pipe, source_host, source_gate);
+        }
+        else
+        {
+            if ((pgate = nfa_hciu_find_gate_by_gid (dest_gate)) != NULL)
+            {
+                /* If the gate is valid, add the pipe to it  */
+                if ((response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate)) == NFA_HCI_ANY_OK)
+                {
+                    /* Tell the application a pipe was created with its gate */
+
+                    evt_data.created.status       = NFA_STATUS_OK;
+                    evt_data.created.pipe         = pipe;
+                    evt_data.created.source_gate  = dest_gate;
+                    evt_data.created.dest_host    = source_host;
+                    evt_data.created.dest_gate    = source_gate;
+
+                    nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, pgate->gate_owner);
+                }
+            }
+            else
+                response = NFA_HCI_ANY_E_NOK;
+        }
+        break;
+
+    case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
+        STREAM_TO_UINT8 (pipe, p_data);
+        response = nfa_hciu_release_pipe (pipe);
+        break;
+
+    case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
+        STREAM_TO_UINT8 (source_host, p_data);
+
+        nfa_hciu_remove_all_pipes_from_host (source_host);
+
+        if (source_host == NFA_HCI_HOST_CONTROLLER)
+        {
+            nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+            nfa_hci_cb.cfg.admin_gate.pipe01_state     = NFA_HCI_PIPE_CLOSED;
+
+            /* Reopen the admin pipe immediately */
+            nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
+            nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+            return;
+        }
+        else
+        {
+            if (  (source_host >= NFA_HCI_HOST_ID_UICC0)
+                &&(source_host < (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))  )
+            {
+                nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = source_host;
+            }
+        }
+        break;
+
+    default:
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+    }
+
+    nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_admin_gate_rsp
+**
+** Description      This function handles response received on admin gate
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len)
+{
+    UINT8               hosts[2] = {NFA_HCI_HOST_ID_UICC0, (NFA_HCI_HOST_ID_UICC0 + 1)};
+    UINT8               source_host;
+    UINT8               source_gate = nfa_hci_cb.local_gate_in_use;
+    UINT8               dest_host   = nfa_hci_cb.remote_host_in_use;
+    UINT8               dest_gate   = nfa_hci_cb.remote_gate_in_use;
+    UINT8               pipe        = 0;
+    tNFA_STATUS         status;
+    tNFA_HCI_EVT_DATA   evt_data;
+    UINT8               default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    UINT8               host_count  = 0;
+    UINT8               host_id     = 0;
+    UINT32              os_tick;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s  App: 0x%04x  Gate: 0x%02x  Pipe: 0x%02x",
+                       nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
+#else
+    NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp LastCmdSent: %u  App: 0x%04x  Gate: 0x%02x  Pipe: 0x%02x",
+                       nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
+#endif
+
+    if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED)
+    {
+        nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+        return;
+    }
+
+    /* If starting up, handle events here */
+    if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
+        ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
+        ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)  )
+    {
+        if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
+        {
+            NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_rsp - Initialization failed");
+            nfa_hci_startup_complete (NFA_STATUS_FAILED);
+            return;
+        }
+
+        switch (nfa_hci_cb.cmd_sent)
+        {
+        case NFA_HCI_ANY_SET_PARAMETER:
+            if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
+            {
+                /* Set WHITELIST */
+                nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 0x02, hosts);
+            }
+            else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX)
+            {
+                if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
+                    nfa_hci_dh_startup_complete ();
+
+                else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
+                    nfa_hci_startup_complete (NFA_STATUS_OK);
+            }
+            break;
+
+        case NFA_HCI_ANY_GET_PARAMETER:
+            if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
+            {
+                host_count = 0;
+                while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
+                {
+                    nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
+                    host_count++;
+                }
+
+                host_count = 0;
+                /* Collect active host in the Host Network */
+                while (host_count < data_len)
+                {
+                    host_id = (UINT8) *p_data++;
+
+                    if (  (host_id >= NFA_HCI_HOST_ID_UICC0)
+                        &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)  )
+                    {
+                        nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+                        nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+                    }
+
+                    host_count++;
+                }
+                nfa_hci_startup_complete (NFA_STATUS_OK);
+            }
+            else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
+            {
+                /* The only parameter we get when initializing is the session ID. Check for match. */
+                if (!memcmp ((UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, p_data, NFA_HCI_SESSION_ID_LEN) )
+                {
+                    /* Session has not changed. Set the WHITELIST */
+                    nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 0x01, hosts);
+                }
+                else
+                {
+                    /* Something wrong, NVRAM data could be corrupt or first start with default session id */
+                    nfa_hciu_send_clear_all_pipe_cmd ();
+                    nfa_hci_cb.b_hci_netwk_reset = TRUE;
+                }
+            }
+            break;
+
+        case NFA_HCI_ANY_OPEN_PIPE:
+            nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
+
+            if (nfa_hci_cb.b_hci_netwk_reset)
+            {
+                nfa_hci_cb.b_hci_netwk_reset = FALSE;
+               /* Session ID is reset, Set New session id */
+                memcpy (&nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
+                os_tick = GKI_get_os_tick_count ();
+                memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+                nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
+            }
+            else
+            {
+                /* First thing is to get the session ID */
+                nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
+            }
+            break;
+
+        case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+            nfa_hciu_remove_all_pipes_from_host (0);
+            nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+            nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+            nfa_hci_cb.nv_write_needed = TRUE;
+
+            /* Open admin */
+            nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+            break;
+        }
+    }
+    else
+    {
+        status = (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+        switch (nfa_hci_cb.cmd_sent)
+        {
+        case NFA_HCI_ANY_SET_PARAMETER:
+            if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+                nfa_hci_api_deregister (NULL);
+            else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+                nfa_hci_api_dealloc_gate (NULL);
+            break;
+
+        case NFA_HCI_ANY_GET_PARAMETER:
+            if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
+            {
+                if (!memcmp ((UINT8 *) default_session, p_data , NFA_HCI_SESSION_ID_LEN))
+                {
+                    memcpy (&nfa_hci_cb.cfg.admin_gate.session_id[(NFA_HCI_SESSION_ID_LEN / 2)], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
+                    os_tick = GKI_get_os_tick_count ();
+                    memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *) &os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+                    nfa_hci_cb.nv_write_needed = TRUE;
+                    nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
+                }
+                else
+                {
+                    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+                        nfa_hci_api_deregister (NULL);
+                    else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+                        nfa_hci_api_dealloc_gate (NULL);
+                }
+            }
+            else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
+            {
+                evt_data.hosts.status    = status;
+                evt_data.hosts.num_hosts = data_len;
+                memcpy (evt_data.hosts.host, p_data, data_len);
+
+                host_count = 0;
+                while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
+                {
+                    nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
+                    host_count++;
+                }
+
+                host_count = 0;
+                /* Collect active host in the Host Network */
+                while (host_count < data_len)
+                {
+                    host_id = (UINT8) *p_data++;
+
+                    if (  (host_id >= NFA_HCI_HOST_ID_UICC0)
+                        &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)  )
+                    {
+                        nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+                        nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
+                    }
+                    host_count++;
+                }
+                if (nfa_hciu_is_no_host_resetting ())
+                    nfa_hci_check_pending_api_requests ();
+                nfa_hciu_send_to_app (NFA_HCI_HOST_LIST_EVT, &evt_data, nfa_hci_cb.app_in_use);
+            }
+            break;
+
+        case NFA_HCI_ADM_CREATE_PIPE:
+            if (status == NFA_STATUS_OK)
+            {
+                STREAM_TO_UINT8 (source_host, p_data);
+                STREAM_TO_UINT8 (source_gate, p_data);
+                STREAM_TO_UINT8 (dest_host,   p_data);
+                STREAM_TO_UINT8 (dest_gate,   p_data);
+                STREAM_TO_UINT8 (pipe,        p_data);
+
+                /* Sanity check */
+                if (source_gate != nfa_hci_cb.local_gate_in_use)
+                {
+                    NFA_TRACE_WARNING2 ("nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u got back: %u",
+                                        nfa_hci_cb.local_gate_in_use, source_gate);
+                    break;
+                }
+
+                nfa_hciu_add_pipe_to_gate (pipe, source_gate, dest_host, dest_gate);
+
+            }
+
+            /* Tell the application his pipe was created or not */
+            evt_data.created.status       = status;
+            evt_data.created.pipe         = pipe;
+            evt_data.created.source_gate  = source_gate;
+            evt_data.created.dest_host    = dest_host;
+            evt_data.created.dest_gate    = dest_gate;
+
+            nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+            break;
+
+        case NFA_HCI_ADM_DELETE_PIPE:
+            if (status == NFA_STATUS_OK)
+            {
+                nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+
+                /* If only deleting one pipe, tell the app we are done */
+                if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+                {
+                    evt_data.deleted.status         = status;
+                    evt_data.deleted.pipe           = nfa_hci_cb.pipe_in_use;
+
+                    nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+                }
+                else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+                    nfa_hci_api_deregister (NULL);
+                else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+                    nfa_hci_api_dealloc_gate (NULL);
+            }
+            else
+            {
+                /* If only deleting one pipe, tell the app we are done */
+                if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+                {
+                    evt_data.deleted.status         = status;
+                    evt_data.deleted.pipe           = nfa_hci_cb.pipe_in_use;
+
+                    nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+                }
+                else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
+                {
+                    nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+                    nfa_hci_api_deregister (NULL);
+                }
+                else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
+                {
+                    nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+                    nfa_hci_api_dealloc_gate (NULL);
+                }
+            }
+            break;
+
+        case NFA_HCI_ANY_OPEN_PIPE:
+            nfa_hci_cb.cfg.admin_gate.pipe01_state = status ? NFA_HCI_PIPE_CLOSED:NFA_HCI_PIPE_OPENED;
+            nfa_hci_cb.nv_write_needed = TRUE;
+            if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED)
+            {
+                /* First thing is to get the session ID */
+                nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
+            }
+            break;
+
+        case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+            nfa_hciu_remove_all_pipes_from_host (0);
+            nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
+            nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
+            nfa_hci_cb.nv_write_needed = TRUE;
+            /* Open admin */
+            nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+            break;
+
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_admin_gate_evt
+**
+** Description      This function handles events received on admin gate
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_admin_gate_evt (UINT8 *p_data)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG)
+    {
+        NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
+        return;
+    }
+
+    evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
+
+    nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+    nfa_hciu_send_to_all_apps (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_dyn_pipe_pkt
+**
+** Description      This function handles data received via dynamic pipe
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe_id, UINT8 *p_data, UINT16 data_len)
+{
+    tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id);
+    tNFA_HCI_DYN_GATE   *p_gate;
+
+    if (p_pipe == NULL)
+    {
+        /* Invalid pipe ID */
+        NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",pipe_id);
+        if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+            nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
+        return;
+    }
+
+    if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+    {
+        nfa_hci_handle_identity_mgmt_gate_pkt (p_data, p_pipe);
+    }
+    else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
+    {
+        nfa_hci_handle_loopback_gate_pkt (p_data, data_len, p_pipe);
+    }
+    else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
+    {
+        nfa_hci_handle_connectivity_gate_pkt (p_data, data_len, p_pipe);
+    }
+    else
+    {
+        p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
+        if (p_gate == NULL)
+        {
+            NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",p_pipe->local_gate);
+            if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+                nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
+            return;
+        }
+
+        /* Check if data packet is a command, response or event */
+        switch (nfa_hci_cb.type)
+        {
+        case NFA_HCI_COMMAND_TYPE:
+            nfa_hci_handle_generic_gate_cmd (p_data, (UINT8) data_len, p_gate, p_pipe);
+            break;
+
+        case NFA_HCI_RESPONSE_TYPE:
+            nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe);
+            break;
+
+        case NFA_HCI_EVENT_TYPE:
+            nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe);
+            break;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_identity_mgmt_gate_pkt
+**
+** Description      This function handles incoming Identity Management gate hci
+**                  commands
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    UINT8       data[20];
+    UINT8       index;
+    UINT8       gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
+    UINT16      rsp_len = 0;
+    UINT8       *p_rsp = data;
+    tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
+
+    /* We never send commands on a pipe where the local gate is the identity management
+     * gate, so only commands should be processed.
+     */
+    if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE)
+        return;
+
+    switch (nfa_hci_cb.inst)
+    {
+    case  NFA_HCI_ANY_GET_PARAMETER:
+        index = *(p_data++);
+        if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
+        {
+            switch (index)
+            {
+            case NFA_HCI_VERSION_SW_INDEX:
+                data[0] = (UINT8) ((NFA_HCI_VERSION_SW >> 16 ) & 0xFF);
+                data[1] = (UINT8) ((NFA_HCI_VERSION_SW >> 8 ) & 0xFF);
+                data[2] = (UINT8) ((NFA_HCI_VERSION_SW ) & 0xFF);
+                rsp_len = 3;
+                break;
+
+            case NFA_HCI_HCI_VERSION_INDEX:
+                data[0] = NFA_HCI_VERSION;
+                rsp_len = 1;
+                break;
+
+            case NFA_HCI_VERSION_HW_INDEX:
+                data[0] = (UINT8) ((NFA_HCI_VERSION_HW >> 16 ) & 0xFF);
+                data[1] = (UINT8) ((NFA_HCI_VERSION_HW >> 8 ) & 0xFF);
+                data[2] = (UINT8) ((NFA_HCI_VERSION_HW ) & 0xFF);
+                rsp_len = 3;
+                break;
+
+            case NFA_HCI_VENDOR_NAME_INDEX:
+                memcpy (data,NFA_HCI_VENDOR_NAME,strlen (NFA_HCI_VENDOR_NAME));
+                rsp_len = (UINT8) strlen (NFA_HCI_VENDOR_NAME);
+                break;
+
+            case NFA_HCI_MODEL_ID_INDEX:
+                data[0] = NFA_HCI_MODEL_ID;
+                rsp_len = 1;
+                break;
+
+            case NFA_HCI_GATES_LIST_INDEX:
+                gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
+                gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
+                gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
+                num_gates   = nfa_hciu_get_allocated_gate_list (&gate_rsp[3]);
+                rsp_len     = num_gates + 3;
+                p_rsp       = gate_rsp;
+                break;
+
+            default:
+                response = NFA_HCI_ANY_E_NOK;
+                break;
+            }
+        }
+        else
+        {
+            response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
+        }
+        break;
+
+    case NFA_HCI_ANY_OPEN_PIPE:
+        data[0] = 0;
+        rsp_len = 1;
+        p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+        break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+        p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+        break;
+
+    default:
+        response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
+        break;
+    }
+
+    nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, p_rsp);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_generic_gate_cmd
+**
+** Description      This function handles all generic gates (excluding
+**                  connectivity gate) commands
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_cmd (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_HANDLE         app_handle = nfa_hciu_get_pipe_owner (p_pipe->pipe_id);
+
+    switch (nfa_hci_cb.inst)
+    {
+    case NFA_HCI_ANY_SET_PARAMETER:
+        evt_data.registry.pipe     = p_pipe->pipe_id;
+        evt_data.registry.index    = *p_data++;
+        if (data_len > 0)
+            data_len--;
+        evt_data.registry.data_len = data_len;
+
+        if (data_len <= NFA_MAX_HCI_DATA_LEN)
+            memcpy (evt_data.registry.reg_data, p_data, data_len);
+
+        nfa_hciu_send_to_app (NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
+        break;
+
+    case NFA_HCI_ANY_GET_PARAMETER:
+        evt_data.registry.pipe     = p_pipe->pipe_id;
+        evt_data.registry.index    = *p_data;
+        evt_data.registry.data_len = 0;
+
+        nfa_hciu_send_to_app (NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
+        break;
+
+    case NFA_HCI_ANY_OPEN_PIPE:
+        nfa_hci_handle_pipe_open_close_cmd (p_pipe);
+
+        evt_data.opened.pipe   = p_pipe->pipe_id;
+        evt_data.opened.status = NFA_STATUS_OK;
+
+        nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
+        break;
+
+    case NFA_HCI_ANY_CLOSE_PIPE:
+        nfa_hci_handle_pipe_open_close_cmd (p_pipe);
+
+        evt_data.closed.pipe   = p_pipe->pipe_id;
+        evt_data.opened.status = NFA_STATUS_OK;
+
+        nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
+        break;
+
+    default:
+        /* Could be application specific command, pass it on */
+        evt_data.cmd_rcvd.status   = NFA_STATUS_OK;
+        evt_data.cmd_rcvd.pipe     = p_pipe->pipe_id;;
+        evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
+        evt_data.cmd_rcvd.cmd_len  = data_len;
+
+        if (data_len <= NFA_MAX_HCI_CMD_LEN)
+            memcpy (evt_data.cmd_rcvd.cmd_data, p_data, data_len);
+
+        nfa_hciu_send_to_app (NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_generic_gate_rsp
+**
+** Description      This function handles all generic gates (excluding
+**                  connectivity) response
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_rsp (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+    tNFA_STATUS         status = NFA_STATUS_OK;
+
+    if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
+        status = NFA_STATUS_FAILED;
+
+    if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE)
+    {
+        if (status == NFA_STATUS_OK)
+            p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+
+        nfa_hci_cb.nv_write_needed = TRUE;
+        /* Tell application */
+        evt_data.opened.status  = status;
+        evt_data.opened.pipe    = p_pipe->pipe_id;
+
+        nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+    }
+    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
+    {
+        p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+
+        nfa_hci_cb.nv_write_needed = TRUE;
+        /* Tell application */
+        evt_data.opened.status = status;;
+        evt_data.opened.pipe   = p_pipe->pipe_id;
+
+        nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
+    }
+    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER)
+    {
+        /* Tell application */
+        evt_data.registry.status   = status;
+        evt_data.registry.pipe     = p_pipe->pipe_id;
+        evt_data.registry.data_len = data_len;
+        evt_data.registry.index    = nfa_hci_cb.param_in_use;
+
+        memcpy (evt_data.registry.reg_data, p_data, data_len);
+
+        nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
+    }
+    else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER)
+    {
+        /* Tell application */
+        evt_data.registry.status = status;;
+        evt_data.registry.pipe   = p_pipe->pipe_id;
+
+        nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
+    }
+    else
+    {
+        /* Could be a response to application specific command sent, pass it on */
+        evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
+        evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
+        evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
+        evt_data.rsp_rcvd.rsp_len  = data_len;
+
+        if (data_len <= NFA_MAX_HCI_RSP_LEN)
+            memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
+
+        nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_connectivity_gate_pkt
+**
+** Description      This function handles incoming connectivity gate packets
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+    {
+        switch (nfa_hci_cb.inst)
+        {
+        case NFA_HCI_ANY_OPEN_PIPE:
+        case NFA_HCI_ANY_CLOSE_PIPE:
+            nfa_hci_handle_pipe_open_close_cmd (p_pipe);
+            break;
+
+        case NFA_HCI_CON_PRO_HOST_REQUEST:
+            /* A request to the DH to activate another host. This is not supported for */
+            /* now, we will implement it when the spec is clearer and UICCs need it.   */
+            nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
+            break;
+
+        default:
+            nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
+            break;
+        }
+    }
+    else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
+    {
+        if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
+            p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+        else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
+            p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+    }
+    else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+    {
+        evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
+        evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
+        evt_data.rcvd_evt.evt_len   = data_len;
+        evt_data.rcvd_evt.p_evt_buf = p_data;
+
+        /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
+        nfa_hciu_send_to_apps_handling_connectivity_evts (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_loopback_gate_pkt
+**
+** Description      This function handles incoming loopback gate hci events
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    UINT8               data[1];
+    UINT8               rsp_len = 0;
+    tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
+
+
+    /* Check if data packet is a command, response or event */
+    if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+    {
+        if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
+        {
+            data[0] = 0;
+            rsp_len = 1;
+            p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
+        }
+        else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
+        {
+            p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
+        }
+        else
+            response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
+
+        nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
+    }
+    else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
+    {
+        /* Since we never send any commands on our local loopback gate,
+         * there should not be any response.
+         */
+    }
+    else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+    {
+        if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA)
+        {
+            /* Send back the same data we got */
+            nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, NFA_HCI_EVT_POST_DATA, data_len, p_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_generic_gate_evt
+**
+** Description      This function handles incoming Generic gate hci events
+**
+** Returns          none
+**
+*******************************************************************************/
+static void nfa_hci_handle_generic_gate_evt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
+    evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
+    evt_data.rcvd_evt.evt_len   = data_len;
+
+    if (nfa_hci_cb.assembly_failed)
+        evt_data.rcvd_evt.status    = NFA_STATUS_BUFFER_FULL;
+    else
+        evt_data.rcvd_evt.status    = NFA_STATUS_OK;
+
+    evt_data.rcvd_evt.p_evt_buf = p_data;
+    nfa_hci_cb.rsp_buf_size     = 0;
+    nfa_hci_cb.p_rsp_buf        = NULL;
+
+    /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
+    nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
+}
+
diff --git a/src/nfa/hci/nfa_hci_api.c b/src/nfa/hci/nfa_hci_api.c
new file mode 100644
index 0000000..4b28987
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_api.c
@@ -0,0 +1,1004 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface to HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_hci_defs.h"
+
+/*******************************************************************************
+**
+** Function         NFA_HciRegister
+**
+** Description      This function will register an application with hci and
+**                  returns an application handle and provides a mechanism to
+**                  register a callback with HCI to receive NFA HCI event notification.
+**                  When the application is registered (or if an error occurs),
+**                  the app will be notified with NFA_HCI_REGISTER_EVT. Previous
+**                  session information including allocated gates, created pipes
+**                  and pipes states will be returned as part of tNFA_HCI_REGISTER data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciRegister (char *p_app_name, tNFA_HCI_CBACK *p_cback, BOOLEAN b_send_conn_evts)
+{
+    tNFA_HCI_API_REGISTER_APP *p_msg;
+    UINT8                     app_name_len;
+
+    if (p_app_name == NULL)
+    {
+        NFA_TRACE_API0 ("NFA_HciRegister (): Invalid Application name");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (p_cback == NULL)
+    {
+        NFA_TRACE_API0 ("NFA_HciRegister (): Application should provide callback function to register!");
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API1 ("NFA_HciRegister (): Application Name: %s", p_app_name);
+
+    app_name_len = (UINT8) strlen (p_app_name);
+
+    /* Register the application with HCI */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&(p_app_name != NULL)
+        &&(app_name_len <= NFA_MAX_HCI_APP_NAME_LEN)
+        &&((p_msg = (tNFA_HCI_API_REGISTER_APP *) GKI_getbuf (sizeof (tNFA_HCI_API_REGISTER_APP))) != NULL))
+    {
+        p_msg->hdr.event  = NFA_HCI_API_REGISTER_APP_EVT;
+
+        /* Save application name and callback */
+        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+        BCM_STRNCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+        p_msg->p_cback          = p_cback;
+        p_msg->b_send_conn_evts = b_send_conn_evts;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetGateAndPipeList
+**
+** Description      This function will get the list of gates allocated to the
+**                  application and list of dynamic pipes created by the
+**                  application. The app will be notified with
+**                  NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
+**                  gates to the application and list of pipes created by the
+**                  application will be returned as part of
+**                  tNFA_HCI_GET_GATE_PIPE_LIST data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetGateAndPipeList (tNFA_HANDLE hci_handle)
+{
+    tNFA_HCI_API_GET_APP_GATE_PIPE *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciGetGateAndPipeList (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API1 ("NFA_HciGetGateAndPipeList (): hci_handle:0x%04x", hci_handle);
+
+    /* Register the application with HCI */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_GET_APP_GATE_PIPE *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_APP_GATE_PIPE))) != NULL))
+    {
+        p_msg->hdr.event  = NFA_HCI_API_GET_APP_GATE_PIPE_EVT;
+        p_msg->hci_handle = hci_handle;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeregister
+**
+** Description      This function is called to deregister an application
+**                  from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
+**                  after deleting all the pipes owned by the app and deallocating
+**                  all the gates allocated to the app or if an error occurs.
+**                  Even if deregistration fails, the app has to register again
+**                  to provide a new cback function.
+**
+** Returns          NFA_STATUS_OK if the application is deregistered successfully
+**                  NFA_STATUS_FAILED otherwise
+
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeregister (char *p_app_name)
+{
+    tNFA_HCI_API_DEREGISTER_APP *p_msg;
+    int                         xx;
+    UINT8                       app_name_len;
+
+    if (p_app_name == NULL)
+    {
+        NFA_TRACE_API0 ("NFA_HciDeregister (): Invalid Application");
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API1 ("NFA_HciDeregister (): Application Name: %s", p_app_name);
+    app_name_len = (UINT8) strlen (p_app_name);
+
+    if (app_name_len > NFA_MAX_HCI_APP_NAME_LEN)
+        return (NFA_STATUS_FAILED);
+
+    /* Find the application registration */
+    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+    {
+        if (  (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+            &&(!strncmp (p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], app_name_len)) )
+            break;
+    }
+
+    if (xx == NFA_HCI_MAX_APP_CB)
+    {
+        NFA_TRACE_ERROR1 ("NFA_HciDeregister (): Application Name: %s  NOT FOUND", p_app_name);
+        return (NFA_STATUS_FAILED);
+    }
+
+    /* Deregister the application with HCI */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_DEREGISTER_APP *) GKI_getbuf (sizeof (tNFA_HCI_API_DEREGISTER_APP))) != NULL) )
+    {
+        p_msg->hdr.event  = NFA_HCI_API_DEREGISTER_APP_EVT;
+
+        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+        BCM_STRNCPY_S (p_msg->app_name, sizeof (p_msg->app_name), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciAllocGate
+**
+** Description      This function will allocate an available generic gate for
+**                  the app to provide an entry point for a particular service
+**                  to other host or to establish communication with other host.
+**                  When the generic gate is allocated (or if an error occurs),
+**                  the app will be notified with NFA_HCI_ALLOCATE_GATE_EVT with
+**                  the gate id. The allocated Gate information will be stored in
+**                  non volatile memory.
+**
+** Returns          NFA_STATUS_OK if this API started
+**                  NFA_STATUS_FAILED if no generic gate is available
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciAllocGate (tNFA_HANDLE hci_handle)
+{
+    tNFA_HCI_API_ALLOC_GATE *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciAllocGate (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API1 ("NFA_HciAllocGate (): hci_handle:0x%04x", hci_handle);
+
+    /* Request HCI to allocate a gate to the application */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_ALLOC_GATE *) GKI_getbuf (sizeof (tNFA_HCI_API_ALLOC_GATE))) != NULL) )
+    {
+        p_msg->hdr.event  = NFA_HCI_API_ALLOC_GATE_EVT;
+        p_msg->hci_handle = hci_handle;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeallocGate
+**
+** Description      This function will release the specified gate that was
+**                  previously allocated to the application. When the generic
+**                  gate is released (or if an error occurs), the app will be
+**                  notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeallocGate (tNFA_HANDLE hci_handle, UINT8 gate)
+{
+    tNFA_HCI_API_DEALLOC_GATE *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciDeallocGate (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || (gate > NFA_HCI_LAST_HOST_SPECIFIC_GENERIC_GATE) || (gate == NFA_HCI_CONNECTIVITY_GATE))
+    {
+        NFA_TRACE_API1 ("NFA_HciDeallocGate (): Cannot deallocate the gate:0x%02x", gate);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API2 ("NFA_HciDeallocGate (): hci_handle:0x%04x, gate:0x%02X", hci_handle, gate);
+
+    /* Request HCI to deallocate the gate that was previously allocated to the application */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_DEALLOC_GATE *) GKI_getbuf (sizeof (tNFA_HCI_API_DEALLOC_GATE))) != NULL) )
+    {
+        p_msg->hdr.event  = NFA_HCI_API_DEALLOC_GATE_EVT;
+        p_msg->hci_handle = hci_handle;
+        p_msg->gate       = gate;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetHostList
+**
+** Description      This function will request the host controller to return the
+**                  list of hosts that are present in the host network. When
+**                  host controller responds with the host list (or if an error
+**                  occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetHostList (tNFA_HANDLE hci_handle)
+{
+    tNFA_HCI_API_GET_HOST_LIST *p_msg;
+
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciGetHostList (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API1 ("NFA_HciGetHostList (): hci_handle:0x%04x",hci_handle);
+
+    /* Request HCI to get list of host in the hci network */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_GET_HOST_LIST_EVT;
+        p_msg->hci_handle   = hci_handle;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciCreatePipe
+**
+** Description      This function is called to create a dynamic pipe with the
+**                  specified host. When the dynamic pipe is created (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists
+**                  between the two gates passed as argument and if it was
+**                  created earlier by the calling application then the pipe
+**                  id of the existing pipe will be returned and a new pipe
+**                  will not be created. After successful creation of pipe,
+**                  registry entry will be created for the dynamic pipe and
+**                  all information related to the pipe will be stored in non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciCreatePipe (tNFA_HANDLE  hci_handle,
+                               UINT8        source_gate_id,
+                               UINT8        dest_host,
+                               UINT8        dest_gate)
+{
+    tNFA_HCI_API_CREATE_PIPE_EVT *p_msg;
+    UINT8                        xx;
+
+    NFA_TRACE_API4 ("NFA_HciCreatePipe (): hci_handle:0x%04x, source gate:0x%02X, destination host:0x%02X , destination gate:0x%02X",
+                                         hci_handle, source_gate_id, dest_host, dest_gate);
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((source_gate_id < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) || (source_gate_id > NFA_HCI_LAST_HOST_SPECIFIC_GENERIC_GATE))
+    {
+        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid local Gate:0x%02x", source_gate_id);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (  ((dest_gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE) && (dest_gate != NFA_HCI_LOOP_BACK_GATE) && (dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE))
+        ||(dest_gate > NFA_HCI_LAST_HOST_SPECIFIC_GENERIC_GATE))
+    {
+        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Invalid Destination Gate:0x%02x", dest_gate);
+        return (NFA_STATUS_FAILED);
+    }
+
+    for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+        if (nfa_hci_cb.inactive_host[xx] == dest_host)
+            break;
+
+    if (xx != NFA_HCI_MAX_HOST_IN_NETWORK)
+    {
+        NFA_TRACE_API1 ("NFA_HciCreatePipe (): Host not active:0x%02x", dest_host);
+        return (NFA_STATUS_FAILED);
+    }
+
+    /* Request HCI to create a pipe between two specified gates */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&(!nfa_hci_cb.b_low_power_mode)
+        &&((p_msg = (tNFA_HCI_API_CREATE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CREATE_PIPE_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_CREATE_PIPE_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->source_gate  = source_gate_id;
+        p_msg->dest_host    = dest_host;        /* Host id of the destination host */
+        p_msg->dest_gate    = dest_gate;        /* Gate id of the destination gate */
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciOpenPipe
+**
+** Description      This function is called to open a dynamic pipe.
+**                  When the dynamic pipe is opened (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_OPEN_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciOpenPipe (tNFA_HANDLE hci_handle, UINT8 pipe)
+{
+    tNFA_HCI_API_OPEN_PIPE_EVT *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
+    {
+        NFA_TRACE_API1 ("NFA_HciOpenPipe (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+
+    NFA_TRACE_API2 ("NFA_HciOpenPipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+    /* Request HCI to open a pipe if it is in closed state */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&(!nfa_hci_cb.b_low_power_mode)
+        &&((p_msg = (tNFA_HCI_API_OPEN_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_OPEN_PIPE_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_OPEN_PIPE_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;                     /* Pipe ID of the pipe to open */
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetRegistry
+**
+** Description      This function requests a peer host to return the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_GET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciGetRegistry (tNFA_HANDLE hci_handle, UINT8 pipe, UINT8 reg_inx)
+{
+    tNFA_HCI_API_GET_REGISTRY *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_API1 ("NFA_HciGetRegistry (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API2 ("NFA_HciGetRegistry (): hci_handle:0x%04x  Pipe: 0x%02x", hci_handle, pipe);
+
+    /* Request HCI to get list of gates supported by the specified host */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_GET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_REGISTRY))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_GET_REGISTRY_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;
+        p_msg->reg_inx      = reg_inx;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSetRegistry
+**
+** Description      This function requests a peer host to set the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_SET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSetRegistry (tNFA_HANDLE   hci_handle,
+                                               UINT8         pipe,
+                                               UINT8         reg_inx,
+                                               UINT8         data_size,
+                                               UINT8         *p_data)
+{
+    tNFA_HCI_API_SET_REGISTRY *p_msg;
+
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((data_size == 0) || (p_data == NULL) || (data_size > NFA_MAX_HCI_CMD_LEN))
+    {
+        NFA_TRACE_API1 ("NFA_HciSetRegistry (): Invalid data size:0x%02x", data_size);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API2 ("NFA_HciSetRegistry (): hci_handle:0x%04x  Pipe: 0x%02x", hci_handle, pipe);
+
+    /* Request HCI to get list of gates supported by the specified host */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_SET_REGISTRY *) GKI_getbuf (sizeof (tNFA_HCI_API_SET_REGISTRY))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_SET_REGISTRY_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;
+        p_msg->reg_inx      = reg_inx;
+        p_msg->size         = data_size;
+
+        memcpy (p_msg->data, p_data, data_size);
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendCommand
+**
+** Description      This function is called to send a command on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
+**                  occurs.
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_RSP_RCVD_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendCommand (tNFA_HANDLE  hci_handle,
+                              UINT8        pipe,
+                              UINT8        cmd_code,
+                              UINT16       cmd_size,
+                              UINT8        *p_data)
+{
+    tNFA_HCI_API_SEND_CMD_EVT *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((cmd_size && (p_data == NULL)) || (cmd_size > NFA_MAX_HCI_CMD_LEN))
+    {
+        NFA_TRACE_API1 ("NFA_HciSendCommand (): Invalid cmd size:0x%02x", cmd_size);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API3 ("NFA_HciSendCommand (): hci_handle:0x%04x, pipe:0x%02x  Code: 0x%02x", hci_handle, pipe, cmd_code);
+
+    /* Request HCI to post event data on a particular pipe */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_SEND_CMD_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_CMD_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_SEND_CMD_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;
+        p_msg->cmd_code     = cmd_code;
+        p_msg->cmd_len      = cmd_size;
+
+        if (cmd_size)
+            memcpy (p_msg->data, p_data, cmd_size);
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendResponse
+**
+** Description      This function is called to send a response on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
+**                  occurs.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendResponse (tNFA_HANDLE   hci_handle,
+                                                UINT8         pipe,
+                                                UINT8         response,
+                                                UINT8         data_size,
+                                                UINT8         *p_data)
+{
+    tNFA_HCI_API_SEND_RSP_EVT *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((data_size && (p_data == NULL)) || (data_size > NFA_MAX_HCI_RSP_LEN))
+    {
+        NFA_TRACE_API1 ("NFA_HciSendResponse (): Invalid data size:0x%02x", data_size);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API3 ("NFA_HciSendResponse (): hci_handle:0x%04x  Pipe: 0x%02x  Response: 0x%02x", hci_handle, pipe, response);
+
+    /* Request HCI to get list of gates supported by the specified host */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_SEND_RSP_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_RSP_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_SEND_RSP_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->response     = response;
+        p_msg->size         = data_size;
+
+        if (data_size)
+            memcpy (p_msg->data, p_data, data_size);
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendEvent
+**
+** Description      This function is called to send any event on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_EVENT_SENT_EVT
+**                  after successfully sending the event on the specified pipe
+**                  or if an error occurs. The application should wait for this
+**                  event before releasing event buffer passed as argument.
+**                  If the app is expecting a response to the event then it can
+**                  provide response buffer for collecting the response. If it
+**                  provides a response buffer it can also provide response
+**                  timeout indicating maximum timeout for the response.
+**                  Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
+**                  using internal buffer if no response buffer is provided by
+**                  the application. The app will be notified by
+**                  NFA_HCI_EVENT_RCVD_EVT after receiving the response event
+**                  or on timeout if app provided response buffer and response
+**                  timeout. If response buffer and response timeout is provided
+**                  by the application, it should wait for this event before
+**                  releasing the response buffer. If the application did not
+**                  provide response timeout then it should not release the
+**                  response buffer until it receives NFA_HCI_EVENT_RCVD_EVT or
+**                  after timeout it sends next event on the same pipe
+**                  and receives NFA_HCI_EVENT_SENT_EVT for that event.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciSendEvent (tNFA_HANDLE  hci_handle,
+                              UINT8        pipe,
+                              UINT8        evt_code,
+                              UINT16       evt_size,
+                              UINT8        *p_data,
+                              UINT16       rsp_size,
+                              UINT8        *p_rsp_buf,
+                              UINT16       rsp_timeout)
+{
+    tNFA_HCI_API_SEND_EVENT_EVT *p_msg;
+
+    NFA_TRACE_API3 ("NFA_HciSendEvent(): hci_handle:0x%04x, pipe:0x%02x  Code: 0x%02x", hci_handle, pipe, evt_code);
+
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (pipe < NFA_HCI_FIRST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (evt_size && (p_data == NULL))
+    {
+        NFA_TRACE_API1 ("NFA_HciSendEvent (): Invalid Event size:0x%02x", evt_size);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (rsp_size && (p_rsp_buf == NULL))
+    {
+        NFA_TRACE_API1 ("NFA_HciSendEvent (): No Event buffer, but invalid event buffer size :%u", rsp_size);
+        return (NFA_STATUS_FAILED);
+    }
+
+    /* Request HCI to post event data on a particular pipe */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_SEND_EVENT_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_SEND_EVENT_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_SEND_EVENT_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;
+        p_msg->evt_code     = evt_code;
+        p_msg->evt_len      = evt_size;
+        p_msg->p_evt_buf    = p_data;
+        p_msg->rsp_len      = rsp_size;
+        p_msg->p_rsp_buf    = p_rsp_buf;
+        p_msg->rsp_timeout  = rsp_timeout;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciClosePipe
+**
+** Description      This function is called to close a dynamic pipe.
+**                  When the dynamic pipe is closed (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciClosePipe (tNFA_HANDLE hci_handle, UINT8 pipe)
+{
+    tNFA_HCI_API_CLOSE_PIPE_EVT *p_msg;
+
+    NFA_TRACE_API2 ("NFA_HciClosePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
+    {
+        NFA_TRACE_API1 ("NFA_HciClosePipe (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    /* Request HCI to close a pipe if it is in opened state */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&(!nfa_hci_cb.b_low_power_mode)
+        &&((p_msg = (tNFA_HCI_API_CLOSE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_CLOSE_PIPE_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_CLOSE_PIPE_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeletePipe
+**
+** Description      This function is called to delete a particular dynamic pipe.
+**                  When the dynamic pipe is deleted (or if an error occurs),
+**                  the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
+**                  the pipe id. After successful deletion of pipe, registry
+**                  entry will be deleted for the dynamic pipe and all
+**                  information related to the pipe will be deleted from non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciDeletePipe (tNFA_HANDLE  hci_handle, UINT8 pipe)
+{
+    tNFA_HCI_API_DELETE_PIPE_EVT *p_msg;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((pipe < NFA_HCI_FIRST_DYNAMIC_PIPE) || (pipe > NFA_HCI_LAST_DYNAMIC_PIPE))
+    {
+        NFA_TRACE_API1 ("NFA_HciDeletePipe (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API2 ("NFA_HciDeletePipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+    /* Request HCI to delete a pipe created by the application identified by hci handle */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&(!nfa_hci_cb.b_low_power_mode)
+        &&((p_msg = (tNFA_HCI_API_DELETE_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_DELETE_PIPE_EVT))) != NULL) )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_DELETE_PIPE_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->pipe         = pipe;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_HciAddStaticPipe
+**
+** Description      This function is called to add a static pipe for sending
+**                  7816 APDUs. When the static pipe is added (or if an error occurs),
+**                  the app will be notified with NFA_HCI_ADD_STATIC_PIPE_EVT with
+**                  the status.
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_HciAddStaticPipe (tNFA_HANDLE hci_handle, UINT8 host, UINT8 gate, UINT8 pipe)
+{
+    tNFA_HCI_API_ADD_STATIC_PIPE_EVT *p_msg;
+    UINT8                            xx;
+
+    if ((NFA_HANDLE_GROUP_MASK & hci_handle) != NFA_HANDLE_GROUP_HCI)
+    {
+        NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid hci_handle:0x%04x", hci_handle);
+        return (NFA_STATUS_FAILED);
+    }
+
+    for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+        if (nfa_hci_cb.inactive_host[xx] == host)
+            break;
+
+    if (xx != NFA_HCI_MAX_HOST_IN_NETWORK)
+    {
+        NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Host not active:0x%02x", host);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (gate <= NFA_HCI_LAST_HOST_SPECIFIC_GATE)
+    {
+        NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid Gate:0x%02x", gate);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if (pipe <= NFA_HCI_LAST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_API1 ("NFA_HciAddStaticPipe (): Invalid Pipe:0x%02x", pipe);
+        return (NFA_STATUS_FAILED);
+    }
+
+    NFA_TRACE_API2 ("NFA_HciAddStaticPipe (): hci_handle:0x%04x, pipe:0x%02X", hci_handle, pipe);
+
+    /* Request HCI to delete a pipe created by the application identified by hci handle */
+    if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_DISABLED)
+        &&((p_msg = (tNFA_HCI_API_ADD_STATIC_PIPE_EVT *) GKI_getbuf (sizeof (tNFA_HCI_API_ADD_STATIC_PIPE_EVT))) != NULL)  )
+    {
+        p_msg->hdr.event    = NFA_HCI_API_ADD_STATIC_PIPE_EVT;
+        p_msg->hci_handle   = hci_handle;
+        p_msg->host         = host;
+        p_msg->gate         = gate;
+        p_msg->pipe         = pipe;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    /* Unable to add static pipe */
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_HciDebug
+**
+** Description      Debug function.
+**
+*******************************************************************************/
+void NFA_HciDebug (UINT8 action, UINT8 size, UINT8 *p_data)
+{
+    int                 xx;
+    tNFA_HCI_DYN_GATE   *pg = nfa_hci_cb.cfg.dyn_gates;
+    tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
+    BT_HDR              *p_msg;
+    UINT8               *p;
+
+    switch (action)
+    {
+    case NFA_HCI_DEBUG_DISPLAY_CB:
+        NFA_TRACE_API0 ("NFA_HciDebug  Host List:");
+        for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+        {
+            if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+            {
+                NFA_TRACE_API2 ("              Host Inx:  %u   Name: %s", xx, &nfa_hci_cb.cfg.reg_app_names[xx][0]);
+            }
+        }
+
+        NFA_TRACE_API0 ("NFA_HciDebug  Gate List:");
+        for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+        {
+            if (pg->gate_id != 0)
+            {
+                NFA_TRACE_API4 ("              Gate Inx: %x  ID: 0x%02x  Owner: 0x%04x  PipeInxMask: 0x%08x",
+                                xx, pg->gate_id, pg->gate_owner, pg->pipe_inx_mask);
+            }
+        }
+
+        NFA_TRACE_API0 ("NFA_HciDebug  Pipe List:");
+        for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+        {
+            if (pp->pipe_id != 0)
+            {
+                NFA_TRACE_API6 ("              Pipe Inx: %x  ID: 0x%02x  State: %u  LocalGate: 0x%02x  Dest Gate: 0x%02x  Host: 0x%02x",
+                    xx, pp->pipe_id, pp->pipe_state, pp->local_gate, pp->dest_gate, pp->dest_host);
+            }
+        }
+        break;
+
+    case NFA_HCI_DEBUG_SIM_HCI_EVENT:
+        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+        {
+            p = (UINT8 *) (p_msg + 1);
+
+            p_msg->event  = NFA_HCI_CHECK_QUEUE_EVT;
+            p_msg->len    = size;
+            p_msg->offset = 0;
+
+            memcpy (p, p_data, size);
+
+            nfa_sys_sendmsg (p_msg);
+        }
+        break;
+
+    case NFA_HCI_DEBUG_ENABLE_LOOPBACK:
+        NFA_TRACE_API0 ("NFA_HciDebug  HCI_LOOPBACK_DEBUG = TRUE");
+        HCI_LOOPBACK_DEBUG = TRUE;
+        break;
+
+    case NFA_HCI_DEBUG_DISABLE_LOOPBACK:
+        NFA_TRACE_API0 ("NFA_HciDebug  HCI_LOOPBACK_DEBUG = FALSE");
+        HCI_LOOPBACK_DEBUG = FALSE;
+        break;
+    }
+}
diff --git a/src/nfa/hci/nfa_hci_ci.c b/src/nfa/hci/nfa_hci_ci.c
new file mode 100644
index 0000000..a368d13
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_ci.c
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the call-in functions for NFA HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_nv_co.h"
+
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_read
+**
+** Description      call-in function for non volatile memory read acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_nv_ci_read (UINT16 num_bytes_read, tNFA_NV_CO_STATUS status, UINT8 block)
+{
+    tNFA_HCI_EVENT_DATA *p_msg;
+
+    if ((p_msg = (tNFA_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFA_HCI_EVENT_DATA))) != NULL)
+    {
+        p_msg->nv_read.hdr.event = NFA_HCI_RSP_NV_READ_EVT;
+
+        if (  (status == NFA_STATUS_OK)
+            &&(num_bytes_read != 0) )
+        {
+            p_msg->nv_read.status = NFA_STATUS_OK;
+            p_msg->nv_read.size   = num_bytes_read;
+        }
+        else
+            p_msg->nv_read.status = NFA_STATUS_FAILED;
+
+        p_msg->nv_read.block = block;
+        nfa_sys_sendmsg (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_write
+**
+** Description      call-in function for non volatile memory write acess
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_nv_ci_write (tNFA_NV_CO_STATUS status)
+{
+    tNFA_HCI_EVENT_DATA *p_msg;
+
+    if ((p_msg = (tNFA_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFA_HCI_EVENT_DATA))) != NULL)
+    {
+        p_msg->nv_write.hdr.event = NFA_HCI_RSP_NV_WRITE_EVT;
+        p_msg->nv_write.status = 0;
+        nfa_sys_sendmsg (p_msg);
+    }
+}
+
diff --git a/src/nfa/hci/nfa_hci_main.c b/src/nfa/hci/nfa_hci_main.c
new file mode 100644
index 0000000..ebcc588
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_main.c
@@ -0,0 +1,1057 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_ee_api.h"
+#include "nfa_ee_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+#include "trace_api.h"
+
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+tNFA_HCI_CB nfa_hci_cb;
+
+#ifndef NFA_HCI_NV_READ_TIMEOUT_VAL
+#define NFA_HCI_NV_READ_TIMEOUT_VAL    1000
+#endif
+
+#ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL
+#define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000
+#endif
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static BOOLEAN nfa_hci_evt_hdlr (BT_HDR *p_msg);
+
+static void nfa_hci_sys_enable (void);
+static void nfa_hci_sys_disable (void);
+static void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data);
+static void nfa_hci_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+static void nfa_hci_set_receive_buf (UINT8 pipe);
+static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len);
+static void nfa_hci_handle_nv_read (UINT8 block, tNFA_STATUS status);
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_hci_sys_reg =
+{
+    nfa_hci_sys_enable,
+    nfa_hci_evt_hdlr,
+    nfa_hci_sys_disable,
+    nfa_hci_proc_nfcc_power_mode
+};
+
+/*******************************************************************************
+**
+** Function         nfa_hci_ee_info_cback
+**
+** Description      Callback function
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_ee_info_cback (BOOLEAN disable_discover)
+{
+    NFA_TRACE_DEBUG1 ("nfa_hci_ee_info_cback (): %d", disable_discover);
+
+    /* Notify EE Discovery is complete */
+
+    if (disable_discover)
+    {
+        nfa_hci_cb.w4_hci_netwk_init = FALSE;
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
+        {
+            nfa_sys_stop_timer (&nfa_hci_cb.timer);
+            nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+        }
+    }
+    else
+    {
+        nfa_hci_cb.ee_disc_cmplt = TRUE;
+        nfa_hci_startup ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_init
+**
+** Description      Initialize NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_init (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_hci_init ()");
+
+    /* initialize control block */
+    memset (&nfa_hci_cb, 0, sizeof (tNFA_HCI_CB));
+
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP;
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register (NFA_ID_HCI, &nfa_hci_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_is_valid_cfg
+**
+** Description      Validate hci control block config parameters
+**
+** Returns          None
+**
+*******************************************************************************/
+BOOLEAN nfa_hci_is_valid_cfg (void)
+{
+    UINT8       xx,yy,zz;
+    tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB];
+    UINT8       valid_gate[NFA_HCI_MAX_GATE_CB];
+    UINT8       app_count       = 0;
+    UINT8       gate_count      = 0;
+    UINT32      pipe_inx_mask   = 0;
+
+    /* First, see if valid values are stored in app names, send connectivity events flag */
+    for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
+    {
+        /* Check if app name is valid with null terminated string */
+        if (strlen (&nfa_hci_cb.cfg.reg_app_names[xx][0]) > NFA_MAX_HCI_APP_NAME_LEN)
+            return FALSE;
+
+        /* Send Connectivity event flag can be either TRUE or FALSE */
+        if (  (nfa_hci_cb.cfg.b_send_conn_evts[xx] != TRUE)
+            &&(nfa_hci_cb.cfg.b_send_conn_evts[xx] != FALSE))
+            return FALSE;
+
+        if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
+        {
+            /* Check if the app name is present more than one time in the control block */
+            for (yy = xx + 1; yy < NFA_HCI_MAX_APP_CB; yy++)
+            {
+                if (  (nfa_hci_cb.cfg.reg_app_names[yy][0] != 0)
+                    &&(!strncmp (&nfa_hci_cb.cfg.reg_app_names[xx][0], &nfa_hci_cb.cfg.reg_app_names[yy][0], strlen (nfa_hci_cb.cfg.reg_app_names[xx]))) )
+                {
+                    /* Two app cannot have the same name , NVRAM is corrupted */
+                    NFA_TRACE_EVENT2 ("nfa_hci_is_valid_cfg (%s)  Reusing: %u", &nfa_hci_cb.cfg.reg_app_names[xx][0], xx);
+                    return FALSE;
+                }
+            }
+            /* Collect list of hci handle */
+            reg_app[app_count++] = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
+        }
+    }
+
+    /* Validate Gate Control block */
+    for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++)
+    {
+        if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != 0)
+        {
+            if (  (  (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_LOOP_BACK_GATE)
+                   &&(nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+                   &&(nfa_hci_cb.cfg.dyn_gates[xx].gate_id < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE))
+                ||(nfa_hci_cb.cfg.dyn_gates[xx].gate_id > NFA_HCI_LAST_PROP_GATE))
+                return FALSE;
+
+            /* Check if the same gate id is present more than once in the control block */
+            for (yy = xx + 1; yy < NFA_HCI_MAX_GATE_CB; yy++)
+            {
+                if (  (nfa_hci_cb.cfg.dyn_gates[yy].gate_id != 0)
+                    &&(nfa_hci_cb.cfg.dyn_gates[xx].gate_id == nfa_hci_cb.cfg.dyn_gates[yy].gate_id) )
+                {
+                    NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg  Reusing: %u", nfa_hci_cb.cfg.dyn_gates[xx].gate_id);
+                    return FALSE;
+                }
+            }
+            if ((nfa_hci_cb.cfg.dyn_gates[xx].gate_owner & (~NFA_HANDLE_GROUP_HCI)) >= NFA_HCI_MAX_APP_CB)
+            {
+                NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg  Invalid Gate owner: %u", nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
+                return FALSE;
+            }
+            if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_CONNECTIVITY_GATE)
+            {
+                /* The gate owner should be one of the registered application */
+                for (zz = 0; zz < app_count; zz++)
+                {
+                    if (nfa_hci_cb.cfg.dyn_gates[xx].gate_owner == reg_app[zz])
+                        break;
+                }
+                if (zz == app_count)
+                {
+                    NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg  Invalid Gate owner: %u", nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
+                    return FALSE;
+                }
+            }
+            /* Collect list of allocated gates */
+            valid_gate[gate_count++] = nfa_hci_cb.cfg.dyn_gates[xx].gate_id;
+
+            /* No two gates can own a same pipe */
+            if ((pipe_inx_mask & nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask) != 0)
+                return FALSE;
+            /* Collect the list of pipes on this gate */
+            pipe_inx_mask |= nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask;
+        }
+    }
+
+    for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB)); xx++,pipe_inx_mask >>= 1)
+    {
+        /* Every bit set in pipe increment mask indicates a valid pipe */
+        if (pipe_inx_mask & 1)
+        {
+            /* Check if the pipe is valid one */
+            if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
+                return FALSE;
+        }
+    }
+
+    if (xx == NFA_HCI_MAX_PIPE_CB)
+        return FALSE;
+
+    /* Validate Gate Control block */
+    for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++)
+    {
+        if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id != 0)
+        {
+            /* Check if pipe id is valid */
+            if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
+                return FALSE;
+
+            /* Check if pipe state is valid */
+            if (  (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_OPENED)
+                &&(nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_CLOSED))
+                return FALSE;
+
+            /* Check if local gate on which the pipe is created is valid */
+            if (  (((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate != NFA_HCI_LOOP_BACK_GATE) && (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) && (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE))
+                ||(nfa_hci_cb.cfg.dyn_pipes[xx].local_gate > NFA_HCI_LAST_PROP_GATE))
+                return FALSE;
+
+            /* Check if the peer gate on which the pipe is created is valid */
+            if (  (((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate != NFA_HCI_LOOP_BACK_GATE) && (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)) && (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate < NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE))
+                ||(nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate > NFA_HCI_LAST_PROP_GATE))
+                return FALSE;
+
+            /* Check if the same pipe is present more than once in the control block */
+            for (yy = xx + 1; yy < NFA_HCI_MAX_PIPE_CB; yy++)
+            {
+                if (  (nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id != 0)
+                    &&(nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id == nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id) )
+                {
+                    NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg  Reusing: %u", nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
+                    return FALSE;
+                }
+            }
+            /* The local gate should be one of the element in gate control block */
+            for (zz = 0; zz < gate_count; zz++)
+            {
+                if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz])
+                    break;
+            }
+            if (zz == gate_count)
+            {
+                NFA_TRACE_EVENT1 ("nfa_hci_is_valid_cfg  Invalid Gate: %u", nfa_hci_cb.cfg.dyn_pipes[xx].local_gate);
+                return FALSE;
+            }
+        }
+    }
+
+    /* Check if admin pipe state is valid */
+    if (  (nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_OPENED)
+        &&(nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_CLOSED))
+        return FALSE;
+
+    /* Check if link management pipe state is valid */
+    if (  (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED)
+        &&(nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_CLOSED))
+        return FALSE;
+
+    pipe_inx_mask = nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask;
+    for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB)); xx++,pipe_inx_mask >>= 1)
+    {
+        /* Every bit set in pipe increment mask indicates a valid pipe */
+        if (pipe_inx_mask & 1)
+        {
+            /* Check if the pipe is valid one */
+            if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
+                return FALSE;
+            /* Check if the pipe is connected to Identity management gate */
+            if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate != NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+                return FALSE;
+        }
+    }
+    if (xx == NFA_HCI_MAX_PIPE_CB)
+        return FALSE;
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_cfg_default
+**
+** Description      Configure default values for hci control block
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_restore_default_config (UINT8 *p_session_id)
+{
+    memset (&nfa_hci_cb.cfg, 0, sizeof (nfa_hci_cb.cfg));
+    memcpy (nfa_hci_cb.cfg.admin_gate.session_id, p_session_id, NFA_HCI_SESSION_ID_LEN);
+    nfa_hci_cb.nv_write_needed = TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_proc_nfcc_power_mode
+**
+** Description      Restore NFA HCI sub-module
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_proc_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+    NFA_TRACE_DEBUG1 ("nfa_hci_proc_nfcc_power_mode () nfcc_power_mode=%d", nfcc_power_mode);
+
+    /* if NFCC power mode is change to full power */
+    if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL)
+    {
+        nfa_hci_cb.b_low_power_mode = FALSE;
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+        {
+            nfa_hci_cb.hci_state     = NFA_HCI_STATE_RESTORE;
+            nfa_hci_cb.ee_disc_cmplt = FALSE;
+            nfa_hci_cb.conn_id       = 0;
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_hci_proc_nfcc_power_mode (): Cannot restore now");
+            nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_HCI);
+        }
+    }
+    else
+    {
+        nfa_hci_cb.hci_state     = NFA_HCI_STATE_IDLE;
+        nfa_hci_cb.w4_rsp_evt    = FALSE;
+        nfa_hci_cb.conn_id       = 0;
+        nfa_sys_stop_timer (&nfa_hci_cb.timer);
+        nfa_hci_cb.b_low_power_mode = TRUE;
+        nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_HCI);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_dh_startup_complete
+**
+** Description      Initialization of terminal host in HCI Network is completed
+**                  Wait for other host in the network to initialize
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_dh_startup_complete (void)
+{
+    if (nfa_hci_cb.w4_hci_netwk_init)
+    {
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
+        /* No HCP packet to DH for a specified period of time indicates all host in the network is initialized */
+        nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NETWK_INIT_TIMEOUT);
+    }
+    else
+        nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_startup_complete
+**
+** Description      HCI network initialization is completed
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_startup_complete (tNFA_STATUS status)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    NFA_TRACE_EVENT1 ("nfa_hci_startup_complete (): Status: %u", status);
+
+    nfa_sys_stop_timer (&nfa_hci_cb.timer);
+
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
+    {
+        nfa_ee_proc_hci_info_cback ();
+        nfa_sys_cback_notify_nfcc_power_mode_proc_complete (NFA_ID_HCI);
+    }
+    else
+    {
+        evt_data.hci_init.status = status;
+
+        nfa_hciu_send_to_all_apps (NFA_HCI_INIT_EVT, &evt_data);
+        nfa_sys_cback_notify_enable_complete (NFA_ID_HCI);
+    }
+
+    if (status == NFA_STATUS_OK)
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+    else
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_startup
+**
+** Description      Perform HCI startup
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_startup (void)
+{
+    tNFA_STATUS     status = NFA_STATUS_FAILED;
+    tNFA_EE_INFO    ee_info[2];
+    UINT8           num_nfcee = 2;
+    UINT8           target_handle;
+    UINT8           count = 0;
+    BOOLEAN         found = FALSE;
+
+    if (HCI_LOOPBACK_DEBUG)
+    {
+        /* First step in initialization is to open the admin pipe */
+        nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+        return;
+    }
+
+    /* We can only start up if NV Ram is read and EE discovery is complete */
+    if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt && (nfa_hci_cb.conn_id == 0))
+    {
+        NFA_EeGetInfo (&num_nfcee, ee_info);
+        nfa_hci_cb.num_nfcee = num_nfcee;
+
+        while ((count < num_nfcee) && (!found))
+        {
+            target_handle = (UINT8) ee_info[count].ee_handle;
+
+            if(ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS)
+            {
+                found = TRUE;
+
+                if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE)
+                {
+                    NFC_NfceeModeSet (target_handle, NFC_MODE_ACTIVATE);
+                }
+                if ((status = NFC_ConnCreate (NCI_DEST_TYPE_NFCEE, target_handle, NFA_EE_INTERFACE_HCI_ACCESS, nfa_hci_conn_cback)) == NFA_STATUS_OK)
+                    nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_CON_CREATE_TIMEOUT_VAL);
+                else
+                {
+                    nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+                    NFA_TRACE_ERROR0 ("nfa_hci_startup - Failed to Create Logical connection. HCI Initialization/Restore failed");
+                    nfa_hci_startup_complete (NFA_STATUS_FAILED);
+                }
+            }
+            count++;
+        }
+        if (!found)
+        {
+            NFA_TRACE_ERROR0 ("nfa_hci_startup - HCI ACCESS Interface not discovered. HCI Initialization/Restore failed");
+            nfa_hci_startup_complete (NFA_STATUS_FAILED);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_sys_enable
+**
+** Description      Enable NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_sys_enable (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_hci_sys_enable ()");
+    nfa_ee_reg_cback_enable_done (&nfa_hci_ee_info_cback);
+
+    nfa_nv_co_read ((UINT8 *)&nfa_hci_cb.cfg, sizeof (nfa_hci_cb.cfg),DH_NV_BLOCK);
+    nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NV_READ_TIMEOUT_VAL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_sys_disable
+**
+** Description      Disable NFA HCI
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_sys_disable (void)
+{
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    nfa_sys_stop_timer (&nfa_hci_cb.timer);
+
+    if (nfa_hci_cb.conn_id)
+    {
+        if (nfa_sys_is_graceful_disable ())
+        {
+            /* Tell all applications stack is down */
+            nfa_hciu_send_to_all_apps (NFA_HCI_EXIT_EVT, &evt_data);
+            NFC_ConnClose (nfa_hci_cb.conn_id);
+            return;
+        }
+        nfa_hci_cb.conn_id = 0;
+    }
+
+    nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+    /* deregister message handler on NFA SYS */
+    nfa_sys_deregister (NFA_ID_HCI);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_conn_cback
+**
+** Description      This function Process event from NCI
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    UINT8   *p;
+    BT_HDR  *p_pkt = (BT_HDR *) p_data->data.p_data;
+    UINT8   chaining_bit;
+    UINT8   pipe;
+    UINT16  pkt_len;
+
+    if (event == NFC_CONN_CREATE_CEVT)
+    {
+        nfa_hci_cb.conn_id   = conn_id;
+        nfa_hci_cb.buff_size = p_data->conn_create.buff_size;
+
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
+        {
+            nfa_hci_cb.w4_hci_netwk_init = TRUE;
+            nfa_hciu_alloc_gate (NFA_HCI_CONNECTIVITY_GATE,0);
+        }
+
+        if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED)
+        {
+            /* First step in initialization/restore is to open the admin pipe */
+            nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
+        }
+        else
+        {
+            /* Read session id, to know DH session id is correct */
+            nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
+        }
+    }
+    else if (event == NFC_CONN_CLOSE_CEVT)
+    {
+        nfa_hci_cb.conn_id   = 0;
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
+        /* deregister message handler on NFA SYS */
+        nfa_sys_deregister (NFA_ID_HCI);
+    }
+
+    if ((event != NFC_DATA_CEVT) || (p_pkt == NULL))
+            return;
+
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
+    {
+        /* Received HCP Packet before timeout, Other Host initialization is not complete */
+        nfa_sys_stop_timer (&nfa_hci_cb.timer);
+        nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_NETWK_INIT_TIMEOUT);
+    }
+
+    p       = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
+    pkt_len = p_pkt->len;
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispHcp (p, pkt_len, TRUE, (BOOLEAN) !nfa_hci_cb.assembling);
+#endif
+
+    chaining_bit = ((*p) >> 0x07) & 0x01;
+    pipe = (*p++) & 0x7F;
+    if (pkt_len != 0)
+        pkt_len--;
+
+    if (nfa_hci_cb.assembling == FALSE)
+    {
+        /* First Segment of a packet */
+        nfa_hci_cb.type            = ((*p) >> 0x06) & 0x03;
+        nfa_hci_cb.inst            = (*p++ & 0x3F);
+        if (pkt_len != 0)
+            pkt_len--;
+        nfa_hci_cb.assembly_failed = FALSE;
+        nfa_hci_cb.msg_len         = 0;
+
+        if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION)
+        {
+            nfa_hci_cb.assembling = TRUE;
+            nfa_hci_set_receive_buf (pipe);
+            nfa_hci_assemble_msg (p, pkt_len);
+        }
+        else
+        {
+            if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE))
+            {
+                nfa_hci_set_receive_buf (pipe);
+                nfa_hci_assemble_msg (p, pkt_len);
+                p = nfa_hci_cb.p_msg_data;
+            }
+        }
+    }
+    else
+    {
+        if (nfa_hci_cb.assembly_failed)
+        {
+            /* If Reassembly failed because of insufficient buffer, just drop the new segmented packets */
+            NFA_TRACE_ERROR1 ("nfa_hci_conn_cback (): Insufficient buffer to Reassemble HCP packet! Dropping :%u bytes", pkt_len);
+        }
+        else
+        {
+            /* Reassemble the packet */
+            nfa_hci_assemble_msg (p, pkt_len);
+        }
+
+        if (chaining_bit == NFA_HCI_NO_MESSAGE_FRAGMENTATION)
+        {
+            /* Just added the last segment in the chain. Reset pointers */
+            nfa_hci_cb.assembling = FALSE;
+            p                     = nfa_hci_cb.p_msg_data;
+            pkt_len               = nfa_hci_cb.msg_len;
+        }
+    }
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_EVENT5 ("nfa_hci_conn_cback Recvd data pipe:%d  %s  chain:%d  assmbl:%d  len:%d",
+                      (UINT8)pipe, nfa_hciu_get_type_inst_names (pipe, nfa_hci_cb.type, nfa_hci_cb.inst),
+                      (UINT8)chaining_bit, (UINT8)nfa_hci_cb.assembling, p_pkt->len);
+#else
+    NFA_TRACE_EVENT6 ("nfa_hci_conn_cback Recvd data pipe:%d  Type: %u  Inst: %u  chain:%d reassm:%d len:%d",
+                      pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit, nfa_hci_cb.assembling, p_pkt->len);
+#endif
+
+
+    /* If still reassembling fragments, just return */
+    if (nfa_hci_cb.assembling)
+    {
+        /* if not last packet, release GKI buffer */
+        GKI_freebuf (p_pkt);
+        return;
+    }
+
+    /* If we got a response, cancel the response timer. Also, if waiting for */
+    /* a single response, we can go back to idle state                       */
+    if (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP)
+    {
+        nfa_sys_stop_timer (&nfa_hci_cb.timer);
+        nfa_hci_cb.hci_state  = NFA_HCI_STATE_IDLE;
+        nfa_hci_cb.w4_rsp_evt = FALSE;
+    }
+
+    switch (pipe)
+    {
+    case NFA_HCI_ADMIN_PIPE:
+        /* Check if data packet is a command, response or event */
+        if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+        {
+            nfa_hci_handle_admin_gate_cmd (p);
+        }
+            else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
+        {
+            nfa_hci_handle_admin_gate_rsp (p, (UINT8) pkt_len);
+        }
+        else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
+        {
+            nfa_hci_handle_admin_gate_evt (p);
+        }
+        break;
+
+    case NFA_HCI_LINK_MANAGEMENT_PIPE:
+        /* We don't send Link Management commands, we only get them */
+        if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
+            nfa_hci_handle_link_mgm_gate_cmd (p);
+        break;
+
+    default:
+        if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+            nfa_hci_handle_dyn_pipe_pkt (pipe, p, pkt_len);
+        break;
+    }
+
+    /* Send a message to ouselves to check for anything to do */
+    p_pkt->event = NFA_HCI_CHECK_QUEUE_EVT;
+    p_pkt->len   = 0;
+    nfa_sys_sendmsg (p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_handle_nv_read
+**
+** Description      handler function for nv read complete event
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_handle_nv_read (UINT8 block, tNFA_STATUS status)
+{
+    UINT8   session_id[NFA_HCI_SESSION_ID_LEN];
+    UINT8   default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+    UINT8   reset_session[NFA_HCI_SESSION_ID_LEN]   = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    UINT32  os_tick;
+
+    if (block == DH_NV_BLOCK)
+    {
+        /* Stop timer as NVDATA Read Completed */
+        nfa_sys_stop_timer (&nfa_hci_cb.timer);
+        nfa_hci_cb.nv_read_cmplt = TRUE;
+        if (  (status != NFA_STATUS_OK)
+            ||(!nfa_hci_is_valid_cfg ())
+            ||(!(memcmp (nfa_hci_cb.cfg.admin_gate.session_id, default_session, NFA_HCI_SESSION_ID_LEN)))
+            ||(!(memcmp (nfa_hci_cb.cfg.admin_gate.session_id, reset_session, NFA_HCI_SESSION_ID_LEN)))  )
+        {
+            /* Set a new session id so that we clear all pipes later after seeing a difference with the HC Session ID */
+            memcpy (&session_id[(NFA_HCI_SESSION_ID_LEN / 2)], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
+            os_tick = GKI_get_os_tick_count ();
+            memcpy (session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
+            nfa_hci_restore_default_config (session_id);
+        }
+        nfa_hci_startup ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_rsp_timeout
+**
+** Description      action function to process timeout
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hci_rsp_timeout (tNFA_HCI_EVENT_DATA *p_evt_data)
+{
+    tNFA_HCI_EVT        evt = 0;
+    tNFA_HCI_EVT_DATA   evt_data;
+    UINT8               delete_pipe;
+
+    NFA_TRACE_EVENT2 ("nfa_hci_rsp_timeout () State: %u  Cmd: %u", nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent);
+
+    evt_data.status      = NFA_STATUS_FAILED;
+
+    switch (nfa_hci_cb.hci_state)
+    {
+    case NFA_HCI_STATE_STARTUP:
+    case NFA_HCI_STATE_RESTORE:
+        NFA_TRACE_ERROR0 ("nfa_hci_rsp_timeout - Initialization failed!");
+        nfa_hci_startup_complete (NFA_STATUS_TIMEOUT);
+        break;
+
+    case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
+        /* HCI Network is enabled */
+        nfa_hci_cb.w4_hci_netwk_init = FALSE;
+        nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
+        break;
+
+    case NFA_HCI_STATE_REMOVE_GATE:
+        /* Something wrong, NVRAM data could be corrupt */
+        if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE)
+        {
+            nfa_hciu_send_clear_all_pipe_cmd ();
+        }
+        else
+        {
+            nfa_hciu_remove_all_pipes_from_host (0);
+            nfa_hci_api_dealloc_gate (NULL);
+        }
+        break;
+
+    case NFA_HCI_STATE_APP_DEREGISTER:
+        /* Something wrong, NVRAM data could be corrupt */
+        if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE)
+        {
+            nfa_hciu_send_clear_all_pipe_cmd ();
+        }
+        else
+        {
+            nfa_hciu_remove_all_pipes_from_host (0);
+            nfa_hci_api_deregister (NULL);
+        }
+        break;
+
+    case NFA_HCI_STATE_WAIT_RSP:
+        nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
+
+        if (nfa_hci_cb.w4_rsp_evt)
+        {
+            nfa_hci_cb.w4_rsp_evt       = FALSE;
+            evt                         = NFA_HCI_EVENT_RCVD_EVT;
+            evt_data.rcvd_evt.pipe      = nfa_hci_cb.pipe_in_use;
+            evt_data.rcvd_evt.evt_code  = 0;
+            evt_data.rcvd_evt.evt_len   = 0;
+            evt_data.rcvd_evt.p_evt_buf = NULL;
+            nfa_hci_cb.rsp_buf_size     = 0;
+            nfa_hci_cb.p_rsp_buf        = NULL;
+
+            break;
+        }
+
+        delete_pipe          = 0;
+        switch (nfa_hci_cb.cmd_sent)
+        {
+        case NFA_HCI_ANY_SET_PARAMETER:
+            /*
+             * As no response to the command sent on this pipe, we may assume the pipe is
+             * deleted already and release the pipe. But still send delete pipe command to be safe.
+             */
+            delete_pipe                = nfa_hci_cb.pipe_in_use;
+            evt_data.registry.pipe     = nfa_hci_cb.pipe_in_use;
+            evt_data.registry.data_len = 0;
+            evt_data.registry.index    = nfa_hci_cb.param_in_use;
+            evt                        = NFA_HCI_SET_REG_RSP_EVT;
+            break;
+
+        case NFA_HCI_ANY_GET_PARAMETER:
+            /*
+             * As no response to the command sent on this pipe, we may assume the pipe is
+             * deleted already and release the pipe. But still send delete pipe command to be safe.
+             */
+            delete_pipe                = nfa_hci_cb.pipe_in_use;
+            evt_data.registry.pipe     = nfa_hci_cb.pipe_in_use;
+            evt_data.registry.data_len = 0;
+            evt_data.registry.index    = nfa_hci_cb.param_in_use;
+            evt                        = NFA_HCI_GET_REG_RSP_EVT;
+            break;
+
+        case NFA_HCI_ANY_OPEN_PIPE:
+            /*
+             * As no response to the command sent on this pipe, we may assume the pipe is
+             * deleted already and release the pipe. But still send delete pipe command to be safe.
+             */
+            delete_pipe          = nfa_hci_cb.pipe_in_use;
+            evt_data.opened.pipe = nfa_hci_cb.pipe_in_use;
+            evt                  = NFA_HCI_OPEN_PIPE_EVT;
+            break;
+
+        case NFA_HCI_ANY_CLOSE_PIPE:
+            /*
+             * As no response to the command sent on this pipe, we may assume the pipe is
+             * deleted already and release the pipe. But still send delete pipe command to be safe.
+             */
+            delete_pipe          = nfa_hci_cb.pipe_in_use;
+            evt_data.closed.pipe = nfa_hci_cb.pipe_in_use;
+            evt                  = NFA_HCI_CLOSE_PIPE_EVT;
+            break;
+
+        case NFA_HCI_ADM_CREATE_PIPE:
+            evt_data.created.pipe        = nfa_hci_cb.pipe_in_use;
+            evt_data.created.source_gate = nfa_hci_cb.local_gate_in_use;
+            evt_data.created.dest_host   = nfa_hci_cb.remote_host_in_use;
+            evt_data.created.dest_gate   = nfa_hci_cb.remote_gate_in_use;
+            evt                          = NFA_HCI_CREATE_PIPE_EVT;
+            break;
+
+        case NFA_HCI_ADM_DELETE_PIPE:
+            /*
+             * As no response to the command sent on this pipe, we may assume the pipe is
+             * deleted already. Just release the pipe.
+             */
+            if (nfa_hci_cb.pipe_in_use <= NFA_HCI_LAST_DYNAMIC_PIPE)
+                nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
+            evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
+            evt                   = NFA_HCI_DELETE_PIPE_EVT;
+            break;
+
+        default:
+            /*
+             * As no response to the command sent on this pipe, we may assume the pipe is
+             * deleted already and release the pipe. But still send delete pipe command to be safe.
+             */
+            delete_pipe                = nfa_hci_cb.pipe_in_use;
+            break;
+        }
+        if (delete_pipe && (delete_pipe <= NFA_HCI_LAST_DYNAMIC_PIPE))
+        {
+            nfa_hciu_send_delete_pipe_cmd (delete_pipe);
+            nfa_hciu_release_pipe (delete_pipe);
+        }
+        break;
+    case NFA_HCI_STATE_DISABLED:
+    default:
+        NFA_TRACE_DEBUG0 ("nfa_hci_rsp_timeout () Timeout in DISABLED/ Invalid state");
+        break;
+    }
+    if (evt != 0)
+        nfa_hciu_send_to_app (evt, &evt_data, nfa_hci_cb.app_in_use);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_set_receive_buf
+**
+** Description      Set reassembly buffer for incoming message
+**
+** Returns          status
+**
+*******************************************************************************/
+static void nfa_hci_set_receive_buf (UINT8 pipe)
+{
+    if (  (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+        &&(nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)  )
+    {
+        if (  (nfa_hci_cb.rsp_buf_size)
+            &&(nfa_hci_cb.p_rsp_buf != NULL)  )
+        {
+            nfa_hci_cb.p_msg_data  = nfa_hci_cb.p_rsp_buf;
+            nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
+            return;
+        }
+    }
+    nfa_hci_cb.p_msg_data  = nfa_hci_cb.msg_data;
+    nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_assemble_msg
+**
+** Description      Reassemble the incoming message
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_hci_assemble_msg (UINT8 *p_data, UINT16 data_len)
+{
+    if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len)
+    {
+        /* Fill the buffer as much it can hold */
+        memcpy (&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
+        nfa_hci_cb.msg_len         = nfa_hci_cb.max_msg_len;
+        /* Set Reassembly failed */
+        nfa_hci_cb.assembly_failed = TRUE;
+        NFA_TRACE_ERROR1 ("nfa_hci_assemble_msg (): Insufficient buffer to Reassemble HCP packet! Dropping :%u bytes", ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
+    }
+    else
+    {
+        memcpy (&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
+        nfa_hci_cb.msg_len += data_len;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hci_evt_hdlr
+**
+** Description      Processing all event for NFA HCI
+**
+** Returns          TRUE if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static BOOLEAN nfa_hci_evt_hdlr (BT_HDR *p_msg)
+{
+    tNFA_HCI_EVENT_DATA *p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_EVENT4 ("nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)",
+                      nfa_hciu_get_state_name (nfa_hci_cb.hci_state), nfa_hci_cb.hci_state,
+                      nfa_hciu_get_event_name (p_evt_data->hdr.event), p_evt_data->hdr.event);
+#else
+    NFA_TRACE_EVENT2 ("nfa_hci_evt_hdlr state: %d event: 0x%04x", nfa_hci_cb.hci_state, p_evt_data->hdr.event);
+#endif
+
+    /* If this is an API request, queue it up */
+    if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) && (p_msg->event <= NFA_HCI_LAST_API_EVENT))
+    {
+        GKI_enqueue (&nfa_hci_cb.hci_api_q, p_msg);
+    }
+    else
+    {
+        switch (p_msg->event)
+        {
+        case NFA_HCI_RSP_NV_READ_EVT:
+            nfa_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status);
+            break;
+
+        case NFA_HCI_RSP_NV_WRITE_EVT:
+            /* NV Ram write completed - nothing to do... */
+            break;
+
+        case NFA_HCI_RSP_TIMEOUT_EVT:
+            nfa_hci_rsp_timeout ((tNFA_HCI_EVENT_DATA *)p_msg);
+            break;
+
+        case NFA_HCI_CHECK_QUEUE_EVT:
+            if (HCI_LOOPBACK_DEBUG)
+            {
+                if (p_msg->len != 0)
+                {
+                    tNFC_DATA_CEVT   xx;
+                    xx.p_data = p_msg;
+                    nfa_hci_conn_cback (0, NFC_DATA_CEVT, (tNFC_CONN *)&xx);
+                    return FALSE;
+                }
+            }
+            break;
+        }
+    }
+
+    if ((p_msg->event > NFA_HCI_LAST_API_EVENT))
+        GKI_freebuf (p_msg);
+
+    nfa_hci_check_api_requests ();
+
+    if (nfa_hciu_is_no_host_resetting ())
+        nfa_hci_check_pending_api_requests ();
+
+    if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) && (nfa_hci_cb.nv_write_needed))
+    {
+        nfa_hci_cb.nv_write_needed = FALSE;
+        nfa_nv_co_write ((UINT8 *)&nfa_hci_cb.cfg, sizeof (nfa_hci_cb.cfg),DH_NV_BLOCK);
+    }
+
+    return FALSE;
+}
+
diff --git a/src/nfa/hci/nfa_hci_utils.c b/src/nfa/hci/nfa_hci_utils.c
new file mode 100644
index 0000000..6edf589
--- /dev/null
+++ b/src/nfa/hci/nfa_hci_utils.c
@@ -0,0 +1,1440 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the utility functions for the NFA HCI.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "trace_api.h"
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_hci_api.h"
+#include "nfa_hci_int.h"
+#include "nfa_nv_co.h"
+#include "nfa_mem_co.h"
+#include "nfa_hci_defs.h"
+
+static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction);
+BOOLEAN HCI_LOOPBACK_DEBUG = FALSE;
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_pipe_by_pid
+**
+** Description      look for the pipe control block based on pipe id
+**
+** Returns          pointer to the pipe control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id)
+{
+    tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
+    int                 xx  = 0;
+
+    /* Loop through looking for a match */
+    for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (pp->pipe_id == pipe_id)
+            return (pp);
+    }
+
+    /* If here, not found */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_gate_by_gid
+**
+** Description      Find the gate control block for the given gate id
+**
+** Returns          pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id)
+{
+    tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+    int               xx  = 0;
+
+    for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+    {
+        if (pg->gate_id == gate_id)
+            return (pg);
+    }
+
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_gate_by_owner
+**
+** Description      Find the the first gate control block for the given owner
+**
+** Returns          pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle)
+{
+    tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+    int               xx  = 0;
+
+    for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+    {
+        if (pg->gate_owner == app_handle)
+            return (pg);
+    }
+
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_gate_with_nopipes_by_owner
+**
+** Description      Find the the first gate control block with no pipes
+**                  for the given owner
+**
+** Returns          pointer to the gate control block, or NULL if not found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle)
+{
+    tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
+    int               xx  = 0;
+
+    for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+    {
+        if (  (pg->gate_owner    == app_handle)
+            &&(pg->pipe_inx_mask == 0)  )
+            return (pg);
+    }
+
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_count_pipes_on_gate
+**
+** Description      Count the number of pipes on the given gate
+**
+** Returns          the number of pipes on the gate
+**
+*******************************************************************************/
+UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
+{
+    int               xx    = 0;
+    UINT32            mask  = 1;
+    UINT8             count = 0;
+
+    for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++)
+    {
+        if ( p_gate->pipe_inx_mask & mask )
+            count++;
+
+        mask = mask << 1;
+    }
+
+    return (count);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_count_open_pipes_on_gate
+**
+** Description      Count the number of opened pipes on the given gate
+**
+** Returns          the number of pipes in OPENED state on the gate
+**
+*******************************************************************************/
+UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
+{
+    tNFA_HCI_DYN_PIPE *pp   = nfa_hci_cb.cfg.dyn_pipes;
+    int               xx    = 0;
+    UINT32            mask  = 1;
+    UINT8             count = 0;
+
+    for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        /* For each pipe on this gate, check if it is open */
+        if ((p_gate->pipe_inx_mask & mask) && (pp->pipe_state == NFA_HCI_PIPE_OPENED))
+            count++;
+
+        mask = mask << 1;
+    }
+
+    return (count);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_gate_owner
+**
+** Description      Find the application that owns a gate
+**
+** Returns          application handle
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+
+    if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) == NULL)
+        return (NFA_HANDLE_INVALID);
+
+    return (pg->gate_owner);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_pipe_owner
+**
+** Description      Find the application that owns a pipe
+**
+** Returns          application handle
+**
+*******************************************************************************/
+tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id)
+{
+    tNFA_HCI_DYN_PIPE   *pp;
+    tNFA_HCI_DYN_GATE   *pg;
+
+    if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
+        return (NFA_HANDLE_INVALID);
+
+    if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) == NULL)
+        return (NFA_HANDLE_INVALID);
+
+    return (pg->gate_owner);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_alloc_gate
+**
+** Description      Allocate an gate control block
+**
+** Returns          pointer to the allocated gate, or NULL if cannot allocate
+**
+*******************************************************************************/
+tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    int                 xx;
+    UINT8               app_inx = app_handle & NFA_HANDLE_MASK;
+
+
+    /* First, check if the application handle is valid */
+    if ((gate_id != NFA_HCI_CONNECTIVITY_GATE)
+                    &&
+        (  ((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI)
+         ||(app_inx >= NFA_HCI_MAX_APP_CB)
+         ||(nfa_hci_cb.p_app_cback[app_inx] == NULL)  ))
+    {
+        return (NULL);
+    }
+
+    if (gate_id != 0)
+    {
+        if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL)
+            return (pg);
+    }
+    else
+    {
+        /* If gate_id is 0, we need to assign a free one */
+        /* Loop through all possible gate IDs checking if they are already used */
+        for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id < NFA_HCI_LAST_PROP_GATE; gate_id++)
+        {
+            /* Skip connectivity gate */
+            if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++;
+
+            /* Check if the gate is already allocated */
+            for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+                if (pg->gate_id == gate_id)
+                    break;
+            /* If the gate is not allocated, use the gate */
+            if (xx == NFA_HCI_MAX_GATE_CB)
+                break;
+        }
+        if (gate_id == NFA_HCI_LAST_PROP_GATE)
+        {
+            NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u  App Handle: 0x%04x", gate_id, app_handle);
+            return (NULL);
+        }
+    }
+
+    /* Now look for a free control block */
+    for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
+    {
+        if (pg->gate_id == 0)
+        {
+            /* Found a free gate control block */
+            pg->gate_id       = gate_id;
+            pg->gate_owner    = app_handle;
+            pg->pipe_inx_mask = 0;
+
+            NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d  app_handle: 0x%04x", gate_id, app_handle);
+
+            nfa_hci_cb.nv_write_needed = TRUE;
+            return (pg);
+        }
+    }
+
+    /* If here, no free gate control block */
+    NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB  Gate ID: %u  App Handle: 0x%04x", gate_id, app_handle);
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_msg
+**
+** Description      This function will fragment the given packet, if necessary
+**                  and send it on the given pipe.
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg)
+{
+    BT_HDR          *p_buf;
+    UINT8           *p_data;
+    BOOLEAN          first_pkt = TRUE;
+    UINT16          data_len;
+    tNFA_STATUS     status = NFA_STATUS_OK;
+    UINT16          max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_DEBUG3 ("nfa_hciu_send_msg pipe_id:%d   %s  len:%d",
+                      pipe_id, nfa_hciu_get_type_inst_names (pipe_id, type, instruction), msg_len);
+#else
+    NFA_TRACE_DEBUG4 ("nfa_hciu_send_msg pipe_id:%d   Type: %u  Inst: %u  len: %d",
+                      pipe_id, type, instruction, msg_len);
+#endif
+
+    if (instruction == NFA_HCI_ANY_GET_PARAMETER)
+        nfa_hci_cb.param_in_use = *p_msg;
+
+    while ((first_pkt == TRUE) || (msg_len != 0))
+    {
+        if ((p_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+        {
+            p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+            /* First packet has a 2-byte header, subsequent fragments have a 1-byte header */
+            data_len = first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1);
+
+            p_data = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+            /* Last or only segment has "no fragmentation" bit set */
+            if (msg_len > data_len)
+            {
+                *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
+            }
+            else
+            {
+                data_len = msg_len;
+                *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
+            }
+
+            p_buf->len = 1;
+
+            /* Message header only goes in the first segment */
+            if (first_pkt)
+            {
+                first_pkt = FALSE;
+                *p_data++ = (type << 6) | instruction;
+                p_buf->len++;
+            }
+
+            if (data_len != 0)
+            {
+                memcpy (p_data, p_msg, data_len);
+
+                p_buf->len += data_len;
+                msg_len    -= data_len;
+                if (msg_len > 0)
+                    p_msg      += data_len;
+            }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+            DispHcp (((UINT8 *) (p_buf + 1) + p_buf->offset), p_buf->len, FALSE, (BOOLEAN) ((p_buf->len - data_len) == 2));
+#endif
+
+            if (HCI_LOOPBACK_DEBUG)
+                handle_debug_loopback (p_buf, pipe_id, type, instruction);
+            else
+                status = NFC_SendData (nfa_hci_cb.conn_id, p_buf);
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_hciu_send_data_packet no buffers");
+            status = NFA_STATUS_NO_BUFFERS;
+            break;
+        }
+    }
+
+    /* Start timer if response to wait for a particular time for the response  */
+    if (type == NFA_HCI_COMMAND_TYPE)
+    {
+        nfa_hci_cb.cmd_sent = instruction;
+
+        if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
+            nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
+
+        nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, NFA_HCI_CMD_RSP_TIMEOUT);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_allocated_gate_list
+**
+** Description      fills in a list of allocated gates
+**
+** Returns          the number of gates
+**
+*******************************************************************************/
+UINT8 nfa_hciu_get_allocated_gate_list (UINT8 *p_gate_list)
+{
+    tNFA_HCI_DYN_GATE   *p_cb;
+    int                 xx;
+    UINT8               count = 0;
+
+    for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx <= NFA_HCI_MAX_GATE_CB; xx++, p_cb++)
+    {
+        if (p_cb->gate_id != 0)
+        {
+            *p_gate_list++ = p_cb->gate_id;
+            count++;
+        }
+    }
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_get_allocated_gate_list () returns: %u", count);
+
+    return (count);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_alloc_pipe
+**
+** Description      Allocate a pipe control block
+**
+** Returns          pointer to the pipe control block, or NULL if
+**                  cannot allocate
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_alloc_pipe (UINT8 pipe_id)
+{
+    UINT8               xx;
+    tNFA_HCI_DYN_PIPE   *pp;
+
+    /* If we already have a pipe of the same ID, release it first it */
+    if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL)
+    {
+        if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)
+            return pp;
+        nfa_hciu_release_pipe (pipe_id);
+    }
+
+    /* Look for a free pipe control block */
+    for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (pp->pipe_id == 0)
+        {
+            NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx);
+            pp->pipe_id = pipe_id;
+
+            nfa_hci_cb.nv_write_needed = TRUE;
+            return (pp);
+        }
+    }
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id);
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_release_gate
+**
+** Description      Remove a generic gate from gate list
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_release_gate (UINT8 gate_id)
+{
+    tNFA_HCI_DYN_GATE   *p_gate = nfa_hciu_find_gate_by_gid (gate_id);
+
+    if (p_gate != NULL)
+    {
+        NFA_TRACE_DEBUG3 ("nfa_hciu_release_gate () ID: %d  owner: 0x%04x  pipe_inx_mask: 0x%04x",
+                          gate_id, p_gate->gate_owner, p_gate->pipe_inx_mask);
+
+        p_gate->gate_id       = 0;
+        p_gate->gate_owner    = 0;
+        p_gate->pipe_inx_mask = 0;
+
+        nfa_hci_cb.nv_write_needed = TRUE;
+    }
+    else
+    {
+        NFA_TRACE_WARNING1 ("nfa_hciu_release_gate () ID: %d  NOT FOUND", gate_id);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_add_pipe_to_gate
+**
+** Description      Add pipe to generic gate
+**
+** Returns          NFA_STATUS_OK, if successfully add the pipe on to the gate
+**                  NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate (UINT8 pipe_id,   UINT8 local_gate,
+                                             UINT8 dest_host, UINT8 dest_gate)
+{
+    tNFA_HCI_DYN_GATE   *p_gate;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    UINT8               pipe_index;
+
+    p_gate = nfa_hciu_find_gate_by_gid (local_gate);
+
+    if (p_gate != NULL)
+    {
+        /* Allocate a pipe control block */
+        if ((p_pipe = nfa_hciu_alloc_pipe (pipe_id)) != NULL)
+        {
+            p_pipe->pipe_id     = pipe_id;
+            p_pipe->pipe_state  = NFA_HCI_PIPE_CLOSED;
+            p_pipe->dest_host   = dest_host;
+            p_pipe->dest_gate   = dest_gate;
+            p_pipe->local_gate  = local_gate;
+
+            /* Save the pipe in the gate that it belongs to */
+            pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+            p_gate->pipe_inx_mask |= (UINT32) (1 << pipe_index);
+
+            NFA_TRACE_DEBUG4 ("nfa_hciu_add_pipe_to_gate  Gate ID: 0x%02x  Pipe ID: 0x%02x  pipe_index: %u  App Handle: 0x%08x",
+                              local_gate, pipe_id, pipe_index, p_gate->gate_owner);
+            return (NFA_HCI_ANY_OK);
+        }
+    }
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_add_pipe_to_gate: 0x%02x  NOT FOUND", local_gate);
+
+    return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_add_pipe_to_static_gate
+**
+** Description      Add pipe to identity management gate
+**
+** Returns          NFA_HCI_ANY_OK, if successfully add the pipe on to the gate
+**                  NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate (UINT8 local_gate, UINT8 pipe_id, UINT8 dest_host, UINT8 dest_gate)
+{
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    UINT8               pipe_index;
+
+    NFA_TRACE_EVENT4 ("nfa_hciu_add_pipe_to_static_gate (%u)  Pipe: 0x%02x  Dest Host: 0x%02x  Dest Gate: 0x%02x)",
+                      local_gate, pipe_id, dest_host, dest_gate);
+
+    /* Allocate a pipe control block */
+    if ((p_pipe = nfa_hciu_alloc_pipe (pipe_id)) != NULL)
+    {
+        p_pipe->pipe_id     = pipe_id;
+        p_pipe->pipe_state  = NFA_HCI_PIPE_CLOSED;
+        p_pipe->dest_host   = dest_host;
+        p_pipe->dest_gate   = dest_gate;
+        p_pipe->local_gate  = local_gate;
+
+        /* If this is the ID gate, save the pipe index in the ID gate info     */
+        /* block. Note that for loopback, it is enough to just create the pipe */
+        if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+        {
+            pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+            nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask  |= (UINT32) (1 << pipe_index);
+        }
+        return NFA_HCI_ANY_OK;
+    }
+
+    return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_active_pipe_by_owner
+**
+** Description      Find the first pipe associated with the given app
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_by_owner (tNFA_HANDLE app_handle)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    tNFA_HCI_DYN_PIPE   *pp;
+    int                 xx;
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle);
+
+    /* Loop through all pipes looking for the owner */
+    for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (  (pp->pipe_id != 0)
+            &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+            &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE)
+            &&(nfa_hciu_is_active_host (pp->dest_host))  )
+        {
+            if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+                &&(pg->gate_owner == app_handle) )
+                return (pp);
+        }
+    }
+
+    /* If here, not found */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_pipe_by_owner
+**
+** Description      Find the first pipe associated with the given app
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_owner (tNFA_HANDLE app_handle)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    tNFA_HCI_DYN_PIPE   *pp;
+    int                 xx;
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle);
+
+    /* Loop through all pipes looking for the owner */
+    for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (pp->pipe_id != 0)
+        {
+            if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+                &&(pg->gate_owner == app_handle) )
+                return (pp);
+        }
+    }
+
+    /* If here, not found */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_pipe_on_gate
+**
+** Description      Find the first pipe associated with the given gate
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_on_gate (UINT8 gate_id)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    tNFA_HCI_DYN_PIPE   *pp;
+    int                 xx;
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_on_gate () Gate:0x%x", gate_id);
+
+    /* Loop through all pipes looking for the owner */
+    for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (pp->pipe_id != 0)
+        {
+            if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+                &&(pg->gate_id == gate_id) )
+                return (pp);
+        }
+    }
+
+    /* If here, not found */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_is_active_host
+**
+** Description      Check if the host is currently active
+**
+** Returns          TRUE, if the host is active in the host network
+**                  FALSE, if the host is not active in the host network
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_is_active_host (UINT8 host_id)
+{
+    UINT8   xx;
+
+    for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+    {
+        if (nfa_hci_cb.inactive_host[xx] == host_id)
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_is_host_reseting
+**
+** Description      Check if the host is currently reseting
+**
+** Returns          TRUE, if the host is reseting
+**                  FALSE, if the host is not reseting
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_is_host_reseting (UINT8 host_id)
+{
+    UINT8   xx;
+
+    for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+    {
+        if (nfa_hci_cb.reset_host[xx] == host_id)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_is_no_host_resetting
+**
+** Description      Check if no host is reseting
+**
+** Returns          TRUE, if no host is resetting at this time
+**                  FALSE, if one or more host is resetting
+**
+*******************************************************************************/
+BOOLEAN nfa_hciu_is_no_host_resetting (void)
+{
+    UINT8   xx;
+
+    for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
+    {
+        if (nfa_hci_cb.reset_host[xx] != 0)
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_find_active_pipe_on_gate
+**
+** Description      Find the first active pipe associated with the given gate
+**
+** Returns          pointer to pipe, or NULL if none found
+**
+*******************************************************************************/
+tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    tNFA_HCI_DYN_PIPE   *pp;
+    int                 xx;
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_find_active_pipe_on_gate () Gate:0x%x", gate_id);
+
+    /* Loop through all pipes looking for the owner */
+    for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (  (pp->pipe_id != 0)
+            &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE)
+            &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE)
+            &&(nfa_hciu_is_active_host (pp->dest_host))  )
+        {
+            if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+                &&(pg->gate_id == gate_id) )
+                return (pp);
+        }
+    }
+
+    /* If here, not found */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_release_pipe
+**
+** Description      remove the specified pipe
+**
+** Returns          NFA_HCI_ANY_OK, if removed
+**                  NFA_HCI_ANY_E_NOK, if otherwise
+**
+*******************************************************************************/
+tNFA_HCI_RESPONSE nfa_hciu_release_pipe (UINT8 pipe_id)
+{
+    tNFA_HCI_DYN_GATE   *p_gate;
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+    UINT8               pipe_index;
+
+    NFA_TRACE_EVENT1 ("nfa_hciu_release_pipe: %u", pipe_id);
+
+    if ((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
+        return (NFA_HCI_ANY_E_NOK);
+
+    if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe_id);
+        return (NFA_HCI_ANY_E_NOK);
+    }
+
+    pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
+
+    if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
+    {
+        /* Remove pipe from ID management gate */
+        nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
+    }
+    else
+    {
+        if ((p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate)) == NULL)
+        {
+            /* Mark the pipe control block as free */
+            p_pipe->pipe_id = 0;
+            return (NFA_HCI_ANY_E_NOK);
+        }
+
+        /* Remove pipe from gate */
+        p_gate->pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
+    }
+
+    /* Reset pipe control block */
+    memset (p_pipe,0,sizeof (tNFA_HCI_DYN_PIPE));
+    nfa_hci_cb.nv_write_needed = TRUE;
+    return NFA_HCI_ANY_OK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_remove_all_pipes_from_host
+**
+** Description      remove all the pipes that are connected to a specific host
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_hciu_remove_all_pipes_from_host (UINT8 host)
+{
+    tNFA_HCI_DYN_GATE   *pg;
+    tNFA_HCI_DYN_PIPE   *pp;
+    int                 xx;
+    tNFA_HCI_EVT_DATA   evt_data;
+
+    NFA_TRACE_EVENT1 ("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
+
+    /* Remove all pipes from the specified host connected to all generic gates */
+    for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
+    {
+        if (  (pp->pipe_id == 0)
+                    ||
+              (  (host != 0)
+               &&((pp->dest_host != host) || (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)))  )
+            continue;
+
+        if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
+        {
+            evt_data.deleted.status = NFA_STATUS_OK;
+            evt_data.deleted.pipe   = pp->pipe_id;
+
+            nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
+        }
+        nfa_hciu_release_pipe (pp->pipe_id);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_create_pipe_cmd
+**
+** Description      Create dynamic pipe between the specified gates
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate)
+{
+    tNFA_STATUS         status;
+    UINT8               data[3];
+
+    data[0] = source_gate;
+    data[1] = dest_host;
+    data[2] = dest_gate;
+
+    NFA_TRACE_DEBUG3 ("nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, dest_gate:%d", source_gate, dest_host, dest_gate);
+
+    status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CREATE_PIPE, 3, data);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_delete_pipe_cmd
+**
+** Description      Delete the dynamic pipe
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe)
+{
+    tNFA_STATUS status;
+
+    NFA_TRACE_DEBUG1 ("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
+
+    if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)
+    {
+        NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe);
+        return (NFA_HCI_ANY_E_NOK);
+    }
+    nfa_hci_cb.pipe_in_use = pipe;
+
+    status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_clear_all_pipe_cmd
+**
+** Description      delete all the dynamic pipe connected to device host,
+**                  to close all static pipes connected to device host,
+**                  and to set registry values related to static pipes to
+**                  theri default values.
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void)
+{
+    tNFA_STATUS status;
+    UINT16      id_ref_data = 0x0102;
+
+    NFA_TRACE_DEBUG0 ("nfa_hciu_send_clear_all_pipe_cmd");
+
+    status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (UINT8 *) &id_ref_data);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_open_pipe_cmd
+**
+** Description      Open a closed pipe
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe)
+{
+    tNFA_STATUS status;
+
+    nfa_hci_cb.pipe_in_use = pipe;
+
+    status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE, 0, NULL);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_close_pipe_cmd
+**
+** Description      Close an opened pipe
+**
+** Returns          status
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe)
+{
+    tNFA_STATUS status;
+
+    nfa_hci_cb.pipe_in_use = pipe;
+
+    status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE, 0, NULL);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_get_param_cmd
+**
+** Description      Read a parameter value from gate registry
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index)
+{
+    tNFA_STATUS status;
+
+    if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_GET_PARAMETER, 1, &index)) == NFC_STATUS_OK)
+        nfa_hci_cb.param_in_use = index;
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_set_param_cmd
+**
+** Description      Set a parameter value in a gate registry
+**
+** Returns          None
+**
+*******************************************************************************/
+tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data)
+{
+    tNFA_STATUS status;
+    UINT8       data[255];
+
+    data[0] = index;
+
+    memcpy (&data[1], p_data, length);
+
+    if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER, (UINT16) (length + 1), data)) == NFC_STATUS_OK)
+        nfa_hci_cb.param_in_use = index;
+
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_to_app
+**
+** Description      Send an event back to an application
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle)
+{
+    UINT8   app_inx = app_handle & NFA_HANDLE_MASK;
+
+    /* First, check if the application handle is valid */
+    if (  ((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI)
+        &&(app_inx < NFA_HCI_MAX_APP_CB) )
+    {
+        if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+        {
+            nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
+            return;
+        }
+    }
+
+    if (app_handle != NFA_HANDLE_INVALID)
+    {
+        NFA_TRACE_WARNING2 ("nfa_hciu_send_to_app no callback,  event: 0x%04x  app_handle: 0x%04x",
+                            event, app_handle);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_to_all_apps
+**
+** Description      Send an event back to all applications
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
+{
+    UINT8   app_inx;
+
+    for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
+    {
+        if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+            nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_send_to_apps_handling_connectivity_evts
+**
+** Description      Send a connectivity event to all the application interested
+**                  in connectivity events
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
+{
+    UINT8   app_inx;
+
+    for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
+    {
+        if (  (nfa_hci_cb.p_app_cback[app_inx] != NULL)
+            &&(nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
+
+            nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
+    }
+
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_response_name
+**
+** Description      This function returns the error code name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_get_response_name (UINT8 rsp_code)
+{
+    static char unknown[50];
+
+    switch (rsp_code)
+    {
+    case NFA_HCI_ANY_OK:
+        return ("ANY_OK");
+    case NFA_HCI_ANY_E_NOT_CONNECTED:
+        return ("ANY_E_NOT_CONNECTED");
+    case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
+        return ("ANY_E_CMD_PAR_UNKNOWN");
+    case NFA_HCI_ANY_E_NOK:
+        return ("ANY_E_NOK");
+    case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
+        return ("ADM_E_NO_PIPES_AVAILABLE");
+    case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
+        return ("ANY_E_REG_PAR_UNKNOWN");
+    case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
+        return ("ANY_E_PIPE_NOT_OPENED");
+    case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
+        return ("ANY_E_CMD_NOT_SUPPORTED");
+    case NFA_HCI_ANY_E_INHIBITED:
+        return ("ANY_E_INHIBITED");
+    case NFA_HCI_ANY_E_TIMEOUT:
+        return ("ANY_E_TIMEOUT");
+    case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
+        return ("ANY_E_REG_ACCESS_DENIED");
+    case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
+        return ("ANY_E_PIPE_ACCESS_DENIED");
+    default:
+        sprintf (unknown, "?? Unknown: %u ?? ", rsp_code);
+        return (unknown);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_type_2_str
+**
+** Description      This function returns the type name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_type_2_str(UINT8 type)
+{
+    static char unknown[40];
+
+    switch (type)
+    {
+    case NFA_HCI_COMMAND_TYPE:
+        return ("COMMAND");
+    case NFA_HCI_EVENT_TYPE:
+        return ("EVENT");
+    case NFA_HCI_RESPONSE_TYPE:
+        return ("RESPONSE");
+    default:
+        sprintf (unknown, "?? Unknown: %u ?? ", type);
+        return (unknown);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_instr_2_str
+**
+** Description      This function returns the instruction name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_instr_2_str (UINT8 instruction)
+{
+    static char unknown[40];
+
+    switch (instruction)
+    {
+    case NFA_HCI_ANY_SET_PARAMETER:
+        return ("ANY_SET_PARAMETER");
+    case NFA_HCI_ANY_GET_PARAMETER:
+        return ("ANY_GET_PARAMETER");
+    case NFA_HCI_ANY_OPEN_PIPE:
+        return ("ANY_OPEN_PIPE");
+    case NFA_HCI_ANY_CLOSE_PIPE:
+        return ("ANY_CLOSE_PIPE");
+    case NFA_HCI_ADM_CREATE_PIPE:
+        return ("ADM_CREATE_PIPE");
+    case NFA_HCI_ADM_DELETE_PIPE:
+        return ("ADM_DELETE_PIPE");
+    case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
+        return ("ADM_NOTIFY_PIPE_CREATED");
+    case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
+        return ("ADM_NOTIFY_PIPE_DELETED");
+    case NFA_HCI_ADM_CLEAR_ALL_PIPE:
+        return ("ADM_CLEAR_ALL_PIPE");
+    case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
+        return ("ADM_NOTIFY_ALL_PIPE_CLEARED");
+    default:
+        sprintf (unknown, "?? Unknown: %u ?? ", instruction);
+        return (unknown);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_event_name
+**
+** Description      This function returns the event code name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_get_event_name (UINT16 event)
+{
+    static char unknown[40];
+
+    switch (event)
+    {
+    case NFA_HCI_API_REGISTER_APP_EVT:        return ("API_REGISTER");
+    case NFA_HCI_API_DEREGISTER_APP_EVT:      return ("API_DEREGISTER");
+    case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:   return ("API_GET_GATE_LIST");
+    case NFA_HCI_API_ALLOC_GATE_EVT:          return ("API_ALLOC_GATE");
+    case NFA_HCI_API_DEALLOC_GATE_EVT:        return ("API_DEALLOC_GATE");
+    case NFA_HCI_API_GET_HOST_LIST_EVT:       return ("API_GET_HOST_LIST");
+    case NFA_HCI_API_GET_REGISTRY_EVT:        return ("API_GET_REG_VALUE");
+    case NFA_HCI_API_SET_REGISTRY_EVT:        return ("API_SET_REG_VALUE");
+    case NFA_HCI_API_CREATE_PIPE_EVT:         return ("API_CREATE_PIPE");
+    case NFA_HCI_API_OPEN_PIPE_EVT:           return ("API_OPEN_PIPE");
+    case NFA_HCI_API_CLOSE_PIPE_EVT:          return ("API_CLOSE_PIPE");
+    case NFA_HCI_API_DELETE_PIPE_EVT:         return ("API_DELETE_PIPE");
+    case NFA_HCI_API_SEND_CMD_EVT:            return ("API_SEND_COMMAND_EVT");
+    case NFA_HCI_API_SEND_RSP_EVT:            return ("API_SEND_RESPONSE_EVT");
+    case NFA_HCI_API_SEND_EVENT_EVT:          return ("API_SEND_EVENT_EVT");
+    case NFA_HCI_RSP_NV_READ_EVT:             return ("NV_READ_EVT");
+    case NFA_HCI_RSP_NV_WRITE_EVT:            return ("NV_WRITE_EVT");
+    case NFA_HCI_RSP_TIMEOUT_EVT:             return ("RESPONSE_TIMEOUT_EVT");
+    case NFA_HCI_CHECK_QUEUE_EVT:             return ("CHECK_QUEUE");
+
+    default:
+        sprintf (unknown, "?? Unknown: %u ?? ", event);
+        return (unknown);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_state_name
+**
+** Description      This function returns the state name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_get_state_name (UINT8 state)
+{
+    static char unknown[40];
+
+    switch (state)
+    {
+    case NFA_HCI_STATE_DISABLED:            return ("DISABLED");
+    case NFA_HCI_STATE_STARTUP:             return ("STARTUP");
+    case NFA_HCI_STATE_IDLE:                return ("IDLE");
+    case NFA_HCI_STATE_WAIT_RSP:            return ("WAIT_RSP");
+    case NFA_HCI_STATE_REMOVE_GATE:         return ("REMOVE_GATE");
+    case NFA_HCI_STATE_APP_DEREGISTER:      return ("APP_DEREGISTER");
+    case NFA_HCI_STATE_RESTORE:             return ("RESTORE");
+
+
+    default:
+        sprintf (unknown, "?? Unknown: %u ?? ", state);
+        return (unknown);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_get_type_inst_names
+**
+** Description      This function returns command/response/event name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_get_type_inst_names (UINT8 pipe, UINT8 type, UINT8 inst)
+{
+    static char buff[100];
+    int   xx;
+
+    xx = sprintf (buff, "Type: %s  ", nfa_hciu_type_2_str (type));
+
+    switch (type)
+    {
+    case NFA_HCI_COMMAND_TYPE:
+        sprintf (&buff[xx], "Inst: %s ", nfa_hciu_instr_2_str (inst));
+        break;
+    case NFA_HCI_EVENT_TYPE:
+        sprintf (&buff[xx], "Evt: %s ", nfa_hciu_evt_2_str (pipe, inst));
+        break;
+    case NFA_HCI_RESPONSE_TYPE:
+        sprintf (&buff[xx], "Resp: %s ", nfa_hciu_get_response_name (inst));
+        break;
+    default:
+        sprintf (&buff[xx], "Inst: %u ", inst);
+        break;
+    }
+    return (buff);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         nfa_hciu_instr_2_str
+**
+** Description      This function returns the instruction name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+char *nfa_hciu_evt_2_str (UINT8 pipe_id, UINT8 evt)
+{
+    static char         unknown[40];
+    tNFA_HCI_DYN_PIPE   *p_pipe;
+
+    if (  (pipe_id != NFA_HCI_ADMIN_PIPE)
+        &&(pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE)
+        &&((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL)  )
+    {
+        if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
+        {
+            switch (evt)
+            {
+            case NFA_HCI_EVT_CONNECTIVITY:
+                return ("EVT_CONNECTIVITY");
+            case NFA_HCI_EVT_TRANSACTION:
+                return ("EVT_TRANSACTION");
+            case NFA_HCI_EVT_OPERATION_ENDED:
+                return ("EVT_OPERATION_ENDED");
+            default:
+                break;
+            }
+        }
+    }
+
+    switch (evt)
+    {
+    case NFA_HCI_EVT_HCI_END_OF_OPERATION:
+        return ("EVT_END_OF_OPERATION");
+    case NFA_HCI_EVT_POST_DATA:
+        return ("EVT_POST_DATA");
+    case NFA_HCI_EVT_HOT_PLUG:
+        return ("EVT_HOT_PLUG");
+    default:
+        sprintf (unknown, "?? Unknown: %u ?? ", evt);
+        return (unknown);
+    }
+}
+#endif
+
+
+static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction)
+{
+    UINT8 *p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+    static UINT8  next_pipe = 0x10;
+
+    if (type == NFA_HCI_COMMAND_TYPE)
+    {
+        switch (instruction)
+        {
+        case NFA_HCI_ADM_CREATE_PIPE:
+            p[6] = next_pipe++;
+            p[5] = p[4];
+            p[4] = p[3];
+            p[3] = p[2];
+            p[2] = 3;
+            p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+            p_buf->len = p_buf->offset + 7;
+            break;
+
+        case NFA_HCI_ANY_GET_PARAMETER:
+            p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+            memcpy (&p[2], (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, NFA_HCI_SESSION_ID_LEN);
+            p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
+            break;
+
+        default:
+            p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
+            p_buf->len = p_buf->offset + 2;
+            break;
+        }
+    }
+    else if (type == NFA_HCI_RESPONSE_TYPE)
+    {
+        GKI_freebuf (p_buf);
+        return;
+    }
+
+    p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
+    nfa_sys_sendmsg (p_buf);
+}
+
diff --git a/src/nfa/include/nfa_api.h b/src/nfa/include/nfa_api.h
new file mode 100644
index 0000000..26007e4
--- /dev/null
+++ b/src/nfa/include/nfa_api.h
@@ -0,0 +1,1126 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA, Broadcom's NFC application
+ *  layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_API_H
+#define NFA_API_H
+
+#include "nfc_target.h"
+#include "nci_defs.h"
+#include "tags_defs.h"
+#include "nfc_api.h"
+#include "nfc_hal_api.h"
+#include "gki.h"
+
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Max length of Appliction ID in 7816-4 */
+#define NFA_MAX_AID_LEN     NFC_MAX_AID_LEN
+#define NFA_MIN_AID_LEN     5 /* per NCI specification */
+
+/* NFA API return status codes */
+#define NFA_STATUS_OK                   NCI_STATUS_OK                   /* Command succeeded    */
+#define NFA_STATUS_REJECTED             NCI_STATUS_REJECTED             /* Command is rejected. */
+#define NFA_STATUS_MSG_CORRUPTED        NCI_STATUS_MESSAGE_CORRUPTED    /* Message is corrupted */
+#define NFA_STATUS_BUFFER_FULL          NCI_STATUS_BUFFER_FULL          /* buffer full          */
+#define NFA_STATUS_FAILED               NCI_STATUS_FAILED               /* failed               */
+#define NFA_STATUS_NOT_INITIALIZED      NCI_STATUS_NOT_INITIALIZED      /* not initialized      */
+#define NFA_STATUS_SYNTAX_ERROR         NCI_STATUS_SYNTAX_ERROR         /* Syntax error         */
+#define NFA_STATUS_SEMANTIC_ERROR       NCI_STATUS_SEMANTIC_ERROR       /* Semantic error       */
+#define NFA_STATUS_UNKNOWN_GID          NCI_STATUS_UNKNOWN_GID          /* Unknown NCI Group ID */
+#define NFA_STATUS_UNKNOWN_OID          NCI_STATUS_UNKNOWN_OID          /* Unknown NCI Opcode   */
+#define NFA_STATUS_INVALID_PARAM        NCI_STATUS_INVALID_PARAM        /* Invalid Parameter    */
+#define NFA_STATUS_MSG_SIZE_TOO_BIG     NCI_STATUS_MSG_SIZE_TOO_BIG     /* Message size too big */
+#define NFA_STATUS_ALREADY_STARTED      NCI_STATUS_ALREADY_STARTED      /* Already started      */
+#define NFA_STATUS_ACTIVATION_FAILED    NCI_STATUS_ACTIVATION_FAILED    /* Activation Failed    */
+#define NFA_STATUS_TEAR_DOWN            NCI_STATUS_TEAR_DOWN            /* Tear Down Error      */
+#define NFA_STATUS_RF_TRANSMISSION_ERR  NCI_STATUS_RF_TRANSMISSION_ERR  /* RF transmission error*/
+#define NFA_STATUS_RF_PROTOCOL_ERR      NCI_STATUS_RF_PROTOCOL_ERR      /* RF protocol error    */
+#define NFA_STATUS_TIMEOUT              NCI_STATUS_TIMEOUT              /* RF Timeout           */
+#define NFA_STATUS_EE_INTF_ACTIVE_FAIL  NCI_STATUS_EE_INTF_ACTIVE_FAIL  /* EE Intf activate err */
+#define NFA_STATUS_EE_TRANSMISSION_ERR  NCI_STATUS_EE_TRANSMISSION_ERR  /* EE transmission error*/
+#define NFA_STATUS_EE_PROTOCOL_ERR      NCI_STATUS_EE_PROTOCOL_ERR      /* EE protocol error    */
+#define NFA_STATUS_EE_TIMEOUT           NCI_STATUS_EE_TIMEOUT           /* EE Timeout           */
+
+#define NFA_STATUS_CMD_STARTED          NFC_STATUS_CMD_STARTED    /* Command started successfully                     */
+#define NFA_STATUS_HW_TIMEOUT           NFC_STATUS_HW_TIMEOUT     /* NFCC Timeout in responding to an NCI command     */
+#define NFA_STATUS_CONTINUE             NFC_STATUS_CONTINUE       /* More NFA_CE_GET_ROUTING_REVT to follow           */
+#define NFA_STATUS_REFUSED              NFC_STATUS_REFUSED        /* API is called to perform illegal function        */
+#define NFA_STATUS_BAD_RESP             NFC_STATUS_BAD_RESP       /* Wrong format of R-APDU, CC file or NDEF file     */
+#define NFA_STATUS_CMD_NOT_CMPLTD       NFC_STATUS_CMD_NOT_CMPLTD /* 7816 Status Word is not command complete(0x9000) */
+#define NFA_STATUS_NO_BUFFERS           NFC_STATUS_NO_BUFFERS     /* Out of GKI buffers                               */
+#define NFA_STATUS_WRONG_PROTOCOL       NFC_STATUS_WRONG_PROTOCOL /* Protocol mismatch between API and activated one  */
+#define NFA_STATUS_BUSY                 NFC_STATUS_BUSY           /* Another Tag command is already in progress       */
+
+#define NFA_STATUS_BAD_LENGTH           NFC_STATUS_BAD_LENGTH     /* data len exceeds MIU                             */
+#define NFA_STATUS_BAD_HANDLE           NFC_STATUS_BAD_HANDLE     /* invalid handle                                   */
+#define NFA_STATUS_CONGESTED            NFC_STATUS_CONGESTED      /* congested                                        */
+typedef UINT8 tNFA_STATUS;
+
+/* Handle for NFA registrations and connections */
+typedef UINT16 tNFA_HANDLE;
+#define NFA_HANDLE_INVALID              (0xFFFF)
+/* NFA Handle definitions */
+
+/* The upper byte of NFA_HANDLE signifies the handle group */
+#define NFA_HANDLE_GROUP_CONNECTION     0x0100      /* Connection handles           */
+#define NFA_HANDLE_GROUP_NDEF_HANDLER   0x0200      /* NDEF Type Handler handles    */
+#define NFA_HANDLE_GROUP_CE             0x0300      /* DH Card Emulation handles    */
+#define NFA_HANDLE_GROUP_EE             0x0400      /* Handles to identify NFCEE    */
+#define NFA_HANDLE_GROUP_P2P            0x0500      /* P2P handles                  */
+#define NFA_HANDLE_GROUP_CHO            0x0600      /* Connection Handvoer handles  */
+#define NFA_HANDLE_GROUP_SNEP           0x0700      /* SNEP handles                 */
+#define NFA_HANDLE_GROUP_HCI            0x0800      /* HCI handles                  */
+#define NFA_HANDLE_GROUP_LOCAL_NDEF     0x0900      /* Local NDEF message handle    */
+#define NFA_HANDLE_GROUP_MASK           0xFF00
+#define NFA_HANDLE_MASK                 0x00FF
+
+/* NCI Parameter IDs */
+typedef UINT8 tNFA_PMID;
+
+/* Definitions for tNFA_TECHNOLOGY_MASK */
+#define NFA_TECHNOLOGY_MASK_A	        0x01    /* NFC Technology A             */
+#define NFA_TECHNOLOGY_MASK_B	        0x02    /* NFC Technology B             */
+#define NFA_TECHNOLOGY_MASK_F	        0x04    /* NFC Technology F             */
+#define NFA_TECHNOLOGY_MASK_ISO15693	0x08    /* Proprietary Technology       */
+#define NFA_TECHNOLOGY_MASK_B_PRIME	    0x10    /* Proprietary Technology       */
+#define NFA_TECHNOLOGY_MASK_KOVIO	    0x20    /* Proprietary Technology       */
+#define NFA_TECHNOLOGY_MASK_A_ACTIVE    0x40    /* NFC Technology A active mode */
+#define NFA_TECHNOLOGY_MASK_F_ACTIVE    0x80    /* NFC Technology F active mode */
+#define NFA_TECHNOLOGY_MASK_ALL         0xFF    /* All supported technologies   */
+typedef UINT8 tNFA_TECHNOLOGY_MASK;
+
+/* Definitions for NFC protocol for RW, CE and P2P APIs */
+#define NFA_PROTOCOL_T1T        NFC_PROTOCOL_T1T        /* Type1Tag         - NFC-A             */
+#define NFA_PROTOCOL_T2T        NFC_PROTOCOL_T2T        /* MIFARE/Type2Tag  - NFC-A             */
+#define NFA_PROTOCOL_T3T        NFC_PROTOCOL_T3T        /* Felica/Type3Tag  - NFC-F             */
+#define NFA_PROTOCOL_ISO_DEP    NFC_PROTOCOL_ISO_DEP    /* Type 4A,4B       - NFC-A or NFC-B    */
+#define NFA_PROTOCOL_NFC_DEP    NFC_PROTOCOL_NFC_DEP    /* NFCDEP/LLCP      - NFC-A or NFC-F    */
+#define NFA_PROTOCOL_ISO15693   NFC_PROTOCOL_15693
+#define NFA_PROTOCOL_B_PRIME    NFC_PROTOCOL_B_PRIME
+#define NFA_PROTOCOL_KOVIO      NFC_PROTOCOL_KOVIO
+#define NFA_PROTOCOL_INVALID    0xFF
+#define NFA_MAX_NUM_PROTOCOLS   8
+typedef UINT8 tNFA_NFC_PROTOCOL;
+
+/* Definitions for tNFA_PROTOCOL_MASK */
+#define NFA_PROTOCOL_MASK_T1T       0x01    /* Type 1 tag          */
+#define NFA_PROTOCOL_MASK_T2T       0x02    /* MIFARE / Type 2 tag */
+#define NFA_PROTOCOL_MASK_T3T       0x04    /* FeliCa / Type 3 tag */
+#define NFA_PROTOCOL_MASK_ISO_DEP   0x08    /* ISODEP/4A,4B        */
+#define NFA_PROTOCOL_MASK_NFC_DEP   0x10    /* NFCDEP/LLCP         */
+typedef UINT8 tNFA_PROTOCOL_MASK;
+
+
+/* NFA_DM callback events */
+#define NFA_DM_ENABLE_EVT               0   /* Result of NFA_Enable             */
+#define NFA_DM_DISABLE_EVT              1   /* Result of NFA_Disable            */
+#define NFA_DM_SET_CONFIG_EVT           2   /* Result of NFA_SetConfig          */
+#define NFA_DM_GET_CONFIG_EVT           3   /* Result of NFA_GetConfig          */
+#define NFA_DM_PWR_MODE_CHANGE_EVT      4   /* Result of NFA_PowerOffSleepMode  */
+#define NFA_DM_RF_FIELD_EVT	            5   /* Status of RF Field               */
+#define NFA_DM_NFCC_TIMEOUT_EVT         6   /* NFCC is not responding           */
+#define NFA_DM_NFCC_TRANSPORT_ERR_EVT   7   /* NCI Tranport error               */
+
+#define NFA_DM_MAX_UICC                 2   /* Max number of UICC               */
+
+#define NFA_T1T_HR_LEN              T1T_HR_LEN      /* T1T HR length            */
+#define NFA_MAX_UID_LEN             TAG_MAX_UID_LEN /* Max UID length of T1/T2  */
+#define NFA_T1T_UID_LEN             T1T_UID_LEN     /* T1T UID length           */
+#define NFA_T1T_CMD_UID_LEN         T1T_CMD_UID_LEN /* UID len for T1T cmds     */
+#define NFA_T2T_UID_LEN             T2T_UID_LEN     /* T2T UID length           */
+
+/* Data for NFA_DM_SET_CONFIG_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;                     /* NFA_STATUS_OK if successful  */
+    UINT8           num_param_id;               /* Number of rejected Param ID  */
+    tNFA_PMID       param_ids[NFC_MAX_NUM_IDS]; /* Rejected Param ID            */
+} tNFA_SET_CONFIG;
+
+/* Data for NFA_DM_GET_CONFIG_EVT */
+typedef struct
+{
+    tNFA_STATUS status;     /* NFA_STATUS_OK if successful              */
+    UINT16 tlv_size;        /* The length of TLV                        */
+    UINT8 param_tlvs[1];    /* TLV (Parameter ID-Len-Value byte stream) */
+} tNFA_GET_CONFIG;
+
+#define NFA_DM_PWR_MODE_FULL        0x04
+#define NFA_DM_PWR_MODE_OFF_SLEEP   0x00
+
+typedef UINT8 tNFA_DM_PWR_MODE;
+
+/* Data for NFA_DM_PWR_MODE_CHANGE_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;        /* NFA_STATUS_OK if successful                       */
+    tNFA_DM_PWR_MODE    power_mode;    /* NFA_DM_PWR_MODE_FULL or NFA_DM_PWR_MODE_OFF_SLEEP */
+} tNFA_DM_PWR_MODE_CHANGE;
+
+/* Data for NFA_DM_RF_FIELD_EVT */
+#define NFA_DM_RF_FIELD_OFF     0x00
+#define NFA_DM_RF_FIELD_ON      0x01
+
+typedef struct
+{
+    tNFA_STATUS     status;         /* NFA_STATUS_OK if successful  */
+    UINT8           rf_field_status;/* NFA_DM_RF_FIELD_ON if operating field generated by remote */
+} tNFA_DM_RF_FIELD;
+
+/* Union of all DM callback structures */
+typedef union
+{
+    tNFA_STATUS             status;         /* NFA_DM_ENABLE_EVT        */
+    tNFA_SET_CONFIG         set_config;     /* NFA_DM_SET_CONFIG_EVT    */
+    tNFA_GET_CONFIG         get_config;     /* NFA_DM_GET_CONFIG_EVT    */
+    tNFA_DM_PWR_MODE_CHANGE power_mode;     /* NFA_DM_PWR_MODE_CHANGE_EVT   */
+    tNFA_DM_RF_FIELD        rf_field;       /* NFA_DM_RF_FIELD_EVT      */
+    void                    *p_vs_evt_data; /* Vendor-specific evt data */
+} tNFA_DM_CBACK_DATA;
+
+/* NFA_DM callback */
+typedef void (tNFA_DM_CBACK) (UINT8 event, tNFA_DM_CBACK_DATA *p_data);
+
+/* Data for data events */
+typedef struct
+{
+    tNFA_HANDLE handle;     /* Connection handle */
+    UINT16      len;        /* Length of data    */
+    UINT8       *p_buf;     /* Data buffer       */
+} tNFA_DATA;
+
+
+/* NFA Connection Callback Events */
+#define NFA_POLL_ENABLED_EVT                    0   /* Polling enabled event                        */
+#define NFA_POLL_DISABLED_EVT                   1   /* Polling disabled event                       */
+#define NFA_DISC_RESULT_EVT                     2   /* NFC link/protocol discovery notificaiton     */
+#define NFA_SELECT_RESULT_EVT                   3   /* NFC link/protocol discovery select response  */
+#define NFA_DEACTIVATE_FAIL_EVT                 4   /* NFA_Deactivate failure                       */
+#define NFA_ACTIVATED_EVT                       5   /* NFC link/protocol activated                  */
+#define NFA_DEACTIVATED_EVT                     6   /* NFC link/protocol deactivated                */
+#define NFA_TLV_DETECT_EVT                      7   /* TLV Detection complete                       */
+#define NFA_NDEF_DETECT_EVT                     8   /* NDEF Detection complete                      */
+#define NFA_DATA_EVT                            9   /* Data message received                        */
+#define NFA_SELECT_CPLT_EVT                     10  /* Select completed                             */
+#define NFA_READ_CPLT_EVT                       11  /* Read completed                               */
+#define NFA_WRITE_CPLT_EVT                      12  /* Write completed                              */
+#define NFA_LLCP_ACTIVATED_EVT                  13  /* LLCP link is activated                       */
+#define NFA_LLCP_DEACTIVATED_EVT                14  /* LLCP link is deactivated                     */
+#define NFA_PRESENCE_CHECK_EVT                  15  /* Response to NFA_RwPresenceCheck              */
+#define NFA_FORMAT_CPLT_EVT                     16  /* Tag Formating completed                      */
+#define NFA_I93_CMD_CPLT_EVT                    17  /* ISO 15693 command completed                  */
+#define NFA_SET_TAG_RO_EVT                      18  /* Tag set as Read only                         */
+#define NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT    19  /* Result for NFA_RequestExclusiveRfControl     */
+#define NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT    20  /* Result for NFA_ReleaseExclusiveRfControl     */
+#define NFA_CE_REGISTERED_EVT                   21  /* DH Card emulation: AID or System code reg'd  */
+#define NFA_CE_DEREGISTERED_EVT                 22  /* DH Card emulation: AID or System code dereg'd*/
+#define NFA_CE_DATA_EVT                         23  /* DH Card emulation: data received event       */
+#define NFA_CE_ACTIVATED_EVT                    24  /* DH Card emulation: activation event          */
+#define NFA_CE_DEACTIVATED_EVT                  25  /* DH Card emulation: deactivation event        */
+#define NFA_CE_LOCAL_TAG_CONFIGURED_EVT         26  /* DH Card emulation: local NDEF configured     */
+#define NFA_CE_NDEF_WRITE_START_EVT             27  /* DH Card emulation: NDEF write started        */
+#define NFA_CE_NDEF_WRITE_CPLT_EVT              28  /* DH Card emulation: NDEF write completed      */
+#define NFA_CE_UICC_LISTEN_CONFIGURED_EVT       29  /* UICC Listen configured                       */
+#define NFA_RF_DISCOVERY_STARTED_EVT            30  /* RF Discovery started event                   */
+#define NFA_RF_DISCOVERY_STOPPED_EVT            31  /* RF Discovery stopped event                   */
+#define NFA_UPDATE_RF_PARAM_RESULT_EVT          32  /* status of updating RF communication paramters*/
+#define NFA_SET_P2P_LISTEN_TECH_EVT             33  /* status of setting P2P listen technologies    */
+#define NFA_RW_INTF_ERROR_EVT                   34  /* RF Interface error event                     */
+
+/* NFC deactivation type */
+#define NFA_DEACTIVATE_TYPE_IDLE        NFC_DEACTIVATE_TYPE_IDLE
+#define NFA_DEACTIVATE_TYPE_SLEEP       NFC_DEACTIVATE_TYPE_SLEEP
+#define NFA_DEACTIVATE_TYPE_DISCOVERY   NFC_DEACTIVATE_TYPE_DISCOVERY
+
+typedef UINT8   tNFA_DEACTIVATE_TYPE;
+
+/* Data for NFA_DISC_RESULT_EVT */
+typedef struct
+{
+    tNFA_STATUS	        status;         /* NFA_STATUS_OK if successful       */
+    tNFC_RESULT_DEVT    discovery_ntf;  /* RF discovery notification details */
+} tNFA_DISC_RESULT;
+
+/* Data for NFA_ACTIVATED_EVT */
+typedef struct
+{
+    UINT8               hr[NFA_T1T_HR_LEN];       /* HR of Type 1 tag         */
+    UINT8               uid[NFA_T1T_CMD_UID_LEN]; /* UID used in T1T Commands */
+} tNFA_T1T_PARAMS;
+
+typedef struct
+{
+    UINT8               uid[NFA_MAX_UID_LEN];     /* UID of T2T tag           */
+} tNFA_T2T_PARAMS;
+
+typedef struct
+{
+    UINT8               num_system_codes;       /* Number of system codes supporte by tag   */
+    UINT16              *p_system_codes;        /* Pointer to list of system codes          */
+} tNFA_T3T_PARAMS;
+
+typedef struct
+{
+    UINT8               uid[I93_UID_BYTE_LEN];  /* UID[0]:MSB, ... UID[7]:LSB                   */
+    UINT8               info_flags;             /* information flags                            */
+    UINT8               dsfid;                  /* DSFID if I93_INFO_FLAG_DSFID                 */
+    UINT8               afi;                    /* AFI if I93_INFO_FLAG_AFI                     */
+    UINT16              num_block;              /* number of blocks if I93_INFO_FLAG_MEM_SIZE   */
+    UINT8               block_size;             /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+    UINT8               IC_reference;           /* IC Reference if I93_INFO_FLAG_IC_REF         */
+} tNFA_I93_PARAMS;
+
+typedef union
+{
+    tNFA_T1T_PARAMS     t1t;            /* HR and UID of T1T                */
+    tNFA_T2T_PARAMS     t2t;            /* UID of T2T                       */
+    tNFA_T3T_PARAMS     t3t;            /* System codes                     */
+    tNFA_I93_PARAMS     i93;            /* System Information of ISO 15693  */
+} tNFA_TAG_PARAMS;
+
+typedef struct
+{
+    tNFC_ACTIVATE_DEVT  activate_ntf;   /* RF discovery activation details */
+    tNFA_TAG_PARAMS     params;         /* additional informaiton of tag   */
+} tNFA_ACTIVATED;
+
+/* Data for NFA_DEACTIVATED_EVT */
+typedef struct
+{
+    tNFA_DEACTIVATE_TYPE type;          /* NFA_DEACTIVATE_TYPE_IDLE or NFA_DEACTIVATE_TYPE_SLEEP */
+} tNFA_DEACTIVATED;
+
+/* Structure for NFA_NDEF_DETECT_EVT event data */
+typedef struct
+{
+    tNFA_STATUS         status;             /* Status of the ndef detecton                              */
+    tNFA_NFC_PROTOCOL   protocol;           /* protocol used to detect NDEF                             */
+    UINT32              max_size;           /* max number of bytes available for NDEF data              */
+    UINT32              cur_size;           /* current size of stored NDEF data (in bytes)              */
+    UINT8               flags;              /* Flags to indicate NDEF capability,formated,formatable and read only */
+} tNFA_NDEF_DETECT;
+
+
+/* Structure for NFA_TLV_DETECT_EVT event data */
+typedef struct
+{
+    tNFA_STATUS         status;     /* Status of the tlv detecton        */
+    tNFA_NFC_PROTOCOL   protocol;   /* protocol used to detect TLV       */
+    UINT8               num_tlvs;   /* number of tlvs present in the tag */
+    UINT8               num_bytes;  /* number of lock/reserved bytes     */
+} tNFA_TLV_DETECT;
+
+/* Structure for NFA_DATA_EVT data */
+typedef struct
+{
+    UINT8               *p_data;        /* Data buffer                      */
+    UINT16              len;            /* Length of data                   */
+} tNFA_RX_DATA;
+
+/* Structure for NFA_CE_NDEF_WRITE_CPLT_EVT data */
+typedef struct
+{
+    tNFA_STATUS         status;         /* Status of the ndef write op      */
+    UINT32              len;            /* Update length of NDEF data       */
+    UINT8               *p_data;        /* data buffer                      */
+} tNFA_CE_NDEF_WRITE_CPLT;
+
+/* Data for NFA_LLCP_ACTIVATED_EVT */
+typedef struct
+{
+    BOOLEAN             is_initiator;   /* TRUE if initiator                */
+    UINT16              remote_wks;     /* Well-Known service mask of peer  */
+    UINT8               remote_lsc;     /* Link Service Class of peer       */
+    UINT16              remote_link_miu;/* Link MIU of peer                 */
+    UINT16              local_link_miu; /* Link MIU of local                */
+} tNFA_LLCP_ACTIVATED;
+
+/* Data for NFA_LLCP_DEACTIVATED_EVT */
+typedef struct
+{
+    UINT8               reason;         /* reason of deactivation           */
+} tNFA_LLCP_DEACTIVATED;
+
+/* Data for NFA_I93_CMD_CPLT_EVT */
+typedef struct
+{
+    UINT8           dsfid;                  /* DSFID                       */
+    UINT8           uid[I93_UID_BYTE_LEN];  /* UID[0]:MSB, ... UID[7]:LSB  */
+} tNFA_I93_INVENTORY;
+
+typedef struct                              /* RW_I93_SYS_INFO_EVT                          */
+{
+    UINT8           info_flags;             /* information flags                            */
+    UINT8           uid[I93_UID_BYTE_LEN];  /* UID                                          */
+    UINT8           dsfid;                  /* DSFID if I93_INFO_FLAG_DSFID                 */
+    UINT8           afi;                    /* AFI if I93_INFO_FLAG_AFI                     */
+    UINT16          num_block;              /* number of blocks if I93_INFO_FLAG_MEM_SIZE   */
+    UINT8           block_size;             /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+    UINT8           IC_reference;           /* IC Reference if I93_INFO_FLAG_IC_REF         */
+} tNFA_I93_SYS_INFO;
+
+typedef struct
+{
+    tNFA_STATUS         status;         /* Status of sending command       */
+    UINT8               sent_command;   /* sent command to tag             */
+    union
+    {
+        UINT8               error_code; /* error code defined in ISO 15693 */
+        tNFA_I93_INVENTORY  inventory;  /* inventory response              */
+        tNFA_I93_SYS_INFO   sys_info;   /* system information              */
+    } params;
+} tNFA_I93_CMD_CPLT;
+
+/* Data for NFA_CE_REGISTERED_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;         /* NFA_STATUS_OK if successful                      */
+    tNFA_HANDLE         handle;         /* handle for NFA_CeRegisterFelicaSystemCodeOnDH () */
+                                        /*            NFA_CeRegisterT4tAidOnDH ()           */
+} tNFA_CE_REGISTERED;
+
+/* Data for NFA_CE_DEREGISTERED_EVT */
+typedef struct
+{
+    tNFA_HANDLE         handle;         /* handle from NFA_CE_REGISTERED_EVT   */
+} tNFA_CE_DEREGISTERED;
+
+/* Data for NFA_CE_ACTIVATED_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;         /* NFA_STATUS_OK if successful              */
+    tNFA_HANDLE         handle;         /* handle from NFA_CE_REGISTERED_EVT        */
+    tNFC_ACTIVATE_DEVT  activate_ntf;   /* RF discovery activation details          */
+} tNFA_CE_ACTIVATED;
+
+/* Data for NFA_CE_DEACTIVATED_EVT */
+typedef struct
+{
+    tNFA_HANDLE         handle;         /* handle from NFA_CE_REGISTERED_EVT   */
+    tNFA_DEACTIVATE_TYPE type;          /* NFA_DEACTIVATE_TYPE_IDLE or NFA_DEACTIVATE_TYPE_SLEEP */
+} tNFA_CE_DEACTIVATED;
+
+/* Structure for NFA_CE_DATA_EVT data */
+typedef struct
+{
+    tNFA_HANDLE         handle;         /* handle from NFA_CE_REGISTERED_EVT    */
+    UINT8               *p_data;        /* Data buffer                          */
+    UINT16              len;            /* Length of data                       */
+} tNFA_CE_DATA;
+
+
+/* Union of all connection callback structures */
+typedef union
+{
+    tNFA_STATUS             status;             /* NFA_POLL_ENABLED_EVT                 */
+                                                /* NFA_POLL_DISABLED_EVT                */
+                                                /* NFA_CE_UICC_LISTEN_CONFIGURED_EVT    */
+                                                /* NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT */
+                                                /* NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT */
+                                                /* NFA_SELECT_RESULT_EVT                */
+                                                /* NFA_DEACTIVATE_FAIL_EVT              */
+                                                /* NFA_CE_NDEF_WRITE_START_EVT          */
+                                                /* NFA_SELECT_CPLT_EVT                  */
+                                                /* NFA_READ_CPLT_EVT                    */
+                                                /* NFA_WRITE_CPLT_EVT                   */
+                                                /* NFA_PRESENCE_CHECK_EVT               */
+                                                /* NFA_FORMAT_CPLT_EVT                  */
+                                                /* NFA_SET_TAG_RO_EVT                   */
+                                                /* NFA_UPDATE_RF_PARAM_RESULT_EVT       */
+                                                /* NFA_RW_INTF_ERROR_EVT                */
+    tNFA_DISC_RESULT         disc_result;       /* NFA_DISC_RESULT_EVT                  */
+    tNFA_ACTIVATED           activated;         /* NFA_ACTIVATED_EVT                    */
+    tNFA_DEACTIVATED         deactivated;       /* NFA_DEACTIVATED_EVT                  */
+    tNFA_NDEF_DETECT         ndef_detect;       /* NFA_NDEF_DETECT_EVT                  */
+    tNFA_TLV_DETECT          tlv_detect;        /* NFA_TLV_DETECT_EVT                   */
+    tNFA_RX_DATA             data;              /* NFA_DATA_EVT                         */
+    tNFA_CE_NDEF_WRITE_CPLT  ndef_write_cplt;   /* NFA_CE_NDEF_WRITE_CPLT_EVT           */
+    tNFA_LLCP_ACTIVATED      llcp_activated;    /* NFA_LLCP_ACTIVATED_EVT               */
+    tNFA_LLCP_DEACTIVATED    llcp_deactivated;  /* NFA_LLCP_DEACTIVATED_EVT             */
+    tNFA_I93_CMD_CPLT        i93_cmd_cplt;      /* NFA_I93_CMD_CPLT_EVT                 */
+    tNFA_CE_REGISTERED       ce_registered;     /* NFA_CE_REGISTERED_EVT                */
+    tNFA_CE_DEREGISTERED     ce_deregistered;   /* NFA_CE_DEREGISTERED_EVT              */
+    tNFA_CE_ACTIVATED        ce_activated;      /* NFA_CE_ACTIVATED_EVT                 */
+    tNFA_CE_DEACTIVATED      ce_deactivated;    /* NFA_CE_DEACTIVATED_EVT               */
+    tNFA_CE_DATA             ce_data;           /* NFA_CE_DATA_EVT                      */
+
+} tNFA_CONN_EVT_DATA;
+
+/* NFA Connection Callback */
+typedef void (tNFA_CONN_CBACK) (UINT8 event, tNFA_CONN_EVT_DATA *p_data);
+
+#ifndef NFA_DM_NUM_INTERFACE_MAP
+#define NFA_DM_NUM_INTERFACE_MAP    3
+#endif
+
+/* compile-time configuration structure */
+typedef struct
+{
+    BOOLEAN auto_detect_ndef;           /* Automatic NDEF detection (when not in exclusive RF mode) */
+    BOOLEAN auto_read_ndef;             /* Automatic NDEF read (when not in exclusive RF mode)      */
+} tNFA_DM_CFG;
+
+/*
+** Exclusive RF mode listen configuration
+*/
+
+#define NFA_LB_MAX_NFCID0_LEN           4
+#define NFA_LF_MAX_SC_NFCID2            1
+#define NFA_LA_MAX_HIST_BYTES           15
+#define NFA_LB_MAX_H_INFO_LEN           15
+
+typedef struct
+{
+    /*
+    ** Discovery Configuration Parameters for Listen A
+    */
+    BOOLEAN la_enable;                          /* TRUE if listening A                      */
+    UINT8   la_bit_frame_sdd;                   /* Bit Frame SDD in Byte 1 of SENS_RES      */
+    UINT8   la_platform_config;                 /* Platform Config in Byte 2 of SENS_RES    */
+    UINT8   la_sel_info;                        /* Byte of SEL_RES                          */
+    UINT8   la_nfcid1_len;                      /* NFCID1 (0, 4, 7 or 10 bytes)             */
+    UINT8   la_nfcid1[NCI_NFCID1_MAX_LEN];      /*        if empty, NFCC will decide        */
+
+    /*
+    ** Discovery Configuration Parameters for Listen B
+    */
+    BOOLEAN lb_enable;                          /* TRUE if listening B                      */
+    UINT8   lb_sensb_info;                      /* Byte 2 of Protocol Info within SENSB_RES */
+    UINT8   lb_nfcid0_len;                      /* NFCID0 (0, 1 or 4 bytes)                 */
+    UINT8   lb_nfcid0[NFA_LB_MAX_NFCID0_LEN];   /*         if empty, NFCC will decide       */
+    UINT8   lb_app_data[NCI_PARAM_LEN_LB_APPDATA];/* Bytes 6 - 9 in SENSB_RES               */
+    UINT8   lb_sfgi;                            /* Start-Up Frame Guard Time                */
+    UINT8   lb_adc_fo;                          /* Byte 12 in SENSB_RES                     */
+
+    /*
+    ** Discovery Configuration Parameters for Listen F
+    */
+    BOOLEAN lf_enable;                          /* TRUE if listening F          */
+    UINT8   lf_con_bitr_f;                      /* bit rate to listen           */
+    UINT8   lf_protocol_type;                   /* Supported Protocols          */
+    UINT16  lf_t3t_flags;                       /* bit field indicating which lf_t3t_identifier are enabled */
+    UINT8   lf_t3t_identifier[NFA_LF_MAX_SC_NFCID2][NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN];
+                                                /* System Code and NFCID2       */
+    UINT8   lf_t3t_pmm[NCI_T3T_PMM_LEN];        /* Bytes 10 - 17 in SENSF_RES   */
+
+    /*
+    ** Discovery Configuration Parameters for Listen ISO-DEP
+    */
+    BOOLEAN li_enable;                          /* TRUE if listening ISO-DEP            */
+    UINT8   li_fwi;                             /* Frame Waiting Time Integer           */
+    UINT8   la_hist_bytes_len;                  /* historical bytes for Listen-A        */
+    UINT8   la_hist_bytes[NFA_LA_MAX_HIST_BYTES];
+    UINT8   lb_h_info_resp_len;                 /* higher layer response for Listen-B   */
+    UINT8   lb_h_info_resp[NFA_LB_MAX_H_INFO_LEN];
+
+    /*
+    ** Discovery Configuration Parameters for Listen NFC-DEP
+    */
+    BOOLEAN ln_enable;                          /* TRUE if listening NFC-DEP            */
+    UINT8   ln_wt;                              /* Waiting Time Integer                 */
+    UINT8   ln_atr_res_gen_bytes_len;           /* General bytes in ATR_RES             */
+    UINT8   ln_atr_res_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+    UINT8   ln_atr_res_config;                  /* Optional parameters (PPt) in ATR_RES */
+} tNFA_LISTEN_CFG;
+
+/* Data for NFA_UpdateRFCommParams () */
+typedef tNFC_RF_COMM_PARAMS tNFA_RF_COMM_PARAMS;
+
+/* RF Interface type */
+#define NFA_INTERFACE_FRAME         NFC_INTERFACE_FRAME
+#define NFA_INTERFACE_ISO_DEP       NFC_INTERFACE_ISO_DEP
+#define NFA_INTERFACE_NFC_DEP       NFC_INTERFACE_NFC_DEP
+typedef tNFC_INTF_TYPE tNFA_INTF_TYPE;
+
+/*******************************************************************************
+** NDEF Definitions
+*******************************************************************************/
+
+/* Definitions for tNFA_TNF (NDEF type name format ID) */
+#define NFA_TNF_EMPTY           NDEF_TNF_EMPTY      /* Empty or no type specified                       */
+#define NFA_TNF_WKT             NDEF_TNF_WKT        /* NFC Forum well-known type [NFC RTD]              */
+#define NFA_TNF_RFC2046_MEDIA   NDEF_TNF_MEDIA      /* Media-type as defined in RFC 2046 [RFC 2046]     */
+#define NFA_TNF_RFC3986_URI     NDEF_TNF_URI        /* Absolute URI as defined in RFC 3986 [RFC 3986]   */
+#define NFA_TNF_EXTERNAL        NDEF_TNF_EXT        /* NFC Forum external type [NFC RTD]                */
+#define NFA_TNF_UNKNOWN	        NDEF_TNF_UNKNOWN    /* Unknown                                          */
+#define NFA_TNF_UNCHANGED       NDEF_TNF_UNCHANGED  /* Unchanged                                        */
+#define NFA_TNF_RESERVED        NDEF_TNF_RESERVED   /* Reserved                                         */
+#define NFA_TNF_DEFAULT	        0xFF                /* Used to register default NDEF type handler       */
+typedef UINT8 tNFA_TNF;
+
+/* Definitions for tNFA_NDEF_URI_ID (Frequently used prefixes. For additional values, see [NFC RTD URI] */
+#define NFA_NDEF_URI_ID_ABSOLUTE    0x00            /* Unabridged URI.  */
+#define NFA_NDEF_URI_ID_HTTP        0x03            /* http://          */
+#define NFA_NDEF_URI_ID_HTTPS       0x04            /* https://         */
+#define NFA_NDEF_URI_ID_TEL         0x05            /* tel:             */
+#define NFA_NDEF_URI_ID_MAILTO      0x06            /* mailto:          */
+#define NFA_NDEF_URI_ID_FTP         0x0D            /* ftp://           */
+#define NFA_NDEF_URI_ID_FILE        0x1D            /* file://          */
+
+typedef UINT8 tNFA_NDEF_URI_ID;
+
+/* Events for tNFA_NDEF_CBACK */
+#define NFA_NDEF_REGISTER_EVT   0   /* NDEF record type registered. (In response to NFA_RegisterNDefTypeHandler)    */
+#define NFA_NDEF_DATA_EVT	    1   /* Received an NDEF message with the registered type. See [tNFA_DATA]       */
+typedef UINT8 tNFA_NDEF_EVT;
+
+/* Structure for NFA_NDEF_REGISTER_EVT event data */
+typedef struct
+{
+    tNFA_STATUS status;             /* Status of the registration               */
+    tNFA_HANDLE ndef_type_handle;   /* Handle for this NDEF type registration.  */
+} tNFA_NDEF_REGISTER;
+
+/* Structure for NFA_NDEF_DATA_EVT event data */
+typedef struct
+{
+    tNFA_HANDLE ndef_type_handle;   /* Handle for NDEF type registration.   */
+    UINT8       *p_data;            /* Data buffer                          */
+    UINT32      len;                /* Length of data                       */
+} tNFA_NDEF_DATA;
+
+/* Union of all NDEF callback structures */
+typedef union
+{
+    tNFA_NDEF_REGISTER  ndef_reg;       /* Structure for NFA_NDEF_REGISTER_EVT event data   */
+    tNFA_NDEF_DATA      ndef_data;      /* Structure for NFA_NDEF_DATA_EVT event data       */
+} tNFA_NDEF_EVT_DATA;
+
+/* NFA_NDEF callback */
+typedef void (tNFA_NDEF_CBACK) (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *p_data);
+
+/* NFA VSC Callback */
+typedef void (tNFA_VSC_CBACK)(UINT8 event, UINT16 param_len, UINT8 *p_param);
+
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_Init
+**
+** Description      This function initializes control blocks for NFA
+**
+**                  p_hal_entry_tbl points to a table of HAL entry points
+**
+**                  NOTE: the buffer that p_hal_entry_tbl points must be
+**                  persistent until NFA is disabled.
+**
+**
+** Returns          none
+**
+*******************************************************************************/
+NFC_API extern void NFA_Init (tHAL_NFC_ENTRY *p_hal_entry_tbl);
+
+/*******************************************************************************
+**
+** Function         NFA_Enable
+**
+** Description      This function enables NFC. Prior to calling NFA_Enable,
+**                  the NFCC must be powered up, and ready to receive commands.
+**                  This function enables the tasks needed by NFC, opens the NCI
+**                  transport, resets the NFC controller, downloads patches to
+**                  the NFCC (if necessary), and initializes the NFC subsystems.
+**
+**                  This function should only be called once - typically when NFC
+**                  is enabled during boot-up, or when NFC is enabled from a
+**                  settings UI. Subsequent calls to NFA_Enable while NFA is
+**                  enabling or enabled will be ignored. When the NFC startup
+**                  procedure is completed, an NFA_DM_ENABLE_EVT is returned to the
+**                  application using the tNFA_DM_CBACK.
+**
+**                  The tNFA_CONN_CBACK parameter is used to register a callback
+**                  for polling, p2p and card emulation events.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Enable (tNFA_DM_CBACK       *p_dm_cback,
+                                       tNFA_CONN_CBACK     *p_conn_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_Disable
+**
+** Description      This function is called to shutdown NFC. The tasks for NFC
+**                  are terminated, and clean up routines are performed. This
+**                  function is typically called during platform shut-down, or
+**                  when NFC is disabled from a settings UI. When the NFC
+**                  shutdown procedure is completed, an NFA_DM_DISABLE_EVT is
+**                  returned to the application using the tNFA_DM_CBACK.
+**
+**                  The platform should wait until the NFC_DISABLE_REVT is
+**                  received before powering down the NFC chip and NCI transport.
+**                  This is required to so that NFA can gracefully shut down any
+**                  open connections.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Disable (BOOLEAN graceful);
+
+/*******************************************************************************
+**
+** Function         NFA_SetConfig
+**
+** Description      Set the configuration parameters to NFCC. The result is
+**                  reported with an NFA_DM_SET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function. Most Configuration
+**                  parameters are related to RF discovery.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BUSY if previous setting is on-going
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SetConfig (tNFA_PMID    param_id,
+                                          UINT8        length,
+                                          UINT8       *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_GetConfig
+**
+** Description      Get the configuration parameters from NFCC. The result is
+**                  reported with an NFA_DM_GET_CONFIG_EVT in the tNFA_DM_CBACK
+**                  callback.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_GetConfig (UINT8 num_ids, tNFA_PMID *p_param_ids);
+
+/*******************************************************************************
+**
+** Function         NFA_RequestExclusiveRfControl
+**
+** Description      Request exclusive control of NFC.
+**                  - Previous behavior (polling/tag reading, DH card emulation)
+**                    will be suspended .
+**                  - Polling and listening will be done based on the specified
+**                    params
+**
+**                  The NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT event of
+**                  tNFA_CONN_CBACK indicates the status of the operation.
+**
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT indicates link
+**                  activation/deactivation.
+**
+**                  NFA_SendRawFrame is used to send data to the peer. NFA_DATA_EVT
+**                  indicates data from the peer.
+**
+**                  If a tag is activated, then the NFA_RW APIs may be used to
+**                  send commands to the tag. Incoming NDEF messages are sent to
+**                  the NDEF callback.
+**
+**                  Once exclusive RF control has started, NFA will not activate
+**                  LLCP internally. The application has exclusive control of
+**                  the link.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RequestExclusiveRfControl (tNFA_TECHNOLOGY_MASK poll_mask,
+                                                          tNFA_LISTEN_CFG *p_listen_cfg,
+                                                          tNFA_CONN_CBACK *p_conn_cback,
+                                                          tNFA_NDEF_CBACK *p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_ReleaseExclusiveRfControl
+**
+** Description      Release exclusive control of NFC. Once released, behavior
+**                  prior to obtaining exclusive RF control will resume.
+**
+Note??
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ReleaseExclusiveRfControl (void);
+
+/*******************************************************************************
+**
+** Function         NFA_EnablePolling
+**
+** Description      Enable polling for technologies specified by poll_mask.
+**
+**                  The following events (notified using the connection
+**                  callback registered with NFA_Enable) are generated during
+**                  polling:
+**
+**                  - NFA_POLL_ENABLED_EVT indicates whether or not polling
+**                    successfully enabled.
+**                  - NFA_DISC_RESULT_EVT indicates there are more than one devices,
+**                    so application must select one of tags by calling NFA_Select().
+**                  - NFA_SELECT_RESULT_EVT indicates whether previous selection was
+**                    successful or not. If it was failed then application must select
+**                    again or deactivate by calling NFA_Deactivate().
+**                  - NFA_ACTIVATED_EVT is generated when an NFC link is activated.
+**                  - NFA_NDEF_DETECT_EVT is generated if tag is activated
+**                  - NFA_LLCP_ACTIVATED_EVT/NFA_LLCP_DEACTIVATED_EVT is generated
+**                    if NFC-DEP is activated
+**                  - NFA_DEACTIVATED_EVT will be returned after deactivating NFC link.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EnablePolling (tNFA_TECHNOLOGY_MASK poll_mask);
+
+/*******************************************************************************
+**
+** Function         NFA_DisablePolling
+**
+** Description      Disable polling
+**                  NFA_POLL_DISABLED_EVT will be returned after stopping polling.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DisablePolling (void);
+
+/*******************************************************************************
+**
+** Function         NFA_SetP2pListenTech
+**
+** Description      This function is called to set listen technology for NFC-DEP.
+**                  This funtion may be called before or after starting any server
+**                  on NFA P2P/CHO/SNEP.
+**                  If there is no technology for NFC-DEP, P2P listening will be
+**                  stopped.
+**
+**                  NFA_SET_P2P_LISTEN_TECH_EVT without data will be returned.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SetP2pListenTech (tNFA_TECHNOLOGY_MASK tech_mask);
+
+/*******************************************************************************
+**
+** Function         NFA_StartRfDiscovery
+**
+** Description      Start RF discovery
+**                  RF discovery parameters shall be set by other APIs.
+**
+**                  An NFA_RF_DISCOVERY_STARTED_EVT indicates whether starting was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_StartRfDiscovery (void);
+
+/*******************************************************************************
+**
+** Function         NFA_StopRfDiscovery
+**
+** Description      Stop RF discovery
+**
+**                  An NFA_RF_DISCOVERY_STOPPED_EVT indicates whether stopping was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_StopRfDiscovery (void);
+
+/*******************************************************************************
+**
+** Function         NFA_SetRfDiscoveryDuration
+**
+** Description      Set the duration of the single discovery period in [ms].
+**                  Allowable range: 0 ms to 0xFFFF ms.
+**
+** Note:            If discovery is already started, the application should
+**                  call NFA_StopRfDiscovery prior to calling
+**                  NFA_SetRfDiscoveryDuration, and then call
+**                  NFA_StartRfDiscovery afterwards to restart discovery using
+**                  the new duration.
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SetRfDiscoveryDuration (UINT16 discovery_period_ms);
+
+/*******************************************************************************
+**
+** Function         NFA_Select
+**
+** Description      Select one from detected devices by NFA_DISC_RESULT_EVT after the
+**                  last discovery result is received.
+**                  An NFA_SELECT_RESULT_EVT indicates whether selection was successful or not.
+**                  If failed then application must select again or deactivate by NFA_Deactivate ().
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if RF interface is not matched protocol
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Select (UINT8             rf_disc_id,
+                                       tNFA_NFC_PROTOCOL protocol,
+                                       tNFA_INTF_TYPE    rf_interface);
+
+/*******************************************************************************
+**
+** Function         NFA_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication parameters
+**                  once the Frame RF Interface has been activated.
+**
+**                  An NFA_UPDATE_RF_PARAM_RESULT_EVT indicates whether updating
+**                  was successful or not.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_UpdateRFCommParams (tNFA_RF_COMM_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function         NFA_Deactivate
+**
+** Description
+**                  If sleep_mode=TRUE:
+**                      Deselect the activated device by deactivating into sleep mode.
+**
+**                      An NFA_DEACTIVATE_FAIL_EVT indicates that selection was not successful.
+**                      Application can select another discovered device or deactivate by NFA_Deactivate ()
+**                      after receiving NFA_DEACTIVATED_EVT.
+**
+**                      Deactivating to sleep mode is not allowed when NFCC is in wait-for-host-select
+**                      mode, or in listen-sleep states; NFA will deactivate to idle or discovery state
+**                      for these cases respectively.
+**
+**
+**                  If sleep_mode=FALSE:
+**                      Deactivate the connection (e.g. as a result of presence check failure)
+**                      NFA_DEACTIVATED_EVT will indicate that link is deactivated.
+**                      Polling/listening will resume (unless the nfcc is in wait_for-all-discoveries state)
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_Deactivate (BOOLEAN sleep_mode);
+
+/*******************************************************************************
+**
+** Function         NFA_SendRawFrame
+**
+** Description      Send a raw frame over the activated interface with the NFCC.
+**                  This function can only be called after NFC link is activated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SendRawFrame (UINT8  *p_raw_data,
+                                             UINT16  data_len);
+
+/*******************************************************************************
+** NDEF APIs
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefTypeHandler
+**
+** Description      This function allows the applications to register for
+**                  specific types of NDEF records. When NDEF records are
+**                  received, NFA will parse the record-type field, and pass
+**                  the record to the registered tNFA_NDEF_CBACK.
+**
+**                  For records types which were not registered, the record will
+**                  be sent to the default handler. A default type-handler may
+**                  be registered by calling this NFA_RegisterNDefTypeHandler
+**                  with tnf=NFA_TNF_DEFAULT. In this case, all un-registered
+**                  record types will be sent to the callback. Only one default
+**                  handler may be registered at a time.
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this record type.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RegisterNDefTypeHandler (BOOLEAN          handle_whole_message,
+                                                        tNFA_TNF         tnf,
+                                                        UINT8           *p_type_name,
+                                                        UINT8            type_name_len,
+                                                        tNFA_NDEF_CBACK *p_ndef_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_RegisterNDefUriHandler
+**
+** Description      This API is a special-case of NFA_RegisterNDefTypeHandler
+**                  with TNF=NFA_TNF_WKT, and type_name='U' (URI record); and allows
+**                  registering for specific URI types (e.g. 'tel:' or 'mailto:').
+**
+**                  An NFA_NDEF_REGISTER_EVT will be sent to the tNFA_NDEF_CBACK
+**                  to indicate that registration was successful, and provide a
+**                  handle for this registration.
+**
+**                  If uri_id=NFA_NDEF_URI_ID_ABSOLUTE, then p_abs_uri contains the
+**                  unabridged URI. For all other uri_id values, the p_abs_uri
+**                  parameter is ignored (i.e the URI prefix is implied by uri_id).
+**                  See [NFC RTD URI] for more information.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RegisterNDefUriHandler (BOOLEAN          handle_whole_message,
+                                                       tNFA_NDEF_URI_ID uri_id,
+                                                       UINT8            *p_abs_uri,
+                                                       UINT8            uri_id_len,
+                                                       tNFA_NDEF_CBACK  *p_ndef_cback);
+
+
+/*******************************************************************************
+**
+** Function         NFA_DeregisterNDefTypeHandler
+**
+** Description      Deregister NDEF record type handler.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_DeregisterNDefTypeHandler (tNFA_HANDLE ndef_type_handle);
+
+
+/*******************************************************************************
+**
+** Function         NFA_PowerOffSleepMode
+**
+** Description      This function is called to enter or leave NFCC Power Off Sleep mode
+**                  NFA_DM_PWR_MODE_CHANGE_EVT will be sent to indicate status.
+**
+**                  start_stop : TRUE if entering Power Off Sleep mode
+**                               FALSE if leaving Power Off Sleep mode
+**
+Note??
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_PowerOffSleepMode (BOOLEAN start_stop);
+
+/*******************************************************************************
+**
+** Function         NFA_RegVSCback
+**
+** Description      This function is called to register or de-register a callback
+**                  function to receive Proprietary NCI response and notification
+**                  events.
+**                  The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFA_RegVSCback (BOOLEAN          is_register,
+                                           tNFA_VSC_CBACK   *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SendVsCommand
+**
+** Description      This function is called to send an NCI Vendor Specific
+**                  command to NFCC.
+**
+**                  oid             - The opcode of the VS command.
+**                  cmd_params_len  - The command parameter len
+**                  p_cmd_params    - The command parameter
+**                  p_cback         - The callback function to receive the command
+**                                    status
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SendVsCommand (UINT8            oid,
+                                              UINT8            cmd_params_len,
+                                              UINT8            *p_cmd_params,
+                                              tNFA_VSC_CBACK   *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SetTraceLevel
+**
+** Description      This function sets the trace level for NFA.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_SetTraceLevel (UINT8 new_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_API_H */
+
diff --git a/src/nfa/include/nfa_ce_api.h b/src/nfa/include/nfa_ce_api.h
new file mode 100644
index 0000000..d339320
--- /dev/null
+++ b/src/nfa/include/nfa_ce_api.h
@@ -0,0 +1,236 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA card emulation API functions
+ *
+ ******************************************************************************/
+#ifndef NFA_CE_API_H
+#define NFA_CE_API_H
+
+#include "nfc_target.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureLocalTag
+**
+** Description      Configure local NDEF tag.
+**
+**                  Tag events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of the
+**                  operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+**                  If a write-request is received to update the tag memory,
+**                  an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application, along
+**                  with a buffer containing the updated contents.
+**
+**                  To disable the local NDEF tag, set protocol_mask=0
+**
+**                  The NDEF data provided by p_ndef_data must be persistent
+**                  as long as the local NDEF tag is enabled.
+**
+**                  UID of the tag can be set only for Type 1 and Type 2 tag.
+**                  UID Length should be 4/7 bytes in case of Type 1 tag and
+**                  UID Length should be 4/10 bytes in case of Type 2 tag.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK,            if command accepted
+**                  NFA_STATUS_INVALID_PARAM,
+**                      if protocol_maks is not 0 and p_ndef_data is NULL
+**                  (or)if p_uid is NULL and uid_len is not 0
+**                  (or)if protocol mask is set for both Type 1 and Type 2
+**                  (or)if uid_len is not 0 and protocol mask is not set for Type 1/2
+**                  (or)if protocol mask is set for Type 1 and uid_len is not 4/7
+**                  (or)if protocol mask is set for Type 2 and uid_len is not 4/10
+**
+**                  NFA_STATUS_FAILED:        otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeConfigureLocalTag (tNFA_PROTOCOL_MASK protocol_mask,
+                                                    UINT8     *p_ndef_data,
+                                                    UINT16    ndef_cur_size,
+                                                    UINT16    ndef_max_size,
+                                                    BOOLEAN   read_only,
+                                                    UINT8     uid_len,
+                                                    UINT8     *p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_CeConfigureUiccListenTech
+**
+** Description      Configure listening for the UICC, using the specified
+**                  technologies.
+**
+**                  Events will be notifed using the tNFA_CONN_CBACK
+**                  (registered during NFA_Enable)
+**
+**                  The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of the
+**                  operation.
+**
+**                  Activation and deactivation are reported using the
+**                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeConfigureUiccListenTech (tNFA_HANDLE          ee_handle,
+                                                          tNFA_TECHNOLOGY_MASK tech_mask);
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterFelicaSystemCodeOnDH
+**
+** Description      Register listening callback for Felica system code
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH (UINT16           system_code,
+                                                               UINT8            nfcid2[NCI_RF_F_UID_LEN],
+                                                               tNFA_CONN_CBACK  *p_conn_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterFelicaSystemCodeOnDH
+**
+** Description      Deregister listening callback for Felica
+**                  (previously registered using NFA_CeRegisterFelicaSystemCodeOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_CeRegisterAidOnDH
+**
+** Description      Register listening callback for the specified ISODEP AID
+**
+**                  The NFA_CE_REGISTERED_EVT reports the status of the
+**                  operation.
+**
+**                  If no AID is specified (aid_len=0), then p_conn_cback will
+**                  will get notifications for any AIDs routed to the DH. This
+**                  over-rides callbacks registered for specific AIDs.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeRegisterAidOnDH (UINT8           aid[NFC_MAX_AID_LEN],
+                                                  UINT8           aid_len,
+                                                  tNFA_CONN_CBACK *p_conn_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_CeDeregisterAidOnDH
+**
+** Description      Deregister listening callback for ISODEP AID
+**                  (previously registered using NFA_CeRegisterAidOnDH)
+**
+**                  The NFA_CE_DEREGISTERED_EVT reports the status of the
+**                  operation.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if invalid handle
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeDeregisterAidOnDH (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_CeSetIsoDepListenTech
+**
+** Description      Set the technologies (NFC-A and/or NFC-B) to listen for when
+**                  NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are called.
+**
+**                  By default (if this API is not called), NFA will listen
+**                  for both NFC-A and NFC-B for ISODEP.
+**
+** Note:            If listening for ISODEP on UICC, the DH listen callbacks
+**                  may still get activate notifications for ISODEP if the reader/
+**                  writer selects an AID that is not routed to the UICC (regardless
+**                  of whether A or B was disabled using NFA_CeSetIsoDepListenTech)
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns:
+**                  NFA_STATUS_OK, if command accepted
+**                  NFA_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_CeSetIsoDepListenTech (tNFA_TECHNOLOGY_MASK tech_mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_CE_API_H */
diff --git a/src/nfa/include/nfa_cho_api.h b/src/nfa/include/nfa_cho_api.h
new file mode 100644
index 0000000..fde3222
--- /dev/null
+++ b/src/nfa/include/nfa_cho_api.h
@@ -0,0 +1,372 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA Connection Handover,
+ *  Broadcom's NFC application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_CHO_API_H
+#define NFA_CHO_API_H
+
+#include "nfa_api.h"
+#include "ndef_utils.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Handover version */
+#define NFA_CHO_VERSION             0x12    /* version 1.2 */
+#define NFA_CHO_GET_MAJOR_VERSION(x) ((UINT8)(x) >> 4)
+#define NFA_CHO_GET_MINOR_VERSION(x) ((UINT8)(x) & 0x0F)
+
+/*
+** NFA Connection Handover callback events
+*/
+#define NFA_CHO_REG_EVT             0x00    /* Registered                       */
+#define NFA_CHO_ACTIVATED_EVT       0x01    /* LLCP link activated              */
+#define NFA_CHO_DEACTIVATED_EVT     0x02    /* LLCP link deactivated            */
+#define NFA_CHO_CONNECTED_EVT       0x03    /* data link connected              */
+#define NFA_CHO_DISCONNECTED_EVT    0x04    /* data link disconnected           */
+#define NFA_CHO_REQUEST_EVT         0x05    /* AC information in "Hr" record    */
+#define NFA_CHO_SELECT_EVT          0x06    /* AC information in "Hs" record    */
+#define NFA_CHO_SEL_ERR_EVT         0x07    /* Received select with error       */
+#define NFA_CHO_TX_FAIL_EVT         0x08    /* Cannot send message to peer      */
+
+typedef UINT8 tNFA_CHO_EVT;
+
+/*
+** Data for NFA_CHO_ACTIVATED_EVT
+*/
+typedef struct
+{
+    BOOLEAN         is_initiator;   /* TRUE if local LLCP is initiator */
+} tNFA_CHO_ACTIVATED;
+
+/* NFA Connection Handover Carrier Power State */
+#define NFA_CHO_CPS_INACTIVE        0x00    /* Carrier is currently off         */
+#define NFA_CHO_CPS_ACTIVE          0x01    /* Carrier is currently on          */
+#define NFA_CHO_CPS_ACTIVATING      0x02    /* Activating carrier               */
+#define NFA_CHO_CPS_UNKNOWN         0x03    /* Unknown                          */
+
+typedef UINT8 tNFA_CHO_CPS;
+
+/* Data for Alternative Carrier Information */
+typedef struct
+{
+    tNFA_CHO_CPS        cps;            /* carrier power state                      */
+    UINT8               num_aux_data;   /* number of Auxiliary NDEF records         */
+} tNFA_CHO_AC_INFO;
+
+/* Device Role of Handover */
+#define NFA_CHO_ROLE_REQUESTER  0
+#define NFA_CHO_ROLE_SELECTOR   1
+#define NFA_CHO_ROLE_UNDECIDED  2
+
+typedef UINT8 tNFA_CHO_ROLE_TYPE;
+
+/*
+** Data for NFA_CHO_CONNECTED_EVT
+*/
+typedef struct
+{
+    tNFA_CHO_ROLE_TYPE  initial_role;   /* NFA_CHO_ROLE_REQUESTER if local initiated */
+                                        /* NFA_CHO_ROLE_SELECTOR if remote initiated */
+} tNFA_CHO_CONNECTED;
+
+/* Disconnected reason */
+#define NFA_CHO_DISC_REASON_API_REQUEST         0
+#define NFA_CHO_DISC_REASON_ALEADY_CONNECTED    1
+#define NFA_CHO_DISC_REASON_CONNECTION_FAIL     2
+#define NFA_CHO_DISC_REASON_PEER_REQUEST        3
+#define NFA_CHO_DISC_REASON_LINK_DEACTIVATED    4
+#define NFA_CHO_DISC_REASON_TIMEOUT             5
+#define NFA_CHO_DISC_REASON_UNKNOWN_MSG         6
+#define NFA_CHO_DISC_REASON_INVALID_MSG         7
+#define NFA_CHO_DISC_REASON_SEMANTIC_ERROR      8
+#define NFA_CHO_DISC_REASON_INTERNAL_ERROR      9
+
+typedef UINT8 tNFA_CHO_DISC_REASON;
+
+/*
+** Data for NFA_CHO_DISCONNECTED_EVT
+*/
+typedef struct
+{
+    tNFA_CHO_DISC_REASON    reason;     /* disconnected reason */
+} tNFA_CHO_DISCONNECTED;
+
+/* Reference ID */
+typedef struct
+{
+    UINT8               ref_len;
+    UINT8               ref_name[NFA_CHO_MAX_REF_NAME_LEN];
+} tNFA_CHO_REF_ID;
+
+/* Alternative Carrier records including carrier power state, carrier data reference and aux data reference */
+typedef struct
+{
+    tNFA_CHO_CPS        cps;                                      /* carrier power state    */
+    tNFA_CHO_REF_ID     carrier_data_ref;                         /* carrier data reference */
+    UINT8               aux_data_ref_count;                       /* number of aux data     */
+    tNFA_CHO_REF_ID     aux_data_ref[NFA_CHO_MAX_AUX_DATA_COUNT]; /* aux data reference     */
+} tNFA_CHO_AC_REC;
+
+/*
+** Data for NFA_CHO_REQUEST_EVT
+** Application may receive it while waiting for NFA_CHO_SELECT_EVT because of handover collision.
+*/
+typedef struct
+{
+    tNFA_STATUS         status;
+    UINT8               num_ac_rec;                     /* number of Alternative Carrier records*/
+    tNFA_CHO_AC_REC     ac_rec[NFA_CHO_MAX_AC_INFO];    /* Alternative Carrier records          */
+    UINT8               *p_ref_ndef;                    /* pointer of NDEF including AC records */
+    UINT32              ref_ndef_len;                   /* length of NDEF                       */
+} tNFA_CHO_REQUEST;
+
+/*
+** Data for NFA_CHO_SELECT_EVT
+*/
+typedef struct
+{
+    tNFA_STATUS         status;
+    UINT8               num_ac_rec;                     /* number of Alternative Carrier records*/
+    tNFA_CHO_AC_REC     ac_rec[NFA_CHO_MAX_AC_INFO];    /* Alternative Carrier records          */
+    UINT8               *p_ref_ndef;                    /* pointer of NDEF including AC records */
+    UINT32              ref_ndef_len;                   /* length of NDEF                       */
+} tNFA_CHO_SELECT;
+
+/* Error reason */
+#define NFA_CHO_ERROR_TEMP_MEM  0x01
+#define NFA_CHO_ERROR_PERM_MEM  0x02
+#define NFA_CHO_ERROR_CARRIER   0x03
+
+/*
+** Data for NFA_CHO_SEL_ERR_EVT
+*/
+typedef struct
+{
+    UINT8               error_reason;   /* Error reason          */
+    UINT32              error_data;     /* Error Data per reason */
+} tNFA_CHO_SEL_ERR;
+
+/* Union of all Connection Handover callback structures */
+typedef union
+{
+    tNFA_STATUS             status;         /* NFA_CHO_REG_EVT          */
+                                            /* NFA_CHO_DEACTIVATED_EVT  */
+                                            /* NFA_CHO_TX_FAIL_EVT      */
+    tNFA_CHO_ACTIVATED      activated;      /* NFA_CHO_ACTIVATED_EVT    */
+    tNFA_CHO_CONNECTED      connected;      /* NFA_CHO_CONNECTED_EVT    */
+    tNFA_CHO_DISCONNECTED   disconnected;   /* NFA_CHO_DISCONNECTED_EVT */
+    tNFA_CHO_SELECT         select;         /* NFA_CHO_SELECT_EVT       */
+    tNFA_CHO_REQUEST        request;        /* NFA_CHO_REQUEST_EVT      */
+    tNFA_CHO_SEL_ERR        sel_err;        /* NFA_CHO_SEL_ERR_EVT      */
+} tNFA_CHO_EVT_DATA;
+
+/* NFA Connection Handover callback */
+typedef void (tNFA_CHO_CBACK) (tNFA_CHO_EVT event, tNFA_CHO_EVT_DATA *p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_ChoRegister
+**
+** Description      This function is called to register callback function to receive
+**                  connection handover events.
+**
+**                  On this registration, "urn:nfc:sn:handover" server will be
+**                  registered on LLCP if enable_server is TRUE.
+**
+**                  The result of the registration is reported with NFA_CHO_REG_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoRegister (BOOLEAN        enable_server,
+                                            tNFA_CHO_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoDeregister
+**
+** Description      This function is called to deregister callback function from NFA
+**                  Connection Handover Application.
+**
+**                  If this is the valid deregistration, NFA Connection Handover
+**                  Application will close the service with "urn:nfc:sn:handover"
+**                  on LLCP and deregister NDEF type handler if any.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoDeregister (void);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoConnect
+**
+** Description      This function is called to create data link connection to
+**                  Connection Handover server on peer device.
+**
+**                  It must be called after receiving NFA_CHO_ACTIVATED_EVT.
+**                  NFA_CHO_CONNECTED_EVT will be returned if successful.
+**                  Otherwise, NFA_CHO_DISCONNECTED_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoConnect (void);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoDisconnect
+**
+** Description      This function is called to disconnect data link connection with
+**                  Connection Handover server on peer device.
+**
+**                  NFA_CHO_DISCONNECTED_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoDisconnect (void);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSendHr
+**
+** Description      This function is called to send Handover Request Message with
+**                  Handover Carrier records or Alternative Carrier records.
+**
+**                  It must be called after receiving NFA_CHO_CONNECTED_EVT.
+**
+**                  NDEF may include one or more Handover Carrier records or Alternative
+**                  Carrier records with auxiliary data.
+**                  The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
+**                  Payload ID must be unique and Payload ID length must be less than
+**                  or equal to NFA_CHO_MAX_REF_NAME_LEN.
+**
+**                  The alternative carrier information of Handover Select record
+**                  will be sent to application by NFA_CHO_SELECT_EVT. Application
+**                  may receive NFA_CHO_REQUEST_EVT because of handover collision.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoSendHr (UINT8             num_ac_info,
+                                          tNFA_CHO_AC_INFO *p_ac_info,
+                                          UINT8            *p_ndef,
+                                          UINT32            ndef_len);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSendHs
+**
+** Description      This function is called to send Handover Select message with
+**                  Alternative Carrier records as response to Handover Request
+**                  message.
+**
+**                  NDEF may include one or more Alternative Carrier records with
+**                  auxiliary data.
+**                  The records in NDEF must be matched with tNFA_CHO_AC_INFO in order.
+**                  Payload ID must be unique and Payload ID length must be less than
+**                  or equal to NFA_CHO_MAX_REF_NAME_LEN.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoSendHs (UINT8             num_ac_info,
+                                          tNFA_CHO_AC_INFO *p_ac_info,
+                                          UINT8            *p_ndef,
+                                          UINT32            ndef_len);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSendSelectError
+**
+** Description      This function is called to send Error record to indicate failure
+**                  to process the most recently received Handover Request message.
+**
+**                  error_reason : NFA_CHO_ERROR_TEMP_MEM
+**                                 NFA_CHO_ERROR_PERM_MEM
+**                                 NFA_CHO_ERROR_CARRIER
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_ChoSendSelectError (UINT8  error_reason,
+                                                   UINT32 error_data);
+
+/*******************************************************************************
+**
+** Function         NFA_ChoSetTraceLevel
+**
+** Description      This function sets the trace level for CHO.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_ChoSetTraceLevel (UINT8 new_level);
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+
+#define NFA_CHO_TEST_VERSION    0x01
+#define NFA_CHO_TEST_RANDOM     0x02
+/*******************************************************************************
+**
+** Function         NFA_ChoSetTestParam
+**
+** Description      This function is called to set test parameters.
+**
+*******************************************************************************/
+NFC_API extern void NFA_ChoSetTestParam (UINT8  test_enable,
+                                         UINT8  test_version,
+                                         UINT16 test_random_number);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_CHO_API_H */
+
diff --git a/src/nfa/include/nfa_ee_api.h b/src/nfa/include/nfa_ee_api.h
new file mode 100644
index 0000000..7098ae3
--- /dev/null
+++ b/src/nfa/include/nfa_ee_api.h
@@ -0,0 +1,453 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface to NFCEE
+ *
+ ******************************************************************************/
+#ifndef NFA_EE_API_H
+#define NFA_EE_API_H
+
+#include "nfc_target.h"
+#include "nfa_api.h"
+#include "nfc_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_MAX_AID_LEN             NFC_MAX_AID_LEN /* 16 per ISO 7816 specification    */
+#define NFA_EE_HANDLE_DH            (NFA_HANDLE_GROUP_EE|NFC_DH_ID)
+
+/* NFA EE callback events */
+enum
+{
+    NFA_EE_DISCOVER_EVT,        /* The status for NFA_EeDiscover ()                      */
+    NFA_EE_REGISTER_EVT,        /* The status for NFA_EeRegister ()                      */
+    NFA_EE_DEREGISTER_EVT,      /* The status for NFA_EeDeregister ()                    */
+    NFA_EE_MODE_SET_EVT,        /* The status for activating or deactivating an NFCEE    */
+    NFA_EE_ADD_AID_EVT,         /* The status for adding an AID to a routing table entry */
+    NFA_EE_REMOVE_AID_EVT,      /* The status for removing an AID from a routing table   */
+    NFA_EE_SET_TECH_CFG_EVT,    /* The status for setting the routing based on RF tech.  */
+    NFA_EE_SET_PROTO_CFG_EVT,   /* The status for setting the routing based on protocols */
+    NFA_EE_CONNECT_EVT,         /* Result of NFA_EeConnect                               */
+    NFA_EE_DATA_EVT,            /* Received data from NFCEE.                             */
+    NFA_EE_DISCONNECT_EVT,      /* NFCEE connection closed.                              */
+    NFA_EE_NEW_EE_EVT,          /* A new NFCEE is discovered                             */
+    NFA_EE_ACTION_EVT,          /* An action happened in NFCEE                           */
+    NFA_EE_DISCOVER_REQ_EVT,    /* NFCEE Discover Request Notification                   */
+    NFA_EE_ROUT_ERR_EVT,        /* Error - exceed NFCC CE Routing size                   */
+    NFA_EE_NO_MEM_ERR_EVT,      /* Error - out of GKI buffers                            */
+    NFA_EE_NO_CB_ERR_EVT        /* Error - Can not find control block or wrong state     */
+};
+typedef UINT8 tNFA_EE_EVT;
+
+/* tNFA_NFCEE_INTERFACE values */
+#define NFA_EE_INTERFACE_APDU         NFC_NFCEE_INTERFACE_APDU          /* APDU Interface       */
+#define NFA_EE_INTERFACE_HCI_ACCESS   NFC_NFCEE_INTERFACE_HCI_ACCESS    /* HCI Access Interface*/
+#define NFA_EE_INTERFACE_T3T          NFC_NFCEE_INTERFACE_T3T           /* T3T Command Interface*/
+#define NFA_EE_INTERFACE_TRANSPARENT  NFC_NFCEE_INTERFACE_TRANSPARENT   /* Transparent Interface*/
+#define NFA_EE_INTERFACE_PROPRIETARY  NFC_NFCEE_INTERFACE_PROPRIETARY   /* Proprietary          */
+typedef UINT8 tNFA_EE_INTERFACE;
+
+#define NFA_EE_TAG_HW_ID             NFC_NFCEE_TAG_HW_ID                /* HW/Registration ID   */
+#define NFA_EE_TAG_ATR_BYTES         NFC_NFCEE_TAG_ATR_BYTES            /* ATR Bytes            */
+#define NFA_EE_TAG_T3T_INFO          NFC_NFCEE_TAG_T3T_INFO             /* T3T Supplement. Info */
+#define NFA_EE_TAG_HCI_HOST_ID       NFC_NFCEE_TAG_HCI_HOST_ID          /* Broadcom Proprietary */
+typedef UINT8 tNFA_EE_TAG;
+
+/* for NFA_EeModeSet () */
+#define NFA_EE_MD_ACTIVATE          NFC_MODE_ACTIVATE
+#define NFA_EE_MD_DEACTIVATE        NFC_MODE_DEACTIVATE
+typedef UINT8 tNFA_EE_MD;
+
+#define NFA_EE_PWR_STATE_ON         0x01    /* The device is on                 */
+#define NFA_EE_PWR_STATE_SWITCH_OFF 0x02    /* The device is switched off       */
+#define NFA_EE_PWR_STATE_BATT_OFF   0x04    /* The device's battery is removed  */
+#define NFA_EE_PWR_STATE_NONE       0       /* used to remove a particular technology or protocol based routing cfg of a handle from the routing table. */
+typedef UINT8 tNFA_EE_PWR_STATE;
+
+
+#define NFA_EE_STATUS_INACTIVE          NFC_NFCEE_STATUS_INACTIVE /* NFCEE connected and inactive */
+#define NFA_EE_STATUS_ACTIVE            NFC_NFCEE_STATUS_ACTIVE   /* NFCEE connected and active   */
+#define NFA_EE_STATUS_REMOVED           NFC_NFCEE_STATUS_REMOVED  /* NFCEE removed                */
+#define NFA_EE_STATUS_PENDING           0x10                      /* waiting for response from NFCC */
+#define NFA_EE_STATUS_ACTIVATING        (NFA_EE_STATUS_PENDING+NFC_NFCEE_STATUS_ACTIVE)
+#define NFA_EE_STATUS_DEACTIVATING      (NFA_EE_STATUS_PENDING+NFC_NFCEE_STATUS_INACTIVE)
+typedef UINT8 tNFA_EE_STATUS;
+
+
+
+/* additional NFCEE Info */
+typedef struct
+{
+    tNFA_EE_TAG             tag;
+    UINT8                   len;
+    UINT8                   info[NFC_MAX_EE_INFO];
+} tNFA_EE_TLV;
+
+typedef struct
+{
+    tNFA_HANDLE         ee_handle;              /* handle for NFCEE oe DH   */
+    tNFA_EE_STATUS      ee_status;              /* The NFCEE status         */
+    UINT8               num_interface;          /* number of NFCEE interface*/
+    tNFA_EE_INTERFACE   ee_interface[NFC_MAX_EE_INTERFACE];/* NFCEE supported interface */
+    UINT8               num_tlvs;               /* number of TLVs           */
+    tNFA_EE_TLV         ee_tlv[NFC_MAX_EE_TLVS];/* the TLV                  */
+} tNFA_EE_INFO;
+
+
+
+typedef struct
+{
+    tNFA_STATUS         status;                         /* NFA_STATUS_OK is successful      */
+    UINT8               num_ee;                         /* number of NFCEEs found           */
+    tNFA_EE_INFO        ee_info[NFA_EE_MAX_EE_SUPPORTED];/*NFCEE information                */
+} tNFA_EE_DISCOVER;
+
+typedef struct
+{
+    tNFA_HANDLE         ee_handle;      /* Handle of NFCEE                                  */
+    tNFA_STATUS         status;         /* NFA_STATUS_OK is successful                      */
+    tNFA_EE_INTERFACE   ee_interface;   /* NFCEE interface associated with this connection  */
+} tNFA_EE_CONNECT;
+
+#define NFA_EE_TRGR_SELECT              NFC_EE_TRIG_7816_SELECT  /* ISO 7816-4 SELECT command */
+#define NFA_EE_TRGR_RF_PROTOCOL         NFC_EE_TRIG_RF_PROTOCOL  /* RF Protocol changed       */
+#define NFA_EE_TRGR_RF_TECHNOLOGY       NFC_EE_TRIG_RF_TECHNOLOGY/* RF Technology changed     */
+#define NFA_EE_TRGR_APP_INIT            NFC_EE_TRIG_APP_INIT     /* Application initiation    */
+typedef tNFC_EE_TRIGGER tNFA_EE_TRIGGER;
+
+/* Union of NFCEE action parameter depending on the associated trigger */
+typedef union
+{
+    tNFA_NFC_PROTOCOL   protocol;   /* NFA_EE_TRGR_RF_PROTOCOL: the protocol that triggers this event */
+    tNFC_RF_TECH        technology; /* NFA_EE_TRGR_RF_TECHNOLOGY:the technology that triggers this event */
+    tNFC_AID            aid;        /* NFA_EE_TRGR_SELECT      : the AID in the received SELECT AID command */
+    tNFC_APP_INIT       app_init;   /* NFA_EE_TRGR_APP_INIT:     The information for the application initiated trigger */
+} tNFA_EE_ACTION_PARAM;
+
+typedef struct
+{
+    tNFA_HANDLE             ee_handle;      /* Handle of NFCEE                  */
+    tNFA_EE_TRIGGER         trigger;        /* the trigger of this event        */
+    tNFA_EE_ACTION_PARAM    param;
+} tNFA_EE_ACTION;
+
+typedef struct
+{
+    tNFA_HANDLE         ee_handle;  /* Handle of NFCEE              */
+    tNFA_STATUS         status;     /* NFA_STATUS_OK is successful  */
+    tNFA_EE_STATUS      ee_status;  /* The NFCEE status             */
+} tNFA_EE_MODE_SET;
+
+typedef struct
+{
+    tNFA_HANDLE         ee_handle;          /* Handle of MFCEE      */
+    tNFA_NFC_PROTOCOL   la_protocol;        /* Listen A protocol    */
+    tNFA_NFC_PROTOCOL   lb_protocol;        /* Listen B protocol    */
+    tNFA_NFC_PROTOCOL   lf_protocol;        /* Listen F protocol    */
+    tNFA_NFC_PROTOCOL   lbp_protocol;       /* Listen B' protocol   */
+} tNFA_EE_DISCOVER_INFO;
+
+/* Data for NFA_EE_DISCOVER_REQ_EVT */
+typedef struct
+{
+    UINT8                   status;                         /* NFA_STATUS_OK if successful   */
+    UINT8                   num_ee;                         /* number of MFCEE information   */
+    tNFA_EE_DISCOVER_INFO   ee_disc_info[NFA_DM_MAX_UICC];  /* MFCEE DISCOVER Request info   */
+} tNFA_EE_DISCOVER_REQ;
+
+
+/* Union of all EE callback structures */
+typedef union
+{
+    tNFA_STATUS             status;             /* NFA_STATUS_OK is successful; otherwise NFA_STATUS_FAILED */
+    tNFA_DATA               data;
+    tNFA_HANDLE             handle;
+    tNFA_EE_DISCOVER        ee_discover;
+    tNFA_STATUS             ee_register;
+    tNFA_STATUS             deregister;
+    tNFA_STATUS             add_aid;
+    tNFA_STATUS             remove_aid;
+    tNFA_STATUS             set_tech;
+    tNFA_STATUS             set_proto;
+    tNFA_EE_CONNECT         connect;
+    tNFA_EE_ACTION          action;
+    tNFA_EE_MODE_SET        mode_set;
+    tNFA_EE_INFO            new_ee;
+    tNFA_EE_DISCOVER_REQ    discover_req;
+} tNFA_EE_CBACK_DATA;
+
+
+/* EE callback */
+typedef void (tNFA_EE_CBACK) (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_EeDiscover
+**
+** Description      This function retrieves the NFCEE information from NFCC.
+**                  The NFCEE information is reported in NFA_EE_DISCOVER_EVT.
+**
+**                  This function may be called when a system supports removable
+**                  NFCEEs,
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeDiscover (tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeGetInfo
+**
+** Description      This function retrieves the NFCEE information from NFA.
+**                  The actual number of NFCEE is returned in p_num_nfcee
+**                  and NFCEE information is returned in p_info
+**
+** Returns          NFA_STATUS_OK if information is retrieved successfully
+**                  NFA_STATUS_FAILED If wrong state (retry later)
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeGetInfo (UINT8        *p_num_nfcee,
+                                          tNFA_EE_INFO *p_info);
+
+/*******************************************************************************
+**
+** Function         NFA_EeRegister
+**
+** Description      This function registers a callback function to receive the
+**                  events from NFA-EE module.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeRegister (tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeDeregister
+**
+** Description      This function de-registers the callback function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeDeregister (tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeModeSet
+**
+** Description      This function is called to activate (mode = NFA_EE_MD_ACTIVATE)
+**                  or deactivate (mode = NFA_EE_MD_DEACTIVATE) the NFCEE
+**                  identified by the given ee_handle. The result of this
+**                  operation is reported with the NFA_EE_MODE_SET_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeModeSet (tNFA_HANDLE    ee_handle,
+                                          tNFA_EE_MD     mode);
+
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultTechRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on RF technology in the listen mode
+**                  routing table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_TECH_CFG_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeSetDefaultTechRouting (tNFA_HANDLE          ee_handle,
+                                                        tNFA_TECHNOLOGY_MASK technologies_switch_on,
+                                                        tNFA_TECHNOLOGY_MASK technologies_switch_off,
+                                                        tNFA_TECHNOLOGY_MASK technologies_battery_off);
+
+/*******************************************************************************
+**
+** Function         NFA_EeSetDefaultProtoRouting
+**
+** Description      This function is called to add, change or remove the
+**                  default routing based on Protocol in the listen mode routing
+**                  table for the given ee_handle. The status of this
+**                  operation is reported as the NFA_EE_SET_PROTO_CFG_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeSetDefaultProtoRouting (tNFA_HANDLE         ee_handle,
+                                                         tNFA_PROTOCOL_MASK  protocols_switch_on,
+                                                         tNFA_PROTOCOL_MASK  protocols_switch_off,
+                                                         tNFA_PROTOCOL_MASK  protocols_battery_off);
+
+/*******************************************************************************
+**
+** Function         NFA_EeAddAidRouting
+**
+** Description      This function is called to add an AID entry in the
+**                  listen mode routing table in NFCC. The status of this
+**                  operation is reported as the NFA_EE_ADD_AID_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeAddAidRouting (tNFA_HANDLE          ee_handle,
+                                                UINT8                aid_len,
+                                                UINT8               *p_aid,
+                                                tNFA_EE_PWR_STATE    power_state);
+
+/*******************************************************************************
+**
+** Function         NFA_EeRemoveAidRouting
+**
+** Description      This function is called to remove the given AID entry from the
+**                  listen mode routing table. If the entry configures VS,
+**                  it is also removed. The status of this operation is reported
+**                  as the NFA_EE_REMOVE_AID_EVT.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Note:            NFA_EeUpdateNow() should be called after last NFA-EE function
+**                  to change the listen mode routing is called.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeRemoveAidRouting (UINT8     aid_len,
+                                                   UINT8    *p_aid);
+
+/*******************************************************************************
+**
+** Function         NFA_EeUpdateNow
+**
+** Description      This function is called to send the current listen mode
+**                  routing table and VS configuration to the NFCC
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeUpdateNow (void);
+
+/*******************************************************************************
+**
+** Function         NFA_EeConnect
+**
+** Description      Open connection to an NFCEE attached to the NFCC
+**
+**                  The status of this operation is
+**                  reported with the NFA_EE_CONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeConnect (tNFA_HANDLE    ee_handle,
+                                          UINT8          ee_interface,
+                                          tNFA_EE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_EeSendData
+**
+** Description      Send data to the given NFCEE.
+**                  This function shall be called after NFA_EE_CONNECT_EVT is reported
+**                  and before NFA_EeDisconnect is called on the given ee_handle.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeSendData (tNFA_HANDLE  ee_handle,
+                                           UINT16       data_len,
+                                           UINT8       *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_EeDisconnect
+**
+** Description      Disconnect (if a connection is currently open) from an
+**                  NFCEE interface. The result of this operation is reported
+**                  with the NFA_EE_DISCONNECT_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**                  NFA_STATUS_INVALID_PARAM If bad parameter
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_EeDisconnect (tNFA_HANDLE ee_handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_EE_API_H */
+
diff --git a/src/nfa/include/nfa_hci_api.h b/src/nfa/include/nfa_hci_api.h
new file mode 100644
index 0000000..a8b3fcc
--- /dev/null
+++ b/src/nfa/include/nfa_hci_api.h
@@ -0,0 +1,610 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA HCI, Broadcom's NFC
+ *  application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_HCI_API_H
+#define NFA_HCI_API_H
+
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* NFA HCI Debug constants */
+#define NFA_HCI_DEBUG_DISPLAY_CB                0
+#define NFA_HCI_DEBUG_SIM_HCI_EVENT             1
+#define NFA_HCI_DEBUG_ENABLE_LOOPBACK           101
+#define NFA_HCI_DEBUG_DISABLE_LOOPBACK          102
+
+/* NFA HCI callback events */
+#define NFA_HCI_REGISTER_EVT	                0x00    /* Application registered                       */
+#define NFA_HCI_DEREGISTER_EVT                  0x01    /* Application deregistered                     */
+#define NFA_HCI_GET_GATE_PIPE_LIST_EVT          0x02    /* Retrieved gates,pipes assoc. to application  */
+#define NFA_HCI_ALLOCATE_GATE_EVT	            0x03    /* A generic gate allocated to the application  */
+#define NFA_HCI_DEALLOCATE_GATE_EVT	            0x04    /* A generic gate is released                   */
+#define NFA_HCI_CREATE_PIPE_EVT         	    0x05    /* Pipe is created                              */
+#define NFA_HCI_OPEN_PIPE_EVT         	        0x06    /* Pipe is opened / could not open              */
+#define NFA_HCI_CLOSE_PIPE_EVT         	        0x07    /* Pipe is closed / could not close             */
+#define NFA_HCI_DELETE_PIPE_EVT         	    0x08    /* Pipe is deleted                              */
+#define NFA_HCI_HOST_LIST_EVT       	        0x09    /* Received list of Host from Host controller   */
+#define NFA_HCI_INIT_EVT                        0x0A    /* HCI subsytem initialized                     */
+#define NFA_HCI_EXIT_EVT                        0x0B    /* HCI subsytem exited                          */
+#define NFA_HCI_RSP_RCVD_EVT                    0x0C    /* Response recvd to cmd sent on app owned pipe */
+#define NFA_HCI_RSP_SENT_EVT                    0x0D    /* Response sent on app owned pipe              */
+#define NFA_HCI_CMD_SENT_EVT                    0x0E    /* Command sent on app owned pipe               */
+#define NFA_HCI_EVENT_SENT_EVT                  0x0F    /* Event sent on app owned pipe                 */
+#define NFA_HCI_CMD_RCVD_EVT                    0x10    /* Command received on app owned pipe           */
+#define NFA_HCI_EVENT_RCVD_EVT                  0x11    /* Event received on app owned pipe             */
+#define NFA_HCI_GET_REG_CMD_EVT                 0x12    /* Registry read command sent                   */
+#define NFA_HCI_SET_REG_CMD_EVT                 0x13    /* Registry write command sent                  */
+#define NFA_HCI_GET_REG_RSP_EVT                 0x14    /* Received response to read registry command   */
+#define NFA_HCI_SET_REG_RSP_EVT                 0x15    /* Received response to write registry command  */
+#define NFA_HCI_ADD_STATIC_PIPE_EVT             0x16    /* A static pipe is added                       */
+
+typedef UINT8 tNFA_HCI_EVT;
+
+#define NFA_MAX_HCI_APP_NAME_LEN                0x10    /* Max application name length */
+#define NFA_MAX_HCI_CMD_LEN                     255     /* Max HCI command length */
+#define NFA_MAX_HCI_RSP_LEN                     255     /* Max HCI event length */
+#define NFA_MAX_HCI_EVENT_LEN                   260     /* Max HCI event length */
+#define NFA_MAX_HCI_DATA_LEN                    260     /* Max HCI data length */
+
+/* NFA HCI PIPE states */
+#define NFA_HCI_PIPE_CLOSED                         0x00     /* Pipe is closed */
+#define NFA_HCI_PIPE_OPENED                         0x01     /* Pipe is opened */
+
+typedef UINT8 tNFA_HCI_PIPE_STATE;
+/* Dynamic pipe control block */
+typedef struct
+{
+    UINT8                   pipe_id;                /* Pipe ID */
+    tNFA_HCI_PIPE_STATE     pipe_state;             /* State of the Pipe */
+    UINT8                   local_gate;             /* local gate id */
+    UINT8                   dest_host;              /* Peer host to which this pipe is connected */
+    UINT8                   dest_gate;              /* Peer gate to which this pipe is connected */
+} tNFA_HCI_PIPE_INFO;
+
+/* Data for NFA_HCI_REGISTER_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;
+    tNFA_HANDLE         hci_handle;
+    UINT8               num_pipes;
+    UINT8               num_gates;
+} tNFA_HCI_REGISTER;
+
+/* Data for NFA_HCI_DEREGISTER_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;
+} tNFA_HCI_DEREGISTER;
+
+/* Data for NFA_HCI_GET_GATE_PIPE_LIST_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;
+    UINT8               num_pipes;
+    tNFA_HCI_PIPE_INFO  pipe[NFA_HCI_MAX_PIPE_CB];
+    UINT8               num_gates;
+    UINT8               gate[NFA_HCI_MAX_GATE_CB];
+
+} tNFA_HCI_GET_GATE_PIPE_LIST;
+
+/* Data for NFA_HCI_ALLOCATE_GATE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           gate;
+} tNFA_HCI_ALLOCATE_GATE;
+
+/* Data for NFA_HCI_DEALLOCATE_GATE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           gate;
+} tNFA_HCI_DEALLOCATE_GATE;
+
+/* Data for NFA_HCI_CREATE_PIPE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+    UINT8           source_gate;
+    UINT8           dest_host;
+    UINT8           dest_gate;
+} tNFA_HCI_CREATE_PIPE;
+
+/* Data for NFA_HCI_OPEN_PIPE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+}tNFA_HCI_OPEN_PIPE;
+
+/* Data for NFA_HCI_CLOSE_PIPE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+}tNFA_HCI_CLOSE_PIPE;
+
+/* Data for NFA_HCI_DELETE_PIPE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+} tNFA_HCI_DELETE_PIPE;
+
+/* Data for NFA_HCI_HOST_LIST_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           num_hosts;
+    UINT8           host[NFA_HCI_MAX_HOST_IN_NETWORK];
+} tNFA_HCI_HOST_LIST;
+
+/* Data for NFA_HCI_RSP_RCVD_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+    UINT8           rsp_code;
+    UINT16          rsp_len;
+    UINT8           rsp_data[NFA_MAX_HCI_RSP_LEN];
+} tNFA_HCI_RSP_RCVD;
+
+/* Data for NFA_HCI_EVENT_RCVD_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+    UINT8           evt_code;
+    UINT16          evt_len;
+    UINT8           *p_evt_buf;
+} tNFA_HCI_EVENT_RCVD;
+
+/* Data for NFA_HCI_CMD_RCVD_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+    UINT8           pipe;
+    UINT8           cmd_code;
+    UINT16          cmd_len;
+    UINT8           cmd_data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_CMD_RCVD;
+
+/* Data for NFA_HCI_INIT_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+} tNFA_HCI_INIT;
+
+/* Data for NFA_HCI_EXIT_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+} tNFA_HCI_EXIT;
+
+/* Data for NFA_HCI_RSP_SENT_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+} tNFA_HCI_RSP_SENT;
+
+/* Data for NFA_HCI_CMD_SENT_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+} tNFA_HCI_CMD_SENT;
+
+/* Data for NFA_HCI_EVENT_SENT_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+} tNFA_HCI_EVENT_SENT;
+
+/* Data for NFA_HCI_ADD_STATIC_PIPE_EVT */
+typedef struct
+{
+    tNFA_STATUS     status;
+} tNFA_HCI_ADD_STATIC_PIPE_EVT;
+
+/* data type for all registry-related events */
+typedef struct
+{
+    tNFA_STATUS         status;
+    UINT8               pipe;
+    UINT8               index;
+    UINT8               data_len;
+    UINT8               reg_data[NFA_MAX_HCI_DATA_LEN];
+} tNFA_HCI_REGISTRY;
+
+
+/* Union of all hci callback structures */
+typedef union
+{
+    tNFA_HCI_REGISTER               hci_register;   /* NFA_HCI_REGISTER_EVT           */
+    tNFA_HCI_DEREGISTER             hci_deregister; /* NFA_HCI_DEREGISTER_EVT         */
+    tNFA_HCI_GET_GATE_PIPE_LIST     gates_pipes;    /* NFA_HCI_GET_GATE_PIPE_LIST_EVT */
+    tNFA_HCI_ALLOCATE_GATE          allocated;      /* NFA_HCI_ALLOCATE_GATE_EVT      */
+    tNFA_HCI_DEALLOCATE_GATE        deallocated;    /* NFA_HCI_DEALLOCATE_GATE_EVT    */
+    tNFA_HCI_CREATE_PIPE            created;        /* NFA_HCI_CREATE_PIPE_EVT        */
+    tNFA_HCI_OPEN_PIPE              opened;         /* NFA_HCI_OPEN_PIPE_EVT          */
+    tNFA_HCI_CLOSE_PIPE             closed;         /* NFA_HCI_CLOSE_PIPE_EVT         */
+    tNFA_HCI_DELETE_PIPE            deleted;        /* NFA_HCI_DELETE_PIPE_EVT        */
+    tNFA_HCI_HOST_LIST              hosts;          /* NFA_HCI_HOST_LIST_EVT          */
+    tNFA_HCI_RSP_RCVD               rsp_rcvd;       /* NFA_HCI_RSP_RCVD_EVT           */
+    tNFA_HCI_RSP_SENT               rsp_sent;       /* NFA_HCI_RSP_SENT_EVT           */
+    tNFA_HCI_CMD_SENT               cmd_sent;       /* NFA_HCI_CMD_SENT_EVT           */
+    tNFA_HCI_EVENT_SENT             evt_sent;       /* NFA_HCI_EVENT_SENT_EVT         */
+    tNFA_HCI_CMD_RCVD               cmd_rcvd;       /* NFA_HCI_CMD_RCVD_EVT           */
+    tNFA_HCI_EVENT_RCVD             rcvd_evt;       /* NFA_HCI_EVENT_RCVD_EVT         */
+    tNFA_STATUS                     status;         /* status of api command request  */
+    tNFA_HCI_REGISTRY               registry;       /* all registry-related events    */
+    tNFA_HCI_INIT                   hci_init;       /* NFA_HCI_INIT_EVT               */
+    tNFA_HCI_EXIT                   hci_exit;       /* NFA_HCI_EXIT_EVT               */
+    tNFA_HCI_ADD_STATIC_PIPE_EVT    pipe_added;     /* NFA_HCI_ADD_STATIC_PIPE_EVT    */
+} tNFA_HCI_EVT_DATA;
+
+/* NFA HCI callback */
+typedef void (tNFA_HCI_CBACK) (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*******************************************************************************
+**
+** Function         NFA_HciRegister
+**
+** Description      This function will register an application with hci and
+**                  returns an application handle and provides a mechanism to
+**                  register a callback with HCI to receive NFA HCI event notification.
+**                  When the application is registered (or if an error occurs),
+**                  the app will be notified with NFA_HCI_REGISTER_EVT. Previous
+**                  session information including allocated gates, created pipes
+**                  and pipes states will be returned as part of tNFA_HCI_REGISTER data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciRegister (char *p_app_name, tNFA_HCI_CBACK *p_cback, BOOLEAN b_send_conn_evts);
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetGateAndPipeList
+**
+** Description      This function will retrieve the list of gates allocated to
+**                  the application and list of dynamic pipes created for the
+**                  application. The app will be notified with
+**                  NFA_HCI_GET_GATE_PIPE_LIST_EVT. List of allocated dynamic
+**                  gates to the application and list of pipes created by the
+**                  application will be returned as part of
+**                  tNFA_HCI_GET_GATE_PIPE_LIST data.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciGetGateAndPipeList (tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeregister
+**
+** Description      This function is called to deregister an application
+**                  from HCI. The app will be notified by NFA_HCI_DEREGISTER_EVT
+**                  after deleting all the pipes owned by the app and deallocating
+**                  all the gates allocated to the app or if an error occurs.
+**                  The app can release the buffer provided for collecting long
+**                  APDUs after receiving NFA_HCI_DEREGISTER_EVT.
+**                  Even if deregistration fails, the app has to register again
+**                  to provide a new cback function and event buffer for receiving
+**                  long APDUs.
+**
+** Returns          NFA_STATUS_OK if the application is deregistered successfully
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciDeregister (char *p_app_name);
+
+/*******************************************************************************
+**
+** Function         NFA_HciAllocGate
+**
+** Description      This function will allocate an available generic gate for
+**                  the app to provide an entry point for a particular service
+**                  to other host or to establish communication with other host.
+**                  When the generic gate is allocated (or if an error occurs),
+**                  the app will be notified with NFA_HCI_ALLOCATE_GATE_EVT with
+**                  the gate id. The allocated Gate information will be stored in
+**                  non volatile memory.
+**
+** Returns          NFA_STATUS_OK if this API started
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED if no generic gate is available
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciAllocGate (tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeallocGate
+**
+** Description      This function will release the specified gate that was
+**                  previously allocated to the application. When the generic
+**                  gate is released (or if an error occurs), the app will be
+**                  notified with NFA_HCI_DEALLOCATE_GATE_EVT with the gate id.
+**                  The allocated Gate information will be deleted from non
+**                  volatile memory and all the associated pipes are deleted
+**                  by informing host controller.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciDeallocGate (tNFA_HANDLE conn_handle, UINT8 gate);
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetHostList
+**
+** Description      This function will request the host controller to return the
+**                  list of hosts that are present in the host network. When
+**                  host controller responds with the host list (or if an error
+**                  occurs), the app will be notified with NFA_HCI_HOST_LIST_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciGetHostList (tNFA_HANDLE hci_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_HciCreatePipe
+**
+** Description      This function is called to create a dynamic pipe with the
+**                  specified host. When the dynamic pipe is created (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CREATE_PIPE_EVT with the pipe id. If a pipe exists
+**                  between the two gates passed as argument and if it was
+**                  created earlier by the calling application then the pipe
+**                  id of the existing pipe will be returned and a new pipe
+**                  will not be created. After successful creation of pipe,
+**                  registry entry will be created for the dynamic pipe and
+**                  all information related to the pipe will be stored in non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciCreatePipe (tNFA_HANDLE  hci_handle,
+                                              UINT8        source_gate_id,
+                                              UINT8        dest_host,
+                                              UINT8        dest_gate);
+
+/*******************************************************************************
+**
+** Function         NFA_HciOpenPipe
+**
+** Description      This function is called to open a dynamic pipe.
+**                  When the dynamic pipe is opened (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_OPEN_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciOpenPipe (tNFA_HANDLE  hci_handle, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciGetRegistry
+**
+** Description      This function requests a peer host to return the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_GET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciGetRegistry (tNFA_HANDLE hci_handle, UINT8 pipe, UINT8 reg_inx);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSetRegistry
+**
+** Description      This function requests a peer host to set the desired
+**                  registry field value for the gate that the pipe is on.
+**
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_SET_REG_RSP_EVT or
+**                  if an error occurs in sending the command the app will be
+**                  notified by NFA_HCI_CMD_SENT_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSetRegistry (tNFA_HANDLE   hci_handle,
+                                               UINT8         pipe,
+                                               UINT8         reg_inx,
+                                               UINT8         data_size,
+                                               UINT8         *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendCommand
+**
+** Description      This function is called to send a command on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_CMD_SENT_EVT if an error
+**                  occurs.
+**                  When the peer host responds,the app is notified with
+**                  NFA_HCI_RSP_RCVD_EVT
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendCommand (tNFA_HANDLE hci_handle,
+                                               UINT8       pipe,
+                                               UINT8       cmd_code,
+                                               UINT16      cmd_size,
+                                               UINT8       *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendResponse
+**
+** Description      This function is called to send a response on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_RSP_SENT_EVT if an error
+**                  occurs.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendResponse (tNFA_HANDLE   hci_handle,
+                                                UINT8         pipe,
+                                                UINT8         response,
+                                                UINT8         data_size,
+                                                UINT8         *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_HciSendEvent
+**
+** Description      This function is called to send any event on a pipe created
+**                  by the application.
+**                  The app will be notified by NFA_HCI_EVENT_SENT_EVT
+**                  after successfully sending the event on the specified pipe
+**                  or if an error occurs. The application should wait for this
+**                  event before releasing event buffer passed as argument.
+**                  If the app is expecting a response to the event then it can
+**                  provide response buffer for collecting the response. If it
+**                  provides a response buffer it should also provide response
+**                  timeout indicating duration validity of the response buffer.
+**                  Maximum of NFA_MAX_HCI_EVENT_LEN bytes APDU can be received
+**                  using internal buffer if no response buffer is provided by
+**                  the application. The app will be notified by
+**                  NFA_HCI_EVENT_RCVD_EVT after receiving the response event
+**                  or on timeout if app provided response buffer.
+**                  If response buffer is provided by the application, it should
+**                  wait for this event before releasing the response buffer.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciSendEvent (tNFA_HANDLE hci_handle,
+                                            UINT8        pipe,
+                                            UINT8        evt_code,
+                                            UINT16       evt_size,
+                                            UINT8        *p_data,
+                                            UINT16       rsp_size,
+                                            UINT8        *p_rsp_buf,
+                                            UINT16       rsp_timeout);
+
+/*******************************************************************************
+**
+** Function         NFA_HciClosePipe
+**
+** Description      This function is called to close a dynamic pipe.
+**                  When the dynamic pipe is closed (or
+**                  if an error occurs), the app will be notified with
+**                  NFA_HCI_CLOSE_PIPE_EVT with the pipe id.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciClosePipe (tNFA_HANDLE  hci_handle, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDeletePipe
+**
+** Description      This function is called to delete a particular dynamic pipe.
+**                  When the dynamic pipe is deleted (or if an error occurs),
+**                  the app will be notified with NFA_HCI_DELETE_PIPE_EVT with
+**                  the pipe id. After successful deletion of pipe, registry
+**                  entry will be deleted for the dynamic pipe and all
+**                  information related to the pipe will be deleted from non
+**                  volatile memory.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciDeletePipe (tNFA_HANDLE  hci_handle, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciAddStaticPipe
+**
+** Description      This function is called to add a static pipe for sending
+**                  7816 APDUs. When the static pipe is added (or if an error occurs),
+**                  the app will be notified with NFA_HCI_ADD_STATIC_PIPE_EVT with
+**                  status.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_HciAddStaticPipe (tNFA_HANDLE hci_handle, UINT8 host, UINT8 gate, UINT8 pipe);
+
+/*******************************************************************************
+**
+** Function         NFA_HciDebug
+**
+** Description      Debug function.
+**
+*******************************************************************************/
+NFC_API extern void NFA_HciDebug (UINT8 action, UINT8 size, UINT8 *p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
+
diff --git a/src/nfa/include/nfa_hci_defs.h b/src/nfa/include/nfa_hci_defs.h
new file mode 100644
index 0000000..088837f
--- /dev/null
+++ b/src/nfa/include/nfa_hci_defs.h
@@ -0,0 +1,125 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the NFA HCI related definitions from the
+ *  specification.
+ *
+ ******************************************************************************/
+
+#ifndef NFA_HCI_DEFS_H
+#define NFA_HCI_DEFS_H
+
+/* Static gates */
+#define NFA_HCI_LOOP_BACK_GATE              0x04
+#define NFA_HCI_IDENTITY_MANAGEMENT_GATE    0x05
+
+#define NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE    0x10
+#define NFA_HCI_LAST_HOST_SPECIFIC_GENERIC_GATE     0xEF
+#define NFA_HCI_LAST_PROP_GATE                      0xFF
+
+/* Generic Gates */
+#define NFA_HCI_CONNECTIVITY_GATE           0x41
+
+/* Static pipes */
+#define NFA_HCI_LINK_MANAGEMENT_PIPE        0x00
+#define NFA_HCI_ADMIN_PIPE                  0x01
+
+/* Dynamic pipe range */
+#define NFA_HCI_FIRST_DYNAMIC_PIPE          0x02
+#define NFA_HCI_LAST_DYNAMIC_PIPE           0x6F
+
+/* host_table */
+#define NFA_HCI_HOST_CONTROLLER             0x00
+#define NFA_HCI_DH_HOST                     0x01
+#define NFA_HCI_UICC_HOST                   0x02
+
+/* Type of instruction */
+#define NFA_HCI_COMMAND_TYPE                0x00
+#define NFA_HCI_EVENT_TYPE                  0x01
+#define NFA_HCI_RESPONSE_TYPE               0x02
+
+/* Chaining bit value */
+#define NFA_HCI_MESSAGE_FRAGMENTATION       0x00
+#define NFA_HCI_NO_MESSAGE_FRAGMENTATION    0x01
+
+/* NFA HCI commands */
+
+/* Commands for all gates */
+#define NFA_HCI_ANY_SET_PARAMETER           0x01
+#define NFA_HCI_ANY_GET_PARAMETER           0x02
+#define NFA_HCI_ANY_OPEN_PIPE               0x03
+#define NFA_HCI_ANY_CLOSE_PIPE              0x04
+
+/* Admin gate commands */
+#define NFA_HCI_ADM_CREATE_PIPE             0x10
+#define NFA_HCI_ADM_DELETE_PIPE             0x11
+#define NFA_HCI_ADM_NOTIFY_PIPE_CREATED     0x12
+#define NFA_HCI_ADM_NOTIFY_PIPE_DELETED     0x13
+#define NFA_HCI_ADM_CLEAR_ALL_PIPE          0x14
+#define NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED 0x15
+
+/* Connectivity gate command */
+#define NFA_HCI_CON_PRO_HOST_REQUEST        0x10
+
+
+/* NFA HCI responses */
+#define NFA_HCI_ANY_OK                      0x00
+#define NFA_HCI_ANY_E_NOT_CONNECTED         0x01
+#define NFA_HCI_ANY_E_CMD_PAR_UNKNOWN       0x02
+#define NFA_HCI_ANY_E_NOK                   0x03
+#define NFA_HCI_ADM_E_NO_PIPES_AVAILABLE    0x04
+#define NFA_HCI_ANY_E_REG_PAR_UNKNOWN       0x05
+#define NFA_HCI_ANY_E_PIPE_NOT_OPENED       0x06
+#define NFA_HCI_ANY_E_CMD_NOT_SUPPORTED     0x07
+#define NFA_HCI_ANY_E_INHIBITED             0x08
+#define NFA_HCI_ANY_E_TIMEOUT               0x09
+#define NFA_HCI_ANY_E_REG_ACCESS_DENIED     0x0A
+#define NFA_HCI_ANY_E_PIPE_ACCESS_DENIED    0x0B
+
+/* NFA HCI Events */
+#define NFA_HCI_EVT_HCI_END_OF_OPERATION    0x01
+#define NFA_HCI_EVT_POST_DATA               0x02
+#define NFA_HCI_EVT_HOT_PLUG                0x03
+
+
+/* NFA HCI Connectivity gate Events */
+#define NFA_HCI_EVT_CONNECTIVITY            0x10
+#define NFA_HCI_EVT_TRANSACTION             0x12
+#define NFA_HCI_EVT_OPERATION_ENDED         0x13
+
+/* Host controller Admin gate registry identifiers */
+#define NFA_HCI_SESSION_IDENTITY_INDEX      0x01
+#define NFA_HCI_MAX_PIPE_INDEX              0x02
+#define NFA_HCI_WHITELIST_INDEX             0x03
+#define NFA_HCI_HOST_LIST_INDEX             0x04
+
+/* Host controller and DH Link management gate registry identifier */
+#define NFA_HCI_REC_ERROR_INDEX             0x02
+
+/* DH Identity management gate registry identifier */
+#define NFA_HCI_VERSION_SW_INDEX            0x01
+#define NFA_HCI_VERSION_HW_INDEX            0x03
+#define NFA_HCI_VENDOR_NAME_INDEX           0x04
+#define NFA_HCI_MODEL_ID_INDEX              0x05
+#define NFA_HCI_HCI_VERSION_INDEX           0x02
+#define NFA_HCI_GATES_LIST_INDEX            0x06
+
+
+#endif /* NFA_HCI_DEFS_H */
diff --git a/src/nfa/include/nfa_mem_co.h b/src/nfa/include/nfa_mem_co.h
new file mode 100644
index 0000000..5b3686d
--- /dev/null
+++ b/src/nfa/include/nfa_mem_co.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Callout functions for memory allocation/deallocatoin
+ *
+ ******************************************************************************/
+#ifndef NFA_MEM_CO_H
+#define NFA_MEM_CO_H
+
+#include "nfc_target.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_alloc
+**
+** Description      allocate a buffer from platform's memory pool
+**
+** Returns:
+**                  pointer to buffer if successful
+**                  NULL otherwise
+**
+*******************************************************************************/
+NFC_API extern void *nfa_mem_co_alloc (UINT32 num_bytes);
+
+
+/*******************************************************************************
+**
+** Function         nfa_mem_co_free
+**
+** Description      free buffer previously allocated using nfa_mem_co_alloc
+**
+** Returns:
+**                  Nothing
+**
+*******************************************************************************/
+NFC_API extern void nfa_mem_co_free (void *p_buf);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_MEM_CO_H */
+
diff --git a/src/nfa/include/nfa_nv_ci.h b/src/nfa/include/nfa_nv_ci.h
new file mode 100644
index 0000000..7b49ed0
--- /dev/null
+++ b/src/nfa/include/nfa_nv_ci.h
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for non valtile memory call-in functions.
+ *
+ ******************************************************************************/
+#ifndef NFA_NV_CI_H
+#define NFA_NV_CI_H
+
+#include "nfa_nv_co.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Read Ready Event */
+typedef struct
+{
+    BT_HDR            hdr;
+    tNFA_NV_CO_STATUS status;
+    int               fd;
+    UINT16            num_read;
+} tNFA_NV_CI_READ_EVT;
+
+/* Write Ready Event */
+typedef struct
+{
+    BT_HDR            hdr;
+    tNFA_NV_CO_STATUS status;
+    int               fd;
+} tNFA_NV_CI_WRITE_EVT;
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_write
+**
+** Description      This function sends an event to NFAA indicating the phone
+**                  has written the number of bytes specified in the call-out
+**                  function, nfa_nv_co_write (), and is ready for more data.
+**                  This function is used to control the TX data flow.
+**                  Note: The data buffer is released by the stack aioer
+**                        calling this function.
+**
+** Parameters       status - NFA_NV_CO_OK, NFA_NV_CO_NOSPACE, or NFA_NV_CO_FAIL
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_ci_write (tNFA_NV_CO_STATUS status);
+
+/*******************************************************************************
+**
+** Function         nfa_nv_ci_read
+**
+** Description      This function sends an event to NFA indicating the phone has
+**                  read in the requested amount of data specified in the
+**                  nfa_nv_co_read () call-out function.  It should only be called
+**                  when the requested number of bytes has been read.
+**
+** Parameters       num_bytes_read - number of bytes read into the buffer
+**                      specified in the read callout-function.
+**                  status - NFA_NV_CO_OK if full buffer of data,
+**                           NFA_NV_CO_EOF if the end of file has been reached,
+**                           NFA_NV_CO_FAIL if an error has occurred.
+**                  evt - Used Internally by NFA -> MUST be same value passed
+**                       in call-out function.
+**
+** Returns          void
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_ci_read (UINT16            num_bytes_read,
+                                    tNFA_NV_CO_STATUS status,
+                                    UINT8             block);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BTA_FS_CI_H */
+
diff --git a/src/nfa/include/nfa_nv_co.h b/src/nfa/include/nfa_nv_co.h
new file mode 100644
index 0000000..9ed5093
--- /dev/null
+++ b/src/nfa/include/nfa_nv_co.h
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the interface file for the synchronization server call-out
+ *  functions.
+ *
+ ******************************************************************************/
+#ifndef NFA_NV_CO_H
+#define NFA_NV_CO_H
+
+#include <time.h>
+
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and Data Types
+*****************************************************************************/
+
+
+/**************************
+**  Common Definitions
+***************************/
+
+/* Status codes returned by call-out functions, or in call-in functions as status */
+#define NFA_NV_CO_OK            0x00
+#define NFA_NV_CO_FAIL          0x01 /* Used to pass all other errors */
+#define NFA_NV_CO_EACCES        0x02
+#define NFA_NV_CO_ENOTEMPTY     0x03
+#define NFA_NV_CO_EOF           0x04
+#define NFA_NV_CO_EODIR         0x05
+#define NFA_NV_CO_ENOSPACE      0x06 /* Returned in nfa_nv_ci_open if no room */
+#define NFA_NV_CO_EIS_DIR       0x07
+#define NFA_NV_CO_RESUME        0x08 /* used in nfa_nv_ci_open, on resume */
+#define NFA_NV_CO_NONE          0x09 /* used in nfa_nv_ci_open, on resume (no file to resume) */
+
+typedef UINT8 tNFA_NV_CO_STATUS;
+
+
+#define  DH_NV_BLOCK            0x01
+#define  HC_F3_NV_BLOCK         0x02
+#define  HC_F4_NV_BLOCK         0x03
+#define  HC_DH_NV_BLOCK         0x04
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+/**************************
+**  Common Functions
+***************************/
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_read
+**
+** Description      This function is called by NFA to read in data from the
+**                  previously opened file.
+**
+** Parameters       p_buf   - buffer to read the data into.
+**                  nbytes  - number of bytes to read into the buffer.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_read () is
+**                        called with the buffer of data, along with the number
+**                        of bytes read into the buffer, and a status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been read, the end of file has been detected,
+**                        or an error has occurred.
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+/*******************************************************************************
+**
+** Function         nfa_nv_co_write
+**
+** Description      This function is called by io to send file data to the
+**                  phone.
+**
+** Parameters       p_buf   - buffer to read the data from.
+**                  nbytes  - number of bytes to write out to the file.
+**
+** Returns          void
+**
+**                  Note: Upon completion of the request, nfa_nv_ci_write () is
+**                        called with the file descriptor and the status.  The
+**                        call-in function should only be called when ALL requested
+**                        bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+NFC_API extern void nfa_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block);
+
+
+#endif /* NFA_NV_CO_H */
diff --git a/src/nfa/include/nfa_p2p_api.h b/src/nfa/include/nfa_p2p_api.h
new file mode 100644
index 0000000..4134e8d
--- /dev/null
+++ b/src/nfa/include/nfa_p2p_api.h
@@ -0,0 +1,575 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA P2P, Broadcom's NFC
+ *  application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_P2P_API_H
+#define NFA_P2P_API_H
+
+#include "llcp_api.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* NFA P2P Reason of disconnection */
+#define NFA_P2P_DISC_REASON_REMOTE_INITIATE	    0x00    /* remote initiated to disconnect  */
+#define NFA_P2P_DISC_REASON_LOCAL_INITITATE	    0x01    /* local initiated to disconnect   */
+#define NFA_P2P_DISC_REASON_NO_SERVICE	        0x02    /* no service bound in remote      */
+#define NFA_P2P_DISC_REASON_REMOTE_REJECT	    0x03    /* remote rejected connection      */
+#define NFA_P2P_DISC_REASON_FRAME_ERROR	        0x04    /* sending or receiving FRMR PDU   */
+#define NFA_P2P_DISC_REASON_LLCP_DEACTIVATED	0x05    /* LLCP link deactivated           */
+#define NFA_P2P_DISC_REASON_NO_RESOURCE	        0x06    /* Out of resource in local device */
+#define NFA_P2P_DISC_REASON_NO_INFORMATION	    0x80    /* Without information             */
+
+/* NFA P2P callback events */
+#define NFA_P2P_REG_SERVER_EVT      0x00    /* Server is registered                         */
+#define NFA_P2P_REG_CLIENT_EVT      0x01    /* Client is registered                         */
+#define NFA_P2P_ACTIVATED_EVT       0x02    /* LLCP Link has been activated                 */
+#define NFA_P2P_DEACTIVATED_EVT	    0x03    /* LLCP Link has been deactivated               */
+#define NFA_P2P_CONN_REQ_EVT        0x04    /* Data link connection request from peer       */
+#define NFA_P2P_CONNECTED_EVT       0x05    /* Data link connection has been established    */
+#define NFA_P2P_DISC_EVT            0x06    /* Data link connection has been disconnected   */
+#define NFA_P2P_DATA_EVT            0x07    /* Data received from peer                      */
+#define NFA_P2P_CONGEST_EVT         0x08    /* Status indication of outgoing data           */
+#define NFA_P2P_LINK_INFO_EVT       0x09    /* link MIU and Well-Known Service list         */
+#define NFA_P2P_SDP_EVT	            0x0A    /* Remote SAP of SDP result                     */
+
+typedef UINT8 tNFA_P2P_EVT;
+
+/* NFA allocates a SAP for server */
+#define NFA_P2P_ANY_SAP         LLCP_INVALID_SAP
+#define NFA_P2P_INVALID_SAP     LLCP_INVALID_SAP
+
+/* Recommanded MIU's for connection-oriented */
+#define NFA_P2P_MIU_1           (NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_2           (2*NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_3           (3*NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+#define NFA_P2P_MIU_8           (8*NCI_NFC_DEP_MAX_DATA - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE)
+
+#define NFA_P2P_LLINK_TYPE      LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+#define NFA_P2P_DLINK_TYPE      LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+typedef UINT8 tNFA_P2P_LINK_TYPE;
+
+/* Data for NFA_P2P_REG_SERVER_EVT */
+typedef struct
+{
+    tNFA_HANDLE     server_handle;     /* NFA_HANDLE_INVALID if failed */
+    char            service_name[LLCP_MAX_SN_LEN + 1];
+    UINT8           server_sap;
+} tNFA_P2P_REG_SERVER;
+
+/* Data for NFA_P2P_REG_CLIENT_EVT */
+typedef struct
+{
+    tNFA_HANDLE     client_handle;     /* NFA_HANDLE_INVALID if failed */
+} tNFA_P2P_REG_CLIENT;
+
+/* Data for NFA_P2P_ACTIVATED_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+    UINT16          local_link_miu;
+    UINT16          remote_link_miu;
+} tNFA_P2P_ACTIVATED;
+
+/* Data for NFA_P2P_DEACTIVATED_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+} tNFA_P2P_DEACTIVATED;
+
+/* Data for NFA_P2P_CONN_REQ_EVT */
+typedef struct
+{
+    tNFA_HANDLE     server_handle;
+    tNFA_HANDLE     conn_handle;
+    UINT8           remote_sap;
+    UINT16          remote_miu;
+    UINT8           remote_rw;
+} tNFA_P2P_CONN_REQ;
+
+/* Data for NFA_P2P_CONNECTED_EVT */
+typedef struct
+{
+    tNFA_HANDLE     client_handle;
+    tNFA_HANDLE     conn_handle;
+    UINT8           remote_sap;
+    UINT16          remote_miu;
+    UINT8           remote_rw;
+} tNFA_P2P_CONN;
+
+/* Data for NFA_P2P_DISC_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+    UINT8           reason;
+} tNFA_P2P_DISC;
+
+/* Data for NFA_P2P_DATA_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+    UINT8           remote_sap;
+    tNFA_P2P_LINK_TYPE link_type;
+} tNFA_P2P_DATA;
+
+/* Data for NFA_P2P_CONGEST_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+    BOOLEAN         is_congested;
+    tNFA_P2P_LINK_TYPE link_type;
+} tNFA_P2P_CONGEST;
+
+/* Data for NFA_P2P_LINK_INFO_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+    UINT16          wks;            /* well-known service */
+    UINT16          local_link_miu;
+    UINT16          remote_link_miu;
+} tNFA_P2P_LINK_INFO;
+
+/* Data for NFA_P2P_SDP_EVT */
+typedef struct
+{
+    tNFA_HANDLE     handle;
+    UINT8           remote_sap;     /* 0x00 if failed */
+} tNFA_P2P_SDP;
+
+/* Union of all P2P callback structures */
+typedef union
+{
+    tNFA_P2P_REG_SERVER     reg_server;     /* NFA_P2P_REG_SERVER_EVT   */
+    tNFA_P2P_REG_CLIENT     reg_client;     /* NFA_P2P_REG_CLIENT_EVT   */
+    tNFA_P2P_ACTIVATED      activated;      /* NFA_P2P_ACTIVATED_EVT    */
+    tNFA_P2P_DEACTIVATED    deactivated;    /* NFA_P2P_DEACTIVATED_EVT  */
+    tNFA_P2P_CONN_REQ       conn_req;       /* NFA_P2P_CONN_REQ_EVT     */
+    tNFA_P2P_CONN           connected;      /* NFA_P2P_CONNECTED_EVT    */
+    tNFA_P2P_DISC           disc;           /* NFA_P2P_DISC_EVT         */
+    tNFA_P2P_DATA           data;           /* NFA_P2P_DATA_EVT         */
+    tNFA_P2P_CONGEST        congest;        /* NFA_P2P_CONGEST_EVT      */
+    tNFA_P2P_LINK_INFO      link_info;      /* NFA_P2P_LINK_INFO_EVT    */
+    tNFA_P2P_SDP            sdp;            /* NFA_P2P_SDP_EVT          */
+} tNFA_P2P_EVT_DATA;
+
+/* NFA P2P callback */
+typedef void (tNFA_P2P_CBACK)(tNFA_P2P_EVT event, tNFA_P2P_EVT_DATA *p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterServer
+**
+** Description      This function is called to listen to a SAP as server on LLCP.
+**
+**                  NFA_P2P_REG_SERVER_EVT will be returned with status and handle.
+**
+**                  If server_sap is set to NFA_P2P_ANY_SAP, then NFA will allocate
+**                  a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+**                  Otherwise, server_sap must be between (LLCP_SDP_SAP + 1) and
+**                  LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pRegisterServer (UINT8              server_sap,
+                                                  tNFA_P2P_LINK_TYPE link_type,
+                                                  char              *p_service_name,
+                                                  tNFA_P2P_CBACK    *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterClient
+**
+** Description      This function is called to register a client service on LLCP.
+**
+**                  NFA_P2P_REG_CLIENT_EVT will be returned with status and handle.
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pRegisterClient (tNFA_P2P_LINK_TYPE link_type,
+                                                  tNFA_P2P_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDeregister
+**
+** Description      This function is called to stop listening to a SAP as server
+**                  or stop client service on LLCP.
+**
+** Note:            If this function is called to de-register a server and RF discovery
+**                  is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pDeregister (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pAcceptConn
+**
+** Description      This function is called to accept a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pAcceptConn (tNFA_HANDLE conn_handle,
+                                              UINT16      miu,
+                                              UINT8       rw);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRejectConn
+**
+** Description      This function is called to reject a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pRejectConn (tNFA_HANDLE conn_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDisconnect
+**
+** Description      This function is called to disconnect an existing or
+**                  connecting data link connection.
+**
+**                  discard any pending data on data link connection if flush is set to TRUE
+**
+**                  NFA_P2P_DISC_EVT will be returned after data link connection is disconnected
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pDisconnect (tNFA_HANDLE conn_handle,
+                                              BOOLEAN     flush);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectByName
+**
+** Description      This function is called to create a connection-oriented transport
+**                  by a service name.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pConnectByName (tNFA_HANDLE client_handle,
+                                                 char       *p_service_name,
+                                                 UINT16      miu,
+                                                 UINT8       rw);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectBySap
+**
+** Description      This function is called to create a connection-oriented transport
+**                  by a SAP.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pConnectBySap (tNFA_HANDLE client_handle,
+                                                UINT8       dsap,
+                                                UINT16      miu,
+                                                UINT8       rw);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendUI
+**
+** Description      This function is called to send data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote link MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSendUI (tNFA_HANDLE handle,
+                                          UINT8       dsap,
+                                          UINT16      length,
+                                          UINT8      *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadUI
+**
+** Description      This function is called to read data on connectionless
+**                  transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_LLINK_TYPE.
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into p_data.
+**                  - If more information of UI PDU or more UI PDU in queue then more
+**                    is returned to TRUE.
+**                  - Information of next UI PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pReadUI (tNFA_HANDLE handle,
+                                          UINT32      max_data_len,
+                                          UINT8       *p_remote_sap,
+                                          UINT32      *p_data_len,
+                                          UINT8       *p_data,
+                                          BOOLEAN     *p_more);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushUI
+**
+** Description      This function is called to flush data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pFlushUI (tNFA_HANDLE handle,
+                                           UINT32      *p_length);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendData
+**
+** Description      This function is called to send data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSendData (tNFA_HANDLE conn_handle,
+                                            UINT16      length,
+                                            UINT8      *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadData
+**
+** Description      This function is called to read data on connection-oriented
+**                  transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_DLINK_TYPE.
+**
+**                  - Information of I PDU is copied into p_data up to max_data_len.
+**                  - If more information of I PDU or more I PDU in queue, then more
+**                    is returned to TRUE.
+**                  - Information of next I PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pReadData (tNFA_HANDLE handle,
+                                            UINT32      max_data_len,
+                                            UINT32      *p_data_len,
+                                            UINT8       *p_data,
+                                            BOOLEAN     *p_more);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushData
+**
+** Description      This function is called to flush data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pFlushData (tNFA_HANDLE handle,
+                                             UINT32      *p_length);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLocalBusy
+**
+** Description      This function is called to stop or resume incoming data on
+**                  connection-oriented transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSetLocalBusy (tNFA_HANDLE conn_handle,
+                                                BOOLEAN     is_busy);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLinkInfo
+**
+** Description      This function is called to get local/remote link MIU and
+**                  Well-Known Service list encoded as a 16-bit field of connected LLCP.
+**                  NFA_P2P_LINK_INFO_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pGetLinkInfo (tNFA_HANDLE handle);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetRemoteSap
+**
+** Description      This function is called to get SAP associated by service name
+**                  on connected remote LLCP.
+**                  NFA_P2P_SDP_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pGetRemoteSap (tNFA_HANDLE handle,
+                                                char       *p_service_name);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLLCPConfig
+**
+** Description      This function is called to change LLCP config parameters.
+**                  Application must call while LLCP is not activated.
+**
+**                  Parameters descriptions (default value)
+**                  - Local Link MIU (LLCP_MIU)
+**                  - Option parameter (LLCP_OPT_VALUE)
+**                  - Response Waiting Time Index (LLCP_WAITING_TIME)
+**                  - Local Link Timeout (LLCP_LTO_VALUE)
+**                  - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT)
+**                  - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT)
+**                  - Delay SYMM response (LLCP_DELAY_RESP_TIME)
+**                  - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT)
+**                  - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_P2pSetLLCPConfig (UINT16 link_miu,
+                                                 UINT8  opt,
+                                                 UINT8  wt,
+                                                 UINT16 link_timeout,
+                                                 UINT16 inact_timeout_init,
+                                                 UINT16 inact_timeout_target,
+                                                 UINT16 symm_delay,
+                                                 UINT16 data_link_timeout,
+                                                 UINT16 delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLLCPConfig
+**
+** Description      This function is called to read LLCP config parameters.
+**
+**                  Parameters descriptions
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          None
+**
+*******************************************************************************/
+NFC_API extern void NFA_P2pGetLLCPConfig (UINT16 *p_link_miu,
+                                          UINT8  *p_opt,
+                                          UINT8  *p_wt,
+                                          UINT16 *p_link_timeout,
+                                          UINT16 *p_inact_timeout_init,
+                                          UINT16 *p_inact_timeout_target,
+                                          UINT16 *p_symm_delay,
+                                          UINT16 *p_data_link_timeout,
+                                          UINT16 *p_delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetTraceLevel
+**
+** Description      This function sets the trace level for P2P.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_P2pSetTraceLevel (UINT8 new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
+
diff --git a/src/nfa/include/nfa_rw_api.h b/src/nfa/include/nfa_rw_api.h
new file mode 100644
index 0000000..fde2ff7
--- /dev/null
+++ b/src/nfa/include/nfa_rw_api.h
@@ -0,0 +1,746 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA reader/writer API functions
+ *
+ ******************************************************************************/
+#ifndef NFA_RW_API_H
+#define NFA_RW_API_H
+
+#include "nfc_target.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/*****************************************************************************
+**  NFA T3T Constants and definitions
+*****************************************************************************/
+
+/* Block descriptor. (For non-NDEF read/write */
+typedef struct
+{
+    UINT16  service_code;       /* Service code for the block   */
+    UINT16  block_number;       /* Block number.                */
+} tNFA_T3T_BLOCK_DESC;
+
+
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_RwDetectNDef
+**
+** Description      Perform the NDEF detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection, a
+**                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
+**                  of the NDEF attributes (NDEF total memory size, current
+**                  size, etc.).
+**
+**                  It is not mandatory to call this function -  NFA_RwReadNDef
+**                  and NFA_RwWriteNDef will perform NDEF detection internally if
+**                  not performed already. This API may be called to get a
+**                  tag's NDEF size before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwReadNDef
+**
+** Description      Read NDEF message from tag. This function will internally
+**                  perform the NDEF detection procedure (if not performed
+**                  previously), and read the NDEF tag data using the
+**                  appropriate method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection (if performed),
+**                  a NFA_NDEF_DETECT_EVT will be sent, to notify the application
+**                  of the NDEF attributes (NDEF total memory size, current size,
+**                  etc.).
+**
+**                  Upon receiving the NDEF message, the message will be sent to
+**                  the handler registered with NFA_RegisterNDefTypeHandler or
+**                  NFA_RequestExclusiveRfControl (if exclusive RF mode is active)
+**
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the tag
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwReadNDef (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwWriteNDef
+**
+** Description      Write NDEF data to the activated tag. This function will
+**                  internally perform NDEF detection if necessary, and write
+**                  the NDEF tag data using the appropriate method for the
+**                  currently activated tag.
+**
+**                  When the entire message has been written, or if an error
+**                  occurs, the app will be notified with NFA_RW_WRITE_CPLT_EVT.
+**
+**                  p_data needs to be persistent until NFA_RW_WRITE_CPLT_EVT
+**
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF/locked
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwWriteNDef (UINT8 *p_data, UINT32 len);
+
+
+/*****************************************************************************
+**
+** Function         NFA_RwPresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
+**                  indicate presence or non-presence.
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function         NFA_RwFormatTag
+**
+** Description      Check if the tag is NDEF Formatable. If yes Format the
+**                  tag
+**
+**                  The NFA_RW_FORMAT_CPLT_EVT w/ status is used to
+**                  indicate if tag is formated or not.
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwFormatTag (void);
+
+/*******************************************************************************
+** LEGACY / PROPRIETARY TAG READ AND WRITE APIs
+*******************************************************************************/
+
+
+/*******************************************************************************
+**
+** Function         NFA_RwLocateTlv
+**
+** Description:
+**      Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
+**
+**      Data is returned to the application using the NFA_TLV_DETECT_EVT. When
+**      search operation has completed, or if an error occurs, the app will be
+**      notified with NFA_TLV_DETECT_EVT.
+**
+** Description      Perform the TLV detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of TLV detection in T1/T2 tag, a
+**                  NFA_TLV_DETECT_EVT will be sent, to notify the application
+**                  of the TLV attributes (total lock/reserved bytes etc.).
+**                  However if the TLV type specified is NDEF then it is same as
+**                  calling NFA_RwDetectNDef and should expect to receive
+**                  NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
+**
+**                  It is not mandatory to call this function -  NFA_RwDetectNDef,
+**                  NFA_RwReadNDef and NFA_RwWriteNDef will perform TLV detection
+**                  internally if not performed already. An application may call
+**                  this API to check the a tag/card-emulator's total Reserved/
+**                  Lock bytes before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwLocateTlv (UINT8 tlv_type);
+
+/*******************************************************************************
+**
+** Function         NFA_RwSetTagReadOnly
+**
+** Description:
+**      Sets tag as read only.
+**
+**      When tag is set as read only, or if an error occurs, the app will be
+**      notified with NFA_SET_TAG_RO_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_REJECTED if protocol is not T1/T2/ISO15693
+**                 (or) if hard lock is not requested for protocol ISO15693
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwSetTagReadOnly (BOOLEAN b_hard_lock);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRid
+**
+** Description:
+**      Send a RID command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tRid (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadAll
+**
+** Description:
+**      Send a RALL command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tReadAll (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead
+**
+** Description:
+**      Send a READ command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tRead (UINT8 block_number, UINT8 index);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite
+**
+** Description:
+**      Send a WRITE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the write
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tWrite (UINT8    block_number,
+                                           UINT8    index,
+                                           UINT8    data,
+                                           BOOLEAN  b_erase);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadSeg
+**
+** Description:
+**      Send a RSEG command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tReadSeg (UINT8 segment_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead8
+**
+** Description:
+**      Send a READ8 command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tRead8 (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite8
+**
+** Description:
+**      Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 1 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT1tWrite8 (UINT8   block_number,
+                                            UINT8  *p_data,
+                                            BOOLEAN b_erase);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tRead
+**
+** Description:
+**      Send a READ command to the activated Type 2 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT2tRead (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tWrite
+**
+** Description:
+**      Send an WRITE command to the activated Type 2 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT2tWrite (UINT8 block_number,  UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tSectorSelect
+**
+** Description:
+**      Send SECTOR SELECT command to the activated Type 2 tag.
+**
+**      When the sector select operation has completed (or if an error occurs), the
+**      app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 2 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT2tSectorSelect (UINT8 sector_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tRead
+**
+** Description:
+**      Send a CHECK (read) command to the activated Type 3 tag.
+**
+**      Data is returned to the application using the NFA_RW_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 3 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT3tRead (UINT8                num_blocks,
+                                          tNFA_T3T_BLOCK_DESC *t3t_blocks);
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tWrite
+**
+** Description:
+**      Send an UPDATE (write) command to the activated Type 3 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: type 3 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwT3tWrite (UINT8                num_blocks,
+                                           tNFA_T3T_BLOCK_DESC *t3t_blocks,
+                                           UINT8               *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Inventory
+**
+** Description:
+**      Send Inventory command to the activated ISO 15693 tag.
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_NOT_INITIALIZED: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93Inventory (UINT8 afi, UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93StayQuiet
+**
+** Description:
+**      Send Stay Quiet command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93StayQuiet (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadSingleBlock
+**
+** Description:
+**      Send Read Single Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93ReadSingleBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteSingleBlock
+**
+** Description:
+**      Send Write Single Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteSingleBlock (UINT8 block_number,
+                                                      UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockBlock
+**
+** Description:
+**      Send Lock block command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93LockBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadMultipleBlocks
+**
+** Description:
+**      Send Read Multiple Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93ReadMultipleBlocks (UINT8  first_block_number,
+                                                        UINT16 number_blocks);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteMultipleBlocks
+**
+** Description:
+**      Send Write Multiple Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteMultipleBlocks (UINT8  first_block_number,
+                                                         UINT16 number_blocks,
+                                                         UINT8  *p_data);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Select
+**
+** Description:
+**      Send Select command to the activated ISO 15693 tag.
+**
+**      UID[0]: 0xE0, MSB
+**      UID[1]: IC Mfg Code
+**      ...
+**      UID[7]: LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93Select (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ResetToReady
+**
+** Description:
+**      Send Reset to ready command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93ResetToReady (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteAFI
+**
+** Description:
+**      Send Write AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteAFI (UINT8 afi);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockAFI
+**
+** Description:
+**      Send Lock AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93LockAFI (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteDSFID
+**
+** Description:
+**      Send Write DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93WriteDSFID (UINT8 dsfid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockDSFID
+**
+** Description:
+**      Send Lock DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93LockDSFID (void);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetSysInfo
+**
+** Description:
+**      Send Get system information command to the activated ISO 15693 tag.
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93GetSysInfo (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetMultiBlockSecurityStatus
+**
+** Description:
+**      Send Get Multiple block security status command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus (UINT8  first_block_number,
+                                                                 UINT16 number_blocks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_RW_API_H */
diff --git a/src/nfa/include/nfa_snep_api.h b/src/nfa/include/nfa_snep_api.h
new file mode 100644
index 0000000..a890047
--- /dev/null
+++ b/src/nfa/include/nfa_snep_api.h
@@ -0,0 +1,454 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for NFA SNEP, Broadcom's NFC
+ *  application layer for mobile phones.
+ *
+ ******************************************************************************/
+#ifndef NFA_SNEP_API_H
+#define NFA_SNEP_API_H
+
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_SNEP_VERSION                0x10    /* SNEP Version 1.0          */
+
+#define NFA_SNEP_REQ_CODE_CONTINUE      0x00    /* send remaining fragments         */
+#define NFA_SNEP_REQ_CODE_GET           0x01    /* return an NDEF message           */
+#define NFA_SNEP_REQ_CODE_PUT           0x02    /* accept an NDEF message           */
+#define NFA_SNEP_REQ_CODE_REJECT        0x7F    /* do not send remaining fragments  */
+
+#define tNFA_SNEP_REQ_CODE  UINT8
+
+#define NFA_SNEP_RESP_CODE_CONTINUE     0x80    /* continue send remaining fragments    */
+#define NFA_SNEP_RESP_CODE_SUCCESS      0x81    /* the operation succeeded              */
+#define NFA_SNEP_RESP_CODE_NOT_FOUND    0xC0    /* resource not found                   */
+#define NFA_SNEP_RESP_CODE_EXCESS_DATA  0xC1    /* resource exceeds data size limit     */
+#define NFA_SNEP_RESP_CODE_BAD_REQ      0xC2    /* malformed request not understood     */
+#define NFA_SNEP_RESP_CODE_NOT_IMPLM    0xE0    /* unsupported functionality requested  */
+#define NFA_SNEP_RESP_CODE_UNSUPP_VER   0xE1    /* unsupported protocol version         */
+#define NFA_SNEP_RESP_CODE_REJECT       0xFF    /* do not send remaining fragments      */
+
+#define tNFA_SNEP_RESP_CODE UINT8
+
+/* NFA SNEP callback events */
+#define NFA_SNEP_REG_EVT                    0x00    /* Server/client Registeration Status   */
+#define NFA_SNEP_ACTIVATED_EVT              0x01    /* LLCP link has been activated, client only   */
+#define NFA_SNEP_DEACTIVATED_EVT            0x02    /* LLCP link has been deactivated, client only */
+#define NFA_SNEP_CONNECTED_EVT              0x03    /* Data link has been created           */
+#define NFA_SNEP_GET_REQ_EVT                0x04    /* GET request from client              */
+#define NFA_SNEP_PUT_REQ_EVT                0x05    /* PUT request from client              */
+#define NFA_SNEP_GET_RESP_EVT               0x06    /* GET response from server             */
+#define NFA_SNEP_PUT_RESP_EVT               0x07    /* PUT response from server             */
+#define NFA_SNEP_DISC_EVT                   0x08    /* Failed to connect or disconnected    */
+
+#define NFA_SNEP_ALLOC_BUFF_EVT	            0x09    /* Request to allocate a buffer for NDEF*/
+#define NFA_SNEP_GET_RESP_CMPL_EVT          0x0A    /* GET response sent to client          */
+
+#define NFA_SNEP_DEFAULT_SERVER_STARTED_EVT 0x0B    /* SNEP default server is started       */
+#define NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT 0x0C    /* SNEP default server is stopped       */
+
+typedef UINT8 tNFA_SNEP_EVT;
+
+#define NFA_SNEP_ANY_SAP         LLCP_INVALID_SAP
+
+/* Data for NFA_SNEP_REG_EVT */
+typedef struct
+{
+    tNFA_STATUS         status;
+    tNFA_HANDLE         reg_handle;         /* handle for registered server/client */
+    char                service_name[LLCP_MAX_SN_LEN + 1];      /* only for server */
+} tNFA_SNEP_REG;
+
+/* Data for NFA_SNEP_ACTIVATED_EVT */
+typedef struct
+{
+    tNFA_HANDLE         client_handle;      /* handle for registered client    */
+} tNFA_SNEP_ACTIVATED;
+
+/* Data for NFA_SNEP_DEACTIVATED_EVT */
+typedef tNFA_SNEP_ACTIVATED tNFA_SNEP_DEACTIVATED;
+
+/* Data for NFA_SNEP_CONNECTED_EVT */
+/*
+** for server, new handle will be assigned for conn_handle
+** for client, handle used in NFA_SnepConnect () is returned in conn_handle
+*/
+typedef struct
+{
+    tNFA_HANDLE         reg_handle;         /* server/client handle            */
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+} tNFA_SNEP_CONNECT;
+
+/* Data for NFA_SNEP_GET_REQ_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+    UINT32              acceptable_length;  /* acceptable length from client   */
+    UINT32              ndef_length;        /* NDEF message length             */
+    UINT8               *p_ndef;            /* NDEF message                    */
+} tNFA_SNEP_GET_REQ;
+
+/* Data for NFA_SNEP_PUT_REQ_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+    UINT32              ndef_length;        /* NDEF message length             */
+    UINT8               *p_ndef;            /* NDEF message                    */
+} tNFA_SNEP_PUT_REQ;
+
+/* Data for NFA_SNEP_GET_RESP_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+    tNFA_SNEP_RESP_CODE resp_code;          /* response code from server       */
+    UINT32              ndef_length;        /* NDEF message length             */
+    UINT8               *p_ndef;            /* NDEF message                    */
+} tNFA_SNEP_GET_RESP;
+
+/* Data for NFA_SNEP_PUT_RESP_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+    tNFA_SNEP_RESP_CODE resp_code;          /* response code from server       */
+} tNFA_SNEP_PUT_RESP;
+
+/* Data for NFA_SNEP_DISC_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+                                            /* client_handle if connection failed */
+} tNFA_SNEP_DISC;
+
+/* Data for NFA_SNEP_ALLOC_BUFF_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection                */
+    tNFA_SNEP_REQ_CODE  req_code;           /* NFA_SNEP_REQ_CODE_GET or NFA_SNEP_REQ_CODE_PUT */
+    tNFA_SNEP_RESP_CODE resp_code;          /* Response code if cannot allocate buffer        */
+    UINT32              ndef_length;        /* NDEF message length                            */
+    UINT8               *p_buff;            /* buffer for NDEF message                        */
+} tNFA_SNEP_ALLOC;
+
+/* Data for NFA_SNEP_GET_RESP_CMPL_EVT */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;        /* handle for data link connection */
+    UINT8               *p_buff;            /* buffer for NDEF message         */
+} tNFA_SNEP_GET_RESP_CMPL;
+
+/* Union of all SNEP callback structures */
+typedef union
+{
+    tNFA_SNEP_REG           reg;            /* NFA_SNEP_REG_EVT             */
+    tNFA_SNEP_ACTIVATED     activated;      /* NFA_SNEP_ACTIVATED_EVT       */
+    tNFA_SNEP_DEACTIVATED   deactivated;    /* NFA_SNEP_DEACTIVATED_EVT     */
+    tNFA_SNEP_CONNECT       connect;        /* NFA_SNEP_CONNECTED_EVT       */
+    tNFA_SNEP_GET_REQ       get_req;        /* NFA_SNEP_GET_REQ_EVT         */
+    tNFA_SNEP_PUT_REQ       put_req;        /* NFA_SNEP_PUT_REQ_EVT         */
+    tNFA_SNEP_GET_RESP      get_resp;       /* NFA_SNEP_GET_RESP_EVT        */
+    tNFA_SNEP_PUT_RESP      put_resp;       /* NFA_SNEP_PUT_RESP_EVT        */
+    tNFA_SNEP_DISC          disc;           /* NFA_SNEP_DISC_EVT            */
+    tNFA_SNEP_ALLOC         alloc;          /* NFA_SNEP_ALLOC_BUFF_EVT      */
+    tNFA_SNEP_GET_RESP_CMPL get_resp_cmpl;  /* NFA_SNEP_GET_RESP_CMPL_EVT   */
+} tNFA_SNEP_EVT_DATA;
+
+/* NFA SNEP callback */
+typedef void (tNFA_SNEP_CBACK) (tNFA_SNEP_EVT event, tNFA_SNEP_EVT_DATA *p_data);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         NFA_SnepStartDefaultServer
+**
+** Description      This function is called to listen to SAP, 0x04 as SNEP default
+**                  server ("urn:nfc:sn:snep") on LLCP.
+**
+**                  NFA_SNEP_DEFAULT_SERVER_STARTED_EVT without data will be returned.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepStartDefaultServer (tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepStopDefaultServer
+**
+** Description      This function is called to stop SNEP default server on LLCP.
+**
+**                  NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT without data will be returned.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepStopDefaultServer (tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepRegisterServer
+**
+** Description      This function is called to listen to a SAP as SNEP server.
+**
+**                  If server_sap is set to NFA_SNEP_ANY_SAP, then NFA will allocate
+**                  a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  NFC Forum default SNEP server ("urn:nfc:sn:snep") may be launched
+**                  by NFA_SnepStartDefaultServer ().
+**
+**                  NFA_SNEP_REG_EVT will be returned with status, handle and service name.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepRegisterServer (UINT8           server_sap,
+                                                   char            *p_service_name,
+                                                   tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepRegisterClient
+**
+** Description      This function is called to register SNEP client.
+**                  NFA_SNEP_REG_EVT will be returned with status, handle
+**                  and zero-length service name.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepRegisterClient (tNFA_SNEP_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepDeregister
+**
+** Description      This function is called to stop listening as SNEP server
+**                  or SNEP client. Application shall use reg_handle returned in
+**                  NFA_SNEP_REG_EVT.
+**
+** Note:            If this function is called to de-register a SNEP server and RF
+**                  discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepDeregister (tNFA_HANDLE reg_handle);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepConnect
+**
+** Description      This function is called by client to create data link connection
+**                  to SNEP server on peer device.
+**
+**                  Client handle and service name of server to connect shall be provided.
+**                  A conn_handle will be returned in NFA_SNEP_CONNECTED_EVT, if
+**                  successfully connected. Otherwise NFA_SNEP_DISC_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepConnect (tNFA_HANDLE     client_handle,
+                                            char            *p_service_name);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepGet
+**
+** Description      This function is called by client to send GET request.
+**
+**                  Application shall allocate a buffer and put NDEF message with
+**                  desired record type to get from server. NDEF message from server
+**                  will be returned in the same buffer with NFA_SNEP_GET_RESP_EVT.
+**                  The size of buffer will be used as "Acceptable Length".
+**
+**                  NFA_SNEP_GET_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through registered p_cback. Application may free the buffer
+**                  after receiving these events.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepGet (tNFA_HANDLE     conn_handle,
+                                        UINT32          buff_length,
+                                        UINT32          ndef_length,
+                                        UINT8           *p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepPut
+**
+** Description      This function is called by client to send PUT request.
+**
+**                  Application shall allocate a buffer and put desired NDEF message
+**                  to send to server.
+**
+**                  NFA_SNEP_PUT_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through p_cback. Application may free the buffer after receiving
+**                  these events.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepPut (tNFA_HANDLE     conn_handle,
+                                        UINT32          ndef_length,
+                                        UINT8           *p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepGetResponse
+**
+** Description      This function is called by server to send response of GET request.
+**
+**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+**                  it shall allocate a buffer for incoming NDEF message and
+**                  pass the pointer within callback context. This buffer will be
+**                  returned with NFA_SNEP_GET_REQ_EVT after receiving complete
+**                  NDEF message. If buffer is not allocated, NFA_SNEP_RESP_CODE_NOT_FOUND
+**                  (Note:There is no proper response code for this case)
+**                  or NFA_SNEP_RESP_CODE_REJECT will be sent to client.
+**
+**                  Server application shall provide conn_handle which is received in
+**                  NFA_SNEP_GET_REQ_EVT.
+**
+**                  Server application shall allocate a buffer and put NDEF message if
+**                  response code is NFA_SNEP_RESP_CODE_SUCCESS. Otherwise, ndef_length
+**                  shall be set to zero.
+**
+**                  NFA_SNEP_GET_RESP_CMPL_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through registered callback function. Application may free
+**                  the buffer after receiving these events.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepGetResponse (tNFA_HANDLE         conn_handle,
+                                                tNFA_SNEP_RESP_CODE resp_code,
+                                                UINT32              ndef_length,
+                                                UINT8               *p_ndef_buff);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepPutResponse
+**
+** Description      This function is called by server to send response of PUT request.
+**
+**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+**                  it shall allocate a buffer for incoming NDEF message and
+**                  pass the pointer within callback context. This buffer will be
+**                  returned with NFA_SNEP_PUT_REQ_EVT after receiving complete
+**                  NDEF message.  If buffer is not allocated, NFA_SNEP_RESP_CODE_REJECT
+**                  will be sent to client or NFA will discard request and send
+**                  NFA_SNEP_RESP_CODE_SUCCESS (Note:There is no proper response code for
+**                  this case).
+**
+**                  Server application shall provide conn_handle which is received in
+**                  NFA_SNEP_PUT_REQ_EVT.
+**
+**                  NFA_SNEP_DISC_EVT will be returned through registered callback
+**                  function when client disconnects data link connection.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepPutResponse (tNFA_HANDLE         conn_handle,
+                                                tNFA_SNEP_RESP_CODE resp_code);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepDisconnect
+**
+** Description      This function is called to disconnect data link connection.
+**                  discard any pending data if flush is set to TRUE
+**
+**                  Client application shall provide conn_handle in NFA_SNEP_GET_RESP_EVT
+**                  or NFA_SNEP_PUT_RESP_EVT.
+**
+**                  Server application shall provide conn_handle in NFA_SNEP_GET_REQ_EVT
+**                  or NFA_SNEP_PUT_REQ_EVT.
+**
+**                  NFA_SNEP_DISC_EVT will be returned
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+NFC_API extern tNFA_STATUS NFA_SnepDisconnect (tNFA_HANDLE conn_handle,
+                                               BOOLEAN     flush);
+
+/*******************************************************************************
+**
+** Function         NFA_SnepSetTraceLevel
+**
+** Description      This function sets the trace level for SNEP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFA_SnepSetTraceLevel (UINT8 new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_P2P_API_H */
+
diff --git a/src/nfa/int/nfa_ce_int.h b/src/nfa/int/nfa_ce_int.h
new file mode 100644
index 0000000..ef58dc2
--- /dev/null
+++ b/src/nfa/int/nfa_ce_int.h
@@ -0,0 +1,214 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for NFA_CE
+ *
+ ******************************************************************************/
+#ifndef NFA_CE_INT_H
+#define NFA_CE_INT_H
+
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_ce_api.h"
+#include "nfa_dm_int.h"
+#include "nfc_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* ce status callback */
+typedef void tNFA_CE_STATUS_CBACK (tNFA_STATUS status);
+
+/* CE events */
+enum
+{
+    /* device manager local device API events */
+    NFA_CE_API_CFG_LOCAL_TAG_EVT    = NFA_SYS_EVT_START (NFA_ID_CE),
+    NFA_CE_API_REG_LISTEN_EVT,
+    NFA_CE_API_DEREG_LISTEN_EVT,
+    NFA_CE_API_CFG_ISODEP_TECH_EVT,
+    NFA_CE_ACTIVATE_NTF_EVT,
+    NFA_CE_DEACTIVATE_NTF_EVT,
+
+    NFA_CE_MAX_EVT
+};
+
+/* Listen registration types */
+enum
+{
+    NFA_CE_REG_TYPE_NDEF,
+    NFA_CE_REG_TYPE_ISO_DEP,
+    NFA_CE_REG_TYPE_FELICA,
+    NFA_CE_REG_TYPE_UICC
+};
+typedef UINT8 tNFA_CE_REG_TYPE;
+
+/* data type for NFA_CE_API_CFG_LOCAL_TAG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_PROTOCOL_MASK  protocol_mask;
+    UINT8               *p_ndef_data;
+    UINT16              ndef_cur_size;
+    UINT16              ndef_max_size;
+    BOOLEAN             read_only;
+    UINT8               uid_len;
+    UINT8               uid[NFA_MAX_UID_LEN];
+} tNFA_CE_API_CFG_LOCAL_TAG;
+
+/* data type for NFA_CE_ACTIVATE_NTF_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFC_ACTIVATE_DEVT *p_activation_params;
+} tNFA_CE_ACTIVATE_NTF;
+
+/* data type for NFA_CE_API_REG_LISTEN_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_CONN_CBACK     *p_conn_cback;
+
+    tNFA_CE_REG_TYPE   listen_type;
+
+    /* For registering Felica */
+    UINT16              system_code;
+    UINT8               nfcid2[NCI_RF_F_UID_LEN];
+
+    /* For registering Type-4 */
+    UINT8               aid[NFC_MAX_AID_LEN];   /* AID to listen for (For type-4 only)  */
+    UINT8               aid_len;                /* AID length                           */
+
+    /* For registering UICC */
+    tNFA_HANDLE             ee_handle;
+    tNFA_TECHNOLOGY_MASK    tech_mask;
+} tNFA_CE_API_REG_LISTEN;
+
+/* data type for NFA_CE_API_DEREG_LISTEN_EVT */
+typedef struct
+{
+    BT_HDR          hdr;
+    tNFA_HANDLE     handle;
+    UINT32          listen_info;
+} tNFA_CE_API_DEREG_LISTEN;
+
+/* union of all data types */
+typedef union
+{
+    /* GKI event buffer header */
+    BT_HDR                      hdr;
+    tNFA_CE_API_CFG_LOCAL_TAG   local_tag;
+    tNFA_CE_API_REG_LISTEN      reg_listen;
+    tNFA_CE_API_DEREG_LISTEN    dereg_listen;
+    tNFA_CE_ACTIVATE_NTF        activate_ntf;
+} tNFA_CE_MSG;
+
+/****************************************************************************
+** LISTEN_INFO definitions
+*****************************************************************************/
+#define NFA_CE_LISTEN_INFO_IDX_NDEF     0                           /* Entry 0 is reserved for local NDEF tag */
+#define NFA_CE_LISTEN_INFO_IDX_INVALID  (NFA_CE_LISTEN_INFO_MAX)
+
+
+/* Flags for listen request */
+#define NFA_CE_LISTEN_INFO_IN_USE           0x00000001  /* LISTEN_INFO entry is in use                                      */
+#define NFC_CE_LISTEN_INFO_READONLY_NDEF    0x00000010  /* NDEF is read-only                                                */
+#define NFA_CE_LISTEN_INFO_T4T_ACTIVATE_PND 0x00000040  /* App has not been notified of ACTIVATE_EVT yet for this T4T AID   */
+#define NFA_CE_LISTEN_INFO_T4T_AID          0x00000080  /* This is a listen_info for T4T AID                                */
+#define NFA_CE_LISTEN_INFO_START_NTF_PND    0x00000100  /* App has not been notified of LISTEN_START yet                    */
+#define NFA_CE_LISTEN_INFO_FELICA           0x00000200  /* This is a listen_info for non-NDEF Felica                        */
+#define NFA_CE_LISTEN_INFO_UICC             0x00000400  /* This is a listen_info for UICC                                   */
+
+
+/* Structure for listen look up table */
+typedef struct
+{
+    UINT32              flags;
+    tNFA_CONN_CBACK     *p_conn_cback;                  /* Callback for this listen request             */
+    tNFA_PROTOCOL_MASK  protocol_mask;                  /* Mask of protocols for this listen request    */
+    tNFA_HANDLE         rf_disc_handle;                 /* RF Discover handle */
+
+    /* For host tag emulation (NFA_CeRegisterVirtualT4tSE and NFA_CeRegisterT4tAidOnDH) */
+    UINT8               t3t_nfcid2[NCI_RF_F_UID_LEN];
+    UINT16              t3t_system_code;                /* Type-3 system code */
+    UINT8               t4t_aid_handle;                 /* Type-4 aid callback handle (from CE_T4tRegisterAID) */
+
+    /* For UICC */
+    tNFA_HANDLE                     ee_handle;
+    tNFA_TECHNOLOGY_MASK            tech_mask;          /* listening technologies               */
+    tNFA_DM_DISC_TECH_PROTO_MASK    tech_proto_mask;    /* listening technologies and protocols */
+} tNFA_CE_LISTEN_INFO;
+
+
+/****************************************************************************/
+
+/* Internal flags for nfa_ce */
+#define NFA_CE_FLAGS_APP_INIT_DEACTIVATION  0x00000001  /* Deactivation locally initiated by application */
+#define NFA_CE_FLAGS_LISTEN_ACTIVE_SLEEP    0x00000002  /* Tag is in listen active or sleep state        */
+typedef UINT32 tNFA_CE_FLAGS;
+
+/* NFA_CE control block */
+typedef struct
+{
+    UINT8   *p_scratch_buf;                                 /* Scratch buffer for write requests    */
+    UINT32  scratch_buf_size;
+
+    tNFC_ACTIVATE_DEVT  activation_params;                  /* Activation params        */
+    tNFA_CE_FLAGS       flags;                              /* internal flags           */
+    tNFA_CONN_CBACK     *p_active_conn_cback;               /* Callback of activated CE */
+
+    /* listen_info table (table of listen paramters and app callbacks) */
+    tNFA_CE_LISTEN_INFO listen_info[NFA_CE_LISTEN_INFO_MAX];/* listen info table                            */
+    UINT8               idx_cur_active;                     /* listen_info index for currently activated CE */
+
+    tNFA_DM_DISC_TECH_PROTO_MASK isodep_disc_mask;          /* the technology/protocol mask for ISO-DEP */
+
+    /* Local ndef tag info */
+    UINT8               *p_ndef_data;
+    UINT16              ndef_cur_size;
+    UINT16              ndef_max_size;
+
+    tNFA_SYS_EVT_HDLR   *p_vs_evt_hdlr;                     /* VS event handler */
+} tNFA_CE_CB;
+extern tNFA_CE_CB nfa_ce_cb;
+
+/* type definition for action functions */
+typedef BOOLEAN (*tNFA_CE_ACTION) (tNFA_CE_MSG *p_data);
+
+/* Action function prototypes */
+BOOLEAN nfa_ce_api_cfg_local_tag (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_api_reg_listen (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_api_dereg_listen (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_api_cfg_isodep_tech (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_activate_ntf (tNFA_CE_MSG *p_ce_msg);
+BOOLEAN nfa_ce_deactivate_ntf (tNFA_CE_MSG *p_ce_msg);
+
+/* Internal function prototypes */
+void nfa_ce_t3t_generate_rand_nfcid (UINT8 nfcid2[NCI_RF_F_UID_LEN]);
+BOOLEAN nfa_ce_hdl_event (BT_HDR *p_msg);
+tNFC_STATUS nfa_ce_set_content (void);
+tNFA_STATUS nfa_ce_start_listening (void);
+void nfa_ce_remove_listen_info_entry (UINT8 listen_info_idx, BOOLEAN notify_app);
+void nfa_ce_sys_disable (void);
+void nfa_ce_free_scratch_buf (void);
+
+#endif /* NFA_DM_INT_H */
+
diff --git a/src/nfa/int/nfa_cho_int.h b/src/nfa/int/nfa_cho_int.h
new file mode 100644
index 0000000..4d0142a
--- /dev/null
+++ b/src/nfa/int/nfa_cho_int.h
@@ -0,0 +1,295 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA Connection Handover.
+ *
+ ******************************************************************************/
+#ifndef NFA_CHO_INT_H
+#define NFA_CHO_INT_H
+
+#if (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE))
+#include "llcp_api.h"
+#include "llcp_defs.h"
+#include "nfa_cho_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* NFA Connection Handover state */
+enum
+{
+    NFA_CHO_ST_DISABLED,        /* Application has not registered      */
+    NFA_CHO_ST_IDLE,            /* No data link connection             */
+    NFA_CHO_ST_W4_CC,           /* Waiting for connection confirm      */
+    NFA_CHO_ST_CONNECTED,       /* Data link connected                 */
+
+    NFA_CHO_ST_MAX
+};
+
+typedef UINT8 tNFA_CHO_STATE;
+
+/* NFA Connection Handover substate in NFA_CHO_ST_CONNECTED */
+enum
+{
+    NFA_CHO_SUBSTATE_W4_LOCAL_HR,   /* Waiting for Hs record from local     */
+    NFA_CHO_SUBSTATE_W4_LOCAL_HS,   /* Waiting for Hs record from local     */
+    NFA_CHO_SUBSTATE_W4_REMOTE_HR,  /* Waiting for Hr record from remote    */
+    NFA_CHO_SUBSTATE_W4_REMOTE_HS,  /* Waiting for Hs record from remote    */
+
+    NFA_CHO_SUBSTATE_MAX
+};
+
+typedef UINT8 tNFA_CHO_SUBSTATE;
+
+/* Handover Message receiving status for SAR */
+#define NFA_CHO_RX_NDEF_COMPLETE    0   /* received complete NDEF message */
+#define NFA_CHO_RX_NDEF_TEMP_MEM    1   /* Cannot process due to temporary memory constraint */
+#define NFA_CHO_RX_NDEF_PERM_MEM    2   /* Cannot process due to permanent memory constraint */
+#define NFA_CHO_RX_NDEF_INCOMPLTE   3   /* Need more date       */
+#define NFA_CHO_RX_NDEF_INVALID     4   /* Invalid NDEF message */
+
+typedef UINT8 tNFA_CHO_RX_NDEF_STATUS;
+
+/* Handover Message Type */
+#define NFA_CHO_MSG_UNKNOWN         0   /* Unknown Message           */
+#define NFA_CHO_MSG_HR              1   /* Handover Request Message  */
+#define NFA_CHO_MSG_HS              2   /* Handover Select Message   */
+#define NFA_CHO_MSG_BT_OOB          3   /* Simplified BT OOB message */
+#define NFA_CHO_MSG_WIFI            4   /* Simplified WIFI message   */
+
+typedef UINT8 tNFA_CHO_MSG_TYPE;
+
+/* Timeout */
+#define NFA_CHO_TIMEOUT_FOR_HS          1000    /* ms, waiting for Hs record */
+#define NFA_CHO_TIMEOUT_FOR_RETRY       1000    /* ms, retry because of temp memory constrain */
+#define NFA_CHO_TIMEOUT_SEGMENTED_HR    500     /* ms, waiting for next segmented Hr */
+
+#define NFA_CHO_EXCLUDING_PAYLOAD_ID    0xFF    /* don't include payload ID string */
+
+/* NFA Connection Handover internal events */
+enum
+{
+    NFA_CHO_API_REG_EVT     = NFA_SYS_EVT_START (NFA_ID_CHO), /* NFA_ChoRegister () */
+    NFA_CHO_API_DEREG_EVT,            /* NFA_ChoDeregister ()       */
+    NFA_CHO_API_CONNECT_EVT,          /* NFA_ChoConnect ()          */
+    NFA_CHO_API_DISCONNECT_EVT,       /* NFA_ChoDisconnect ()       */
+    NFA_CHO_API_SEND_HR_EVT,          /* NFA_ChoSendHr ()           */
+    NFA_CHO_API_SEND_HS_EVT,          /* NFA_ChoSendHs ()           */
+    NFA_CHO_API_SEL_ERR_EVT,          /* NFA_ChoSendSelectError ()  */
+
+    NFA_CHO_RX_HANDOVER_MSG_EVT,      /* Received Handover Message  */
+
+    NFA_CHO_LLCP_CONNECT_IND_EVT,     /* LLCP_SAP_EVT_CONNECT_IND       */
+    NFA_CHO_LLCP_CONNECT_RESP_EVT,    /* LLCP_SAP_EVT_CONNECT_RESP      */
+    NFA_CHO_LLCP_DISCONNECT_IND_EVT,  /* LLCP_SAP_EVT_DISCONNECT_IND    */
+    NFA_CHO_LLCP_DISCONNECT_RESP_EVT, /* LLCP_SAP_EVT_DISCONNECT_RESP   */
+    NFA_CHO_LLCP_CONGEST_EVT,         /* LLCP_SAP_EVT_CONGEST           */
+    NFA_CHO_LLCP_LINK_STATUS_EVT,     /* LLCP_SAP_EVT_LINK_STATUS       */
+
+    NFA_CHO_NDEF_TYPE_HANDLER_EVT,    /* Callback event from NDEF Type handler */
+    NFA_CHO_TIMEOUT_EVT,              /* Timeout event              */
+
+    NFA_CHO_LAST_EVT
+};
+
+typedef UINT16 tNFA_CHO_INT_EVT;
+
+/* data type for NFA_CHO_API_REG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    BOOLEAN             enable_server;
+    tNFA_CHO_CBACK     *p_cback;
+} tNFA_CHO_API_REG;
+
+/* data type for NFA_CHO_API_DEREG_EVT */
+typedef BT_HDR tNFA_CHO_API_DEREG;
+
+/* data type for NFA_CHO_API_CONNECT_EVT */
+typedef BT_HDR tNFA_CHO_API_CONNECT;
+
+/* data type for NFA_CHO_API_DISCONNECT_EVT */
+typedef BT_HDR tNFA_CHO_API_DISCONNECT;
+
+/* data type for NFA_CHO_API_SEND_HR_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               num_ac_info;
+    tNFA_CHO_AC_INFO   *p_ac_info;
+    UINT8              *p_ndef;
+    UINT32              max_ndef_size;
+    UINT32              cur_ndef_size;
+} tNFA_CHO_API_SEND_HR;
+
+/* data type for NFA_CHO_API_SEND_HS_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               num_ac_info;
+    tNFA_CHO_AC_INFO   *p_ac_info;
+    UINT8              *p_ndef;
+    UINT32              max_ndef_size;
+    UINT32              cur_ndef_size;
+} tNFA_CHO_API_SEND_HS;
+
+/* data type for NFA_CHO_API_STOP_EVT */
+typedef BT_HDR tNFA_CHO_API_STOP;
+
+/* data type for NFA_CHO_API_SEL_ERR_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               error_reason;
+    UINT32              error_data;
+} tNFA_CHO_API_SEL_ERR;
+
+/* data type for NFA_CHO_NDEF_TYPE_HANDLER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_NDEF_EVT       event;
+    tNFA_NDEF_EVT_DATA  data;
+} tNFA_CHO_NDEF_TYPE_HDLR_EVT;
+
+/* union of all event data types */
+typedef union
+{
+    BT_HDR                      hdr;                /* NFA_CHO_TIMEOUT_EVT        */
+    tNFA_CHO_API_REG            api_reg;            /* NFA_CHO_API_REG_EVT        */
+    tNFA_CHO_API_DEREG          api_dereg;          /* NFA_CHO_API_DEREG_EVT      */
+    tNFA_CHO_API_CONNECT        api_connect;        /* NFA_CHO_API_CONNECT_EVT    */
+    tNFA_CHO_API_DISCONNECT     api_disconnect;     /* NFA_CHO_API_DISCONNECT_EVT */
+    tNFA_CHO_API_SEND_HR        api_send_hr;        /* NFA_CHO_API_SEND_HR_EVT    */
+    tNFA_CHO_API_SEND_HS        api_send_hs;        /* NFA_CHO_API_SEND_HS_EVT    */
+    tNFA_CHO_API_SEL_ERR        api_sel_err;        /* NFA_CHO_API_SEL_ERR_EVT    */
+    tNFA_CHO_NDEF_TYPE_HDLR_EVT ndef_type_hdlr;     /* NFA_CHO_NDEF_TYPE_HANDLER_EVT */
+    tLLCP_SAP_CBACK_DATA        llcp_cback_data;    /* LLCP callback data         */
+} tNFA_CHO_INT_EVENT_DATA;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+
+#define NFA_CHO_FLAGS_LLCP_ACTIVATED    0x01
+#define NFA_CHO_FLAGS_CLIENT_ONLY       0x02    /* Handover server is not enabled       */
+#define NFA_CHO_FLAGS_CONN_COLLISION    0x04    /* collision when creating data link    */
+
+/* NFA Connection Handover control block */
+typedef struct
+{
+    tNFA_CHO_STATE      state;                  /* main state                           */
+    tNFA_CHO_SUBSTATE   substate;               /* substate in connected state          */
+    TIMER_LIST_ENT      timer;                  /* timer for rx handover message        */
+
+    UINT8               server_sap;             /* SAP for local handover server        */
+    UINT8               client_sap;             /* SAP for connection to remote handover server */
+    UINT8               local_sap;              /* SSAP for connection, either server_sap or client_sap */
+    UINT8               remote_sap;             /* DSAP for connection                  */
+
+    UINT8               flags;                  /* internal flags                       */
+    tNFA_CHO_DISC_REASON disc_reason;           /* disconnection reason                 */
+
+    tNFA_HANDLE         hs_ndef_type_handle;    /* handle for HS NDEF Type handler      */
+    tNFA_HANDLE         bt_ndef_type_handle;    /* handle for BT OOB NDEF Type handler  */
+    tNFA_HANDLE         wifi_ndef_type_handle;  /* handle for WiFi NDEF Type handler    */
+
+    UINT16              local_link_miu;         /* MIU of local LLCP                    */
+    UINT16              remote_miu;             /* peer's MIU of data link connection   */
+    BOOLEAN             congested;              /* TRUE if data link is congested       */
+
+    UINT8               collision_local_sap;    /* SSAP for collision connection        */
+    UINT8               collision_remote_sap;   /* DSAP for collision connection        */
+    UINT16              collision_remote_miu;   /* peer's MIU of collision  connection  */
+    BOOLEAN             collision_congested;    /* TRUE if collision connection is congested */
+
+    UINT16              tx_random_number;       /* it has been sent in Hr for collision */
+
+    UINT8              *p_tx_ndef_msg;          /* allocate buffer for tx NDEF msg      */
+    UINT32              tx_ndef_cur_size;       /* current size of NDEF message         */
+    UINT32              tx_ndef_sent_size;      /* transmitted size of NDEF message     */
+
+    UINT8              *p_rx_ndef_msg;          /* allocate buffer for rx NDEF msg      */
+    UINT32              rx_ndef_buf_size;       /* allocate buffer size for rx NDEF msg */
+    UINT32              rx_ndef_cur_size;       /* current rx size of NDEF message      */
+
+    tNFA_CHO_CBACK     *p_cback;                /* callback registered by application   */
+
+    UINT8               trace_level;
+
+#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE))
+    UINT8               test_enabled;
+    UINT8               test_version;
+    UINT16              test_random_number;
+#endif
+} tNFA_CHO_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA Connection Handover control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_CHO_CB nfa_cho_cb;
+#else
+extern tNFA_CHO_CB *nfa_cho_cb_ptr;
+#define nfa_cho_cb (*nfa_cho_cb_ptr)
+#endif
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/* nfa_cho_main.c */
+void nfa_cho_init (void);
+
+/* nfa_cho_sm.c */
+void nfa_cho_sm_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_cho_sm_execute (tNFA_CHO_INT_EVT event, tNFA_CHO_INT_EVENT_DATA *p_evt_data);
+
+/* nfa_cho_util.c */
+void nfa_cho_proc_ndef_type_handler_evt (tNFA_CHO_INT_EVENT_DATA *p_evt_data);
+tNFA_STATUS nfa_cho_proc_api_reg (tNFA_CHO_INT_EVENT_DATA *p_evt_data);
+void        nfa_cho_proc_api_dereg (void);
+tNFA_STATUS nfa_cho_create_connection (void);
+void nfa_cho_process_disconnection (tNFA_CHO_DISC_REASON disc_reason);
+void nfa_cho_notify_tx_fail_evt (tNFA_STATUS status);
+
+tNFA_STATUS nfa_cho_send_handover_msg (void);
+tNFA_CHO_RX_NDEF_STATUS nfa_cho_read_ndef_msg (UINT8 local_sap, UINT8 remote_sap);
+tNFA_CHO_RX_NDEF_STATUS nfa_cho_reassemble_ho_msg (UINT8 local_sap, UINT8 remote_sap);
+
+tNFA_STATUS nfa_cho_send_hr (tNFA_CHO_API_SEND_HR *p_api_send_hr);
+tNFA_STATUS nfa_cho_send_hs (tNFA_CHO_API_SEND_HS *p_api_select);
+tNFA_STATUS nfa_cho_send_hs_error (UINT8 error_reason, UINT32 error_data);
+
+void nfa_cho_proc_hr (UINT32 length, UINT8 *p_ndef_msg);
+void nfa_cho_proc_hs (UINT32 length, UINT8 *p_ndef_msg);
+void nfa_cho_proc_simplified_format (UINT32 length, UINT8 *p_ndef_msg);
+
+tNFA_CHO_MSG_TYPE  nfa_cho_get_msg_type (UINT32 length, UINT8 *p_ndef_msg);
+tNFA_CHO_ROLE_TYPE nfa_cho_get_local_device_role (UINT32 length, UINT8 *p_ndef_msg);
+tNFA_STATUS nfa_cho_update_random_number (UINT8 *p_ndef_msg);
+#else
+
+#define nfa_cho_init ()
+
+#endif /* (defined (NFA_CHO_INCLUDED) && (NFA_CHO_INCLUDED==TRUE)) */
+#endif /* NFA_CHO_INT_H */
diff --git a/src/nfa/int/nfa_dm_int.h b/src/nfa/int/nfa_dm_int.h
new file mode 100644
index 0000000..3abf918
--- /dev/null
+++ b/src/nfa/int/nfa_dm_int.h
@@ -0,0 +1,596 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA device manager.
+ *
+ ******************************************************************************/
+#ifndef NFA_DM_INT_H
+#define NFA_DM_INT_H
+
+#include "nfc_api.h"
+#include "nfa_api.h"
+
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* DM events */
+enum
+{
+    /* device manager local device API events */
+    NFA_DM_API_ENABLE_EVT           = NFA_SYS_EVT_START (NFA_ID_DM),
+    NFA_DM_API_DISABLE_EVT,
+    NFA_DM_API_SET_CONFIG_EVT,
+    NFA_DM_API_GET_CONFIG_EVT,
+    NFA_DM_API_REQUEST_EXCL_RF_CTRL_EVT,
+    NFA_DM_API_RELEASE_EXCL_RF_CTRL_EVT,
+    NFA_DM_API_ENABLE_POLLING_EVT,
+    NFA_DM_API_DISABLE_POLLING_EVT,
+    NFA_DM_API_RAW_FRAME_EVT,
+    NFA_DM_API_SET_P2P_LISTEN_TECH_EVT,
+    NFA_DM_API_START_RF_DISCOVERY_EVT,
+    NFA_DM_API_STOP_RF_DISCOVERY_EVT,
+    NFA_DM_API_SET_RF_DISC_DURATION_EVT,
+    NFA_DM_API_SELECT_EVT,
+    NFA_DM_API_UPDATE_RF_PARAMS_EVT,
+    NFA_DM_API_DEACTIVATE_EVT,
+    NFA_DM_API_POWER_OFF_SLEEP_EVT,
+    NFA_DM_API_REG_NDEF_HDLR_EVT,
+    NFA_DM_API_DEREG_NDEF_HDLR_EVT,
+    NFA_DM_API_REG_VSC_EVT,
+    NFA_DM_API_SEND_VSC_EVT,
+    NFA_DM_TIMEOUT_DISABLE_EVT,
+    NFA_DM_MAX_EVT
+};
+
+
+/* data type for NFA_DM_API_ENABLE_EVT */
+typedef struct
+{
+    BT_HDR                  hdr;
+    tNFA_DM_CBACK           *p_dm_cback;
+    tNFA_CONN_CBACK         *p_conn_cback;
+} tNFA_DM_API_ENABLE;
+
+/* data type for NFA_DM_API_DISABLE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    BOOLEAN             graceful;
+} tNFA_DM_API_DISABLE;
+
+/* data type for NFA_DM_API_SET_CONFIG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_PMID           param_id;
+    UINT8               length;
+    UINT8              *p_data;
+} tNFA_DM_API_SET_CONFIG;
+
+/* data type for NFA_DM_API_GET_CONFIG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               num_ids;
+    tNFA_PMID          *p_pmids;
+} tNFA_DM_API_GET_CONFIG;
+
+/* data type for NFA_DM_API_REQ_EXCL_RF_CTRL_EVT */
+typedef struct
+{
+    BT_HDR               hdr;
+    tNFA_TECHNOLOGY_MASK poll_mask;
+    tNFA_LISTEN_CFG      listen_cfg;
+    tNFA_CONN_CBACK     *p_conn_cback;
+    tNFA_NDEF_CBACK     *p_ndef_cback;
+} tNFA_DM_API_REQ_EXCL_RF_CTRL;
+
+/* data type for NFA_DM_API_ENABLE_POLLING_EVT */
+typedef struct
+{
+    BT_HDR               hdr;
+    tNFA_TECHNOLOGY_MASK poll_mask;
+} tNFA_DM_API_ENABLE_POLL;
+
+/* data type for NFA_DM_API_SET_P2P_LISTEN_TECH_EVT */
+typedef struct
+{
+    BT_HDR                  hdr;
+    tNFA_TECHNOLOGY_MASK    tech_mask;
+} tNFA_DM_API_SET_P2P_LISTEN_TECH;
+
+/* data type for NFA_DM_API_SELECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               rf_disc_id;
+    tNFA_NFC_PROTOCOL   protocol;
+    tNFA_INTF_TYPE      rf_interface;
+} tNFA_DM_API_SELECT;
+
+/* data type for NFA_DM_API_UPDATE_RF_PARAMS_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_RF_COMM_PARAMS params;
+} tNFA_DM_API_UPDATE_RF_PARAMS;
+
+/* data type for NFA_DM_API_DEACTIVATE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    BOOLEAN             sleep_mode;
+} tNFA_DM_API_DEACTIVATE;
+
+/* data type for NFA_DM_API_SET_RF_DISC_DURATION_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT16              rf_disc_dur_ms;
+} tNFA_DM_API_SET_RF_DISC_DUR;
+#define NFA_RF_DISC_DURATION_MAX                0xFFFF
+
+/* data type for NFA_DM_API_REG_NDEF_HDLR_EVT */
+#define NFA_NDEF_FLAGS_HANDLE_WHOLE_MESSAGE     0x01
+#define NFA_NDEF_FLAGS_WKT_URI                  0x02
+#define NFA_NDEF_FLAGS_WHOLE_MESSAGE_NOTIFIED   0x04
+
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         ndef_type_handle;
+    UINT8               flags;
+    tNFA_NDEF_CBACK    *p_ndef_cback;
+    tNFA_TNF            tnf;                /* Type-name field of record-type that was registered.                  */
+    tNFA_NDEF_URI_ID    uri_id;             /* URI prefix abrieviation (for NFA_RegisterNDefUriHandler)             */
+    UINT8               name_len;           /* Length of type name or absolute URI                                  */
+    UINT8               name[1];            /* Type name or absolute URI of record-type that got was registered.    */
+} tNFA_DM_API_REG_NDEF_HDLR;
+
+/* data type for NFA_DM_API_DEREG_NDEF_HDLR_EVT */
+typedef struct
+{
+    BT_HDR      hdr;
+    tNFA_HANDLE ndef_type_handle;
+} tNFA_DM_API_DEREG_NDEF_HDLR;
+
+/* data type for NFA_DM_API_REG_VSC_EVT */
+typedef struct
+{
+    BT_HDR          hdr;
+    tNFA_VSC_CBACK  *p_cback;
+    BOOLEAN         is_register;
+} tNFA_DM_API_REG_VSC;
+
+/* data type for NFA_DM_API_SEND_VSC_EVT */
+typedef struct
+{
+    BT_HDR          hdr;
+    tNFA_VSC_CBACK  *p_cback;
+    UINT8           oid;
+    UINT8           cmd_params_len;
+    UINT16          pad;    /* add padding to ensure the size is big enough for offset=NCI_VSC_MSG_HDR_SIZE */
+    UINT8           *p_cmd_params;
+} tNFA_DM_API_SEND_VSC;
+
+
+/* union of all data types */
+typedef union
+{
+    /* GKI event buffer header */
+    BT_HDR                          hdr;                /* NFA_DM_API_RAW_FRAME_EVT             */
+                                                        /* NFA_DM_API_MULTI_TECH_RSP_EVT        */
+                                                        /* NFA_DM_API_RELEASE_EXCL_RF_CTRL      */
+                                                        /* NFA_DM_API_DISABLE_POLLING_EVT       */
+                                                        /* NFA_DM_API_START_RF_DISCOVERY_EVT    */
+                                                        /* NFA_DM_API_STOP_RF_DISCOVERY_EVT     */
+    tNFA_DM_API_ENABLE              enable;             /* NFA_DM_API_ENABLE_EVT                */
+    tNFA_DM_API_DISABLE             disable;            /* NFA_DM_API_DISABLE_EVT               */
+    tNFA_DM_API_SET_CONFIG          setconfig;          /* NFA_DM_API_SET_CONFIG_EVT            */
+    tNFA_DM_API_GET_CONFIG          getconfig;          /* NFA_DM_API_GET_CONFIG_EVT            */
+    tNFA_DM_API_SET_RF_DISC_DUR     disc_duration;      /* NFA_DM_API_SET_RF_DISC_DURATION_EVT  */
+    tNFA_DM_API_REG_NDEF_HDLR       reg_ndef_hdlr;      /* NFA_DM_API_REG_NDEF_HDLR_EVT         */
+    tNFA_DM_API_DEREG_NDEF_HDLR     dereg_ndef_hdlr;    /* NFA_DM_API_DEREG_NDEF_HDLR_EVT       */
+    tNFA_DM_API_REQ_EXCL_RF_CTRL    req_excl_rf_ctrl;   /* NFA_DM_API_REQUEST_EXCL_RF_CTRL      */
+    tNFA_DM_API_ENABLE_POLL         enable_poll;        /* NFA_DM_API_ENABLE_POLLING_EVT        */
+    tNFA_DM_API_SET_P2P_LISTEN_TECH set_p2p_listen_tech;/* NFA_DM_API_SET_P2P_LISTEN_TECH_EVT   */
+    tNFA_DM_API_SELECT              select;             /* NFA_DM_API_SELECT_EVT                */
+    tNFA_DM_API_UPDATE_RF_PARAMS    update_rf_params;   /* NFA_DM_API_UPDATE_RF_PARAMS_EVT      */
+    tNFA_DM_API_DEACTIVATE          deactivate;         /* NFA_DM_API_DEACTIVATE_EVT            */
+    tNFA_DM_API_SEND_VSC            send_vsc;           /* NFA_DM_API_SEND_VSC_EVT              */
+    tNFA_DM_API_REG_VSC             reg_vsc;            /* NFA_DM_API_REG_VSC_EVT               */
+} tNFA_DM_MSG;
+
+/* DM RF discovery state */
+enum
+{
+    NFA_DM_RFST_IDLE,               /* idle state                     */
+    NFA_DM_RFST_DISCOVERY,          /* discovery state                */
+    NFA_DM_RFST_W4_ALL_DISCOVERIES, /* wait for all discoveries state */
+    NFA_DM_RFST_W4_HOST_SELECT,     /* wait for host selection state  */
+    NFA_DM_RFST_POLL_ACTIVE,        /* poll mode activated state      */
+    NFA_DM_RFST_LISTEN_ACTIVE,      /* listen mode activated state    */
+    NFA_DM_RFST_LISTEN_SLEEP,       /* listen mode sleep state        */
+    NFA_DM_RFST_LP_LISTEN,          /* Listening in Low Power mode    */
+    NFA_DM_RFST_LP_ACTIVE           /* Activated in Low Power mode    */
+};
+typedef UINT8 tNFA_DM_RF_DISC_STATE;
+
+/* DM RF discovery state machine event */
+enum
+{
+    NFA_DM_RF_DISCOVER_CMD,         /* start RF discovery                    */
+    NFA_DM_RF_DISCOVER_RSP,         /* discover response from NFCC           */
+    NFA_DM_RF_DISCOVER_NTF,         /* RF discovery NTF from NFCC            */
+    NFA_DM_RF_DISCOVER_SELECT_CMD,  /* select discovered target              */
+    NFA_DM_RF_DISCOVER_SELECT_RSP,  /* select response from NFCC             */
+    NFA_DM_RF_INTF_ACTIVATED_NTF,   /* RF interface activation NTF from NFCC */
+    NFA_DM_RF_DEACTIVATE_CMD,       /* deactivate RF interface               */
+    NFA_DM_RF_DEACTIVATE_RSP,       /* deactivate response from NFCC         */
+    NFA_DM_RF_DEACTIVATE_NTF,       /* deactivate RF interface NTF from NFCC */
+    NFA_DM_LP_LISTEN_CMD,           /* NFCC is listening in low power mode   */
+    NFA_DM_CORE_INTF_ERROR_NTF,     /* RF interface error NTF from NFCC      */
+    NFA_DM_DISC_SM_MAX_EVENT
+};
+typedef UINT8 tNFA_DM_RF_DISC_SM_EVENT;
+
+/* DM RF discovery state machine data */
+typedef struct
+{
+    UINT8               rf_disc_id;
+    tNFA_NFC_PROTOCOL   protocol;
+    tNFA_INTF_TYPE      rf_interface;
+} tNFA_DM_DISC_SELECT_PARAMS;
+
+typedef union
+{
+    tNFC_DISCOVER               nfc_discover;       /* discovery data from NFCC    */
+    tNFC_DEACT_TYPE             deactivate_type;    /* deactivation type           */
+    tNFA_DM_DISC_SELECT_PARAMS  select;             /* selected target information */
+} tNFA_DM_RF_DISC_DATA;
+
+/* Callback event from NFA DM RF Discovery to other NFA sub-modules */
+enum
+{
+    NFA_DM_RF_DISC_START_EVT,           /* discovery started with protocol, technology and mode       */
+    NFA_DM_RF_DISC_ACTIVATED_EVT,       /* activated with configured protocol, technology and mode    */
+    NFA_DM_RF_DISC_DEACTIVATED_EVT,     /* deactivated sleep or idle                                  */
+    NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT    /* deactivated to idle from host select or listen sleep state */
+                                        /*  by DH request                                             */
+};
+typedef UINT8 tNFA_DM_RF_DISC_EVT;
+
+/* Combined NFC Technology and protocol bit mask */
+#define NFA_DM_DISC_MASK_PA_T1T                 0x00000001
+#define NFA_DM_DISC_MASK_PA_T2T                 0x00000002
+#define NFA_DM_DISC_MASK_PA_ISO_DEP             0x00000004
+#define NFA_DM_DISC_MASK_PA_NFC_DEP             0x00000008
+#define NFA_DM_DISC_MASK_PB_ISO_DEP             0x00000010
+#define NFA_DM_DISC_MASK_PF_T3T                 0x00000020
+#define NFA_DM_DISC_MASK_PF_NFC_DEP             0x00000040
+#define NFA_DM_DISC_MASK_P_ISO15693             0x00000100
+#define NFA_DM_DISC_MASK_P_B_PRIME              0x00000200
+#define NFA_DM_DISC_MASK_P_KOVIO                0x00000400
+#define NFA_DM_DISC_MASK_PAA_NFC_DEP            0x00000800
+#define NFA_DM_DISC_MASK_PFA_NFC_DEP            0x00001000
+#define NFA_DM_DISC_MASK_P_LEGACY               0x00002000  /* Legacy/proprietary/non-NFC Forum protocol (e.g Shanghai transit card) */
+#define NFA_DM_DISC_MASK_POLL                   0x0000FFFF
+
+#define NFA_DM_DISC_MASK_LA_T1T                 0x00010000
+#define NFA_DM_DISC_MASK_LA_T2T                 0x00020000
+#define NFA_DM_DISC_MASK_LA_ISO_DEP             0x00040000
+#define NFA_DM_DISC_MASK_LA_NFC_DEP             0x00080000
+#define NFA_DM_DISC_MASK_LB_ISO_DEP             0x00100000
+#define NFA_DM_DISC_MASK_LF_T3T                 0x00200000
+#define NFA_DM_DISC_MASK_LF_NFC_DEP             0x00400000
+#define NFA_DM_DISC_MASK_L_ISO15693             0x01000000
+#define NFA_DM_DISC_MASK_L_B_PRIME              0x02000000
+#define NFA_DM_DISC_MASK_LAA_NFC_DEP            0x04000000
+#define NFA_DM_DISC_MASK_LFA_NFC_DEP            0x08000000
+#define NFA_DM_DISC_MASK_L_LEGACY               0x10000000
+#define NFA_DM_DISC_MASK_LISTEN                 0xFFFF0000
+
+typedef UINT32  tNFA_DM_DISC_TECH_PROTO_MASK;
+
+
+/* DM RF discovery host ID */
+#define NFA_DM_DISC_HOST_ID_DH          NFC_DH_ID
+typedef UINT8 tNFA_DM_DISC_HOST_ID;
+
+/* DM deactivation callback type */
+typedef void (tNFA_DISCOVER_CBACK) (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data);
+
+/* DM RF discovery action flags */
+#define NFA_DM_DISC_FLAGS_ENABLED        0x0001    /* RF discovery process has been started        */
+#define NFA_DM_DISC_FLAGS_STOPPING       0x0002    /* Stop RF discovery is pending                 */
+#define NFA_DM_DISC_FLAGS_DISABLING      0x0004    /* Disable NFA is pending                       */
+#define NFA_DM_DISC_FLAGS_CHECKING       0x0008    /* Presence check/unknown protocol in progress  */
+#define NFA_DM_DISC_FLAGS_NOTIFY         0x0010    /* Notify sub-module that discovery is starting */
+#define NFA_DM_DISC_FLAGS_W4_RSP         0x0020    /* command has been sent to NFCC in the state   */
+#define NFA_DM_DISC_FLAGS_W4_NTF         0x0040    /* wait for NTF before changing discovery state */
+
+typedef UINT16 tNFA_DM_DISC_FLAGS;
+
+/* DM Discovery control block */
+typedef struct
+{
+    BOOLEAN                         in_use;             /* TRUE if used          */
+    tNFA_DISCOVER_CBACK            *p_disc_cback;       /* discovery callback    */
+
+    tNFA_DM_DISC_FLAGS              disc_flags;         /* specific action flags */
+    tNFA_DM_DISC_HOST_ID            host_id;            /* DH or UICC1/UICC2     */
+    tNFA_DM_DISC_TECH_PROTO_MASK    requested_disc_mask;/* technology and protocol requested              */
+    tNFA_DM_DISC_TECH_PROTO_MASK    selected_disc_mask; /* technology and protocol waiting for activation */
+} tNFA_DM_DISC_ENTRY;
+
+#define NFA_DM_DISC_NUM_ENTRIES  8              /* polling, raw listen, P2P listen, NDEF CE, 2xVSE, 2xUICC */
+
+#define NFA_DM_MAX_DISC_PARAMS   16             /* max discovery technology parameters */
+
+/* index of listen mode routing table for technologies */
+enum {
+    NFA_DM_DISC_LRT_NFC_A,
+    NFA_DM_DISC_LRT_NFC_B,
+    NFA_DM_DISC_LRT_NFC_F,
+    NFA_DM_DISC_LRT_NFC_BP
+};
+
+/* SLP_REQ (HLTA) command */
+#define SLP_REQ_CMD     0x5000
+#define NFA_DM_MAX_TECH_ROUTE   4 /* NFA_EE_MAX_TECH_ROUTE. only A, B, F, Bprime are supported by UICC now */
+
+typedef struct
+{
+    UINT16                  disc_duration;          /* Disc duration                                    */
+    tNFA_DM_DISC_FLAGS      disc_flags;             /* specific action flags                            */
+    tNFA_DM_RF_DISC_STATE   disc_state;             /* RF discovery state                               */
+
+    tNFC_RF_TECH_N_MODE     activated_tech_mode;    /* activated technology and mode                    */
+    UINT8                   activated_rf_disc_id;   /* activated RF discovery ID                        */
+    tNFA_INTF_TYPE          activated_rf_interface; /* activated RF interface                           */
+    tNFA_NFC_PROTOCOL       activated_protocol;     /* activated protocol                               */
+    tNFA_HANDLE             activated_handle;       /* handle of activated sub-module                   */
+    UINT8                   activated_sel_res;      /* activated tag's SEL_RES response                 */
+
+    tNFA_DM_DISC_ENTRY      entry[NFA_DM_DISC_NUM_ENTRIES];
+
+    tNFA_DM_DISC_ENTRY      excl_disc_entry;        /* exclusive RF discovery                           */
+    tNFA_LISTEN_CFG         excl_listen_config;     /* listen cfg for exclusive-rf mode                 */
+
+    UINT8                   listen_RT[NFA_DM_MAX_TECH_ROUTE];/* Host ID for A, B, F, B' technology routing*/
+    tNFA_DM_DISC_TECH_PROTO_MASK    dm_disc_mask;   /* technology and protocol waiting for activation   */
+
+} tNFA_DM_DISC_CB;
+
+/* NDEF Type Handler Definitions */
+#define NFA_NDEF_DEFAULT_HANDLER_IDX    0           /* Default handler entry in ndef_handler table      */
+
+#define NFA_PARAM_ID_INVALID            0xFF
+
+/* Maximum number of pending SetConfigs */
+#define NFA_DM_SETCONFIG_PENDING_MAX            32
+
+/* NFA_DM flags */
+#define NFA_DM_FLAGS_DM_IS_ACTIVE               0x00000001  /* DM is enabled                                                        */
+#define NFA_DM_FLAGS_EXCL_RF_ACTIVE             0x00000002  /* Exclusive RF mode is active                                          */
+#define NFA_DM_FLAGS_POLLING_ENABLED            0x00000004  /* Polling is enabled (while not in exclusive RF mode                   */
+#define NFA_DM_FLAGS_SEND_POLL_STOP_EVT         0x00000008  /* send poll stop event                                                 */
+#define NFA_DM_FLAGS_AUTO_READING_NDEF          0x00000010  /* auto reading of NDEF in progress                                     */
+#define NFA_DM_FLAGS_ENABLE_EVT_PEND            0x00000020  /* NFA_DM_ENABLE_EVT is not reported yet                                */
+#define NFA_DM_FLAGS_SEND_DEACTIVATED_EVT       0x00000040  /* Send NFA_DEACTIVATED_EVT when deactivated                            */
+#define NFA_DM_FLAGS_NFCC_IS_RESTORING          0x00000100  /* NFCC is restoring after back to full power mode                      */
+#define NFA_DM_FLAGS_SETTING_PWR_MODE           0x00000200  /* NFCC power mode is updating                                          */
+#define NFA_DM_FLAGS_DM_DISABLING_NFC           0x00000400  /* NFA DM is disabling NFC                                              */
+/* stored parameters */
+typedef struct
+{
+    UINT8 total_duration[NCI_PARAM_LEN_TOTAL_DURATION];
+
+    UINT8 la_bit_frame_sdd[NCI_PARAM_LEN_LA_BIT_FRAME_SDD];
+    UINT8 la_bit_frame_sdd_len;
+    UINT8 la_platform_config[NCI_PARAM_LEN_LA_PLATFORM_CONFIG];
+    UINT8 la_platform_config_len;
+    UINT8 la_sel_info[NCI_PARAM_LEN_LA_SEL_INFO];
+    UINT8 la_sel_info_len;
+    UINT8 la_nfcid1[NCI_NFCID1_MAX_LEN];
+    UINT8 la_nfcid1_len;
+    UINT8 la_hist_by[NCI_MAX_HIS_BYTES_LEN];
+    UINT8 la_hist_by_len;
+
+    UINT8 lb_sensb_info[NCI_PARAM_LEN_LB_SENSB_INFO];
+    UINT8 lb_sensb_info_len;
+    UINT8 lb_nfcid0[NCI_PARAM_LEN_LB_NFCID0];
+    UINT8 lb_nfcid0_len;
+    UINT8 lb_appdata[NCI_PARAM_LEN_LB_APPDATA];
+    UINT8 lb_appdata_len;
+    UINT8 lb_adc_fo[NCI_PARAM_LEN_LB_ADC_FO];
+    UINT8 lb_adc_fo_len;
+    UINT8 lb_h_info[NCI_MAX_ATTRIB_LEN];
+    UINT8 lb_h_info_len;
+
+    UINT8 lf_protocol[NCI_PARAM_LEN_LF_PROTOCOL];
+    UINT8 lf_protocol_len;
+    UINT8 lf_t3t_flags2[NCI_PARAM_LEN_LF_T3T_FLAGS2];
+    UINT8 lf_t3t_flags2_len;
+    UINT8 lf_t3t_pmm[NCI_PARAM_LEN_LF_T3T_PMM];
+    UINT8 lf_t3t_id[NFA_CE_LISTEN_INFO_MAX][NCI_PARAM_LEN_LF_T3T_ID];
+
+    UINT8 fwi[NCI_PARAM_LEN_FWI];
+    UINT8 wt[NCI_PARAM_LEN_WT];
+    UINT8 atr_req_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+    UINT8 atr_req_gen_bytes_len;
+    UINT8 atr_res_gen_bytes[NCI_MAX_GEN_BYTES_LEN];
+    UINT8 atr_res_gen_bytes_len;
+} tNFA_DM_PARAMS;
+
+/* DM control block */
+typedef struct
+{
+    UINT32                      flags;              /* NFA_DM flags (see definitions for NFA_DM_FLAGS_*)    */
+    tNFA_DM_CBACK              *p_dm_cback;         /* NFA DM callback                                      */
+    TIMER_LIST_ENT              tle;
+
+    BOOLEAN                     presence_check_deact_pending; /* TRUE if deactivate while checking presence */
+    tNFA_DEACTIVATE_TYPE        presence_check_deact_type;    /* deactivate type                            */
+
+    /* NFC link connection management */
+    tNFA_CONN_CBACK            *p_conn_cback;       /* callback for connection events       */
+    tNFA_TECHNOLOGY_MASK        poll_mask;          /* technologies being polled            */
+
+    tNFA_CONN_CBACK            *p_excl_conn_cback;  /* exclusive RF mode callback           */
+    tNFA_NDEF_CBACK            *p_excl_ndef_cback;  /* ndef callback for exclusive RF mdoe  */
+
+    tNFA_HANDLE                 poll_disc_handle;   /* discovery handle for polling         */
+
+    UINT8                      *p_activate_ntf;     /* temp holding activation notfication  */
+
+    UINT8                       activated_nfcid[NCI_NFCID1_MAX_LEN];
+                                                    /* NFCID 0/1/2 or UID of ISO15694       */
+    UINT8                       activated_nfcid_len;/* length of NFCID ot UID               */
+
+    /* NFC link discovery management */
+    tNFA_DM_DISC_CB             disc_cb;
+
+    /* NDEF Type handler */
+    tNFA_DM_API_REG_NDEF_HDLR   *p_ndef_handler[NFA_NDEF_MAX_HANDLERS];    /* ndef handler table */
+
+    /* stored parameters */
+    tNFA_DM_PARAMS              params;
+
+    /* SetConfig management */
+    UINT32                      setcfg_pending_mask;    /* Mask of to indicate whether pending SET_CONFIGs require NFA_DM_SET_CONFIG_EVT. LSB=oldest pending */
+    UINT8                       setcfg_pending_num;     /* Number of setconfigs pending */
+
+    /* NFCC power mode */
+    UINT8                       nfcc_pwr_mode;          /* NFA_DM_PWR_MODE_FULL or NFA_DM_PWR_MODE_OFF_SLEEP */
+} tNFA_DM_CB;
+
+/* Internal function prototypes */
+void nfa_dm_ndef_handle_message (tNFA_STATUS status, UINT8 *p_msg_buf, UINT32 len);
+void nfa_dm_ndef_dereg_all (void);
+void nfa_dm_act_conn_cback_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data);
+void nfa_dm_notify_activation_status (tNFA_STATUS status, tNFA_TAG_PARAMS *p_params);
+void nfa_dm_disable_complete (void);
+
+/* Internal functions from nfa_rw */
+void nfa_rw_init (void);
+void nfa_rw_proc_disc_evt (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data, BOOLEAN excl_rf_not_active);
+tNFA_STATUS nfa_rw_send_raw_frame (BT_HDR *p_data);
+
+/* Internal functions from nfa_ce */
+void nfa_ce_init (void);
+
+/* Pointer to compile-time configuration structure */
+extern tNFA_DM_CFG *p_nfa_dm_cfg;
+extern UINT8 *p_nfa_dm_ce_cfg;
+extern UINT8 *p_nfa_dm_gen_cfg;
+extern UINT8 nfa_ee_max_ee_cfg;
+extern tNCI_DISCOVER_MAPS *p_nfa_dm_interface_mapping;
+extern UINT8 nfa_dm_num_dm_interface_mapping;
+
+/* NFA device manager control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_DM_CB nfa_dm_cb;
+#else
+extern tNFA_DM_CB *nfa_dm_cb_ptr;
+#define nfa_dm_cb (*nfa_dm_cb_ptr)
+#endif
+
+void nfa_dm_init (void);
+void nfa_p2p_init (void);
+void nfa_cho_init (void);
+void nfa_snep_init (BOOLEAN is_dta_mode);
+void nfa_dta_init (void);
+#if (NFC_NFCEE_INCLUDED == TRUE)
+void nfa_ee_init (void);
+void nfa_hci_init (void);
+#else
+#define nfa_ee_init()
+#define nfa_hci_init()
+#endif
+
+/* Action function prototypes */
+BOOLEAN nfa_dm_enable (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_disable (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_set_config (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_get_config (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_request_excl_rf_ctrl (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_release_excl_rf_ctrl (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_enable_polling (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_disable_polling (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_send_raw_frame (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_set_p2p_listen_tech (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_start_rf_discovery (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_stop_rf_discovery (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_set_rf_disc_duration (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_select (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_update_rf_params (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_deactivate (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_power_off_sleep (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_ndef_reg_hdlr (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_ndef_dereg_hdlr (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_tout (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_reg_vsc (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_send_vsc (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_disable_timeout (tNFA_DM_MSG *p_data);
+BOOLEAN nfa_dm_act_nfc_cback_data (tNFA_DM_MSG *p_data);
+
+void nfa_dm_proc_nfcc_power_mode (UINT8 nfcc_power_mode);
+
+/* Main function prototypes */
+BOOLEAN nfa_dm_evt_hdlr (BT_HDR *p_msg);
+void nfa_dm_sys_enable (void);
+void nfa_dm_sys_disable (void);
+tNFA_STATUS nfa_dm_check_set_config (UINT8 tlv_list_len, UINT8 *p_tlv_list, BOOLEAN app_init);
+
+void nfa_dm_conn_cback_event_notify (UINT8 event, tNFA_CONN_EVT_DATA *p_data);
+
+/* Discovery function prototypes */
+void nfa_dm_disc_sm_execute (tNFA_DM_RF_DISC_SM_EVENT event, tNFA_DM_RF_DISC_DATA *p_data);
+tNFA_HANDLE nfa_dm_add_rf_discover (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask, tNFA_DM_DISC_HOST_ID host_id, tNFA_DISCOVER_CBACK *p_disc_cback);
+void nfa_dm_delete_rf_discover (tNFA_HANDLE handle);
+void nfa_dm_start_excl_discovery (tNFA_TECHNOLOGY_MASK poll_tech_mask,
+                                  tNFA_LISTEN_CFG *p_listen_cfg,
+                                  tNFA_DISCOVER_CBACK  *p_disc_cback);
+void nfa_dm_rel_excl_rf_control_and_notify (void);
+void nfa_dm_stop_excl_discovery (void);
+void nfa_dm_disc_new_state (tNFA_DM_RF_DISC_STATE new_state);
+
+void nfa_dm_start_rf_discover (void);
+void nfa_dm_rf_discover_select (UINT8 rf_disc_id, tNFA_NFC_PROTOCOL protocol, tNFA_INTF_TYPE rf_interface);
+tNFA_STATUS nfa_dm_rf_deactivate (tNFA_DEACTIVATE_TYPE deactivate_type);
+BOOLEAN nfa_dm_is_protocol_supported (tNFA_NFC_PROTOCOL protocol, UINT8 sel_res);
+BOOLEAN nfa_dm_is_active (void);
+tNFC_STATUS nfa_dm_disc_presence_check (void);
+
+
+#if (NFC_NFCEE_INCLUDED == FALSE)
+#define nfa_ee_get_tech_route(ps, ha) memset(ha, NFC_DH_ID, NFA_DM_MAX_TECH_ROUTE);
+#endif
+
+#if (BT_TRACE_VERBOSE == TRUE)
+char *nfa_dm_nfc_revt_2_str (tNFC_RESPONSE_EVT event);
+#endif
+
+
+#endif /* NFA_DM_INT_H */
+
diff --git a/src/nfa/int/nfa_dta_int.h b/src/nfa/int/nfa_dta_int.h
new file mode 100644
index 0000000..b21d725
--- /dev/null
+++ b/src/nfa/int/nfa_dta_int.h
@@ -0,0 +1,414 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA DTA
+ *
+ ******************************************************************************/
+#ifndef NFA_DTA_INT_H
+#define NFA_DTA_INT_H
+
+#include "nfa_dta_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfc_api.h"
+#include "rw_api.h"
+#include "ce_api.h"
+
+#if (NFA_DTA_INCLUDED == TRUE)
+
+/*****************************************************************************
+**  DTA definitions
+*****************************************************************************/
+#define NFA_DTA_PATTERN_NUMBER_INVALID              0xFFFF
+
+#define NFA_DTA_DISCOVER_PARAMS_MAX     6
+
+#define NDEF_WKT_TEXT_HDR_LEN   7               /* Header length for long NDEF text message */
+#define NFA_DTA_T3T_WRITE_NDEF_SIZE     192     /* Size of NDEF message for T3T write-tests ([DTA] $5.5.6) */
+#define NFA_DTA_T3T_LISTEN_SYSTEMCODE   0xBABE  /* System code to use for T3T Listen mode tests */
+
+#define NFA_PROTOCOL_RANK_INVALID       0xFF    /* Maximum protocol preference rank */
+
+#define NFA_DTA_SCRATCH_BUF_SIZE        T3T_MSG_BLOCKSIZE
+
+#ifndef NFA_DTA_DEFAULT_CO_OUT_DSAP
+#define NFA_DTA_DEFAULT_CO_OUT_DSAP     0x10    /* Default SAP[LT,CO-OUT-DEST] if SDP was not performed to get SAP from the LT */
+#endif
+
+/*****************************************************************************
+* DTA state machine definitions
+*****************************************************************************/
+
+typedef struct {
+    BOOLEAN tp_continue;                    /* NFA_DTA_CFG_TP_CONTINUE    */
+    tNFA_DTA_FL_POLL_LISTEN poll_listen;    /* NFA_DTA_CFG_POLL_LISTEN    */
+    BOOLEAN t4at_nfcdep_priority;           /* NFA_DTA_CFG_T4AT_NFCDEP_PRIORITY */
+    BOOLEAN reactivation;                   /* NFA_DTA_CFG_REACTIVATION   */
+    UINT16  total_duration;                 /* NFA_DTA_CFG_TOTAL_DURATION */
+    BOOLEAN enable_dta_llcp;                /* NFA_DTA_CFG_LLCP */
+    tNFA_DTA_SNEP_MODE dta_snep_mode;       /* NFA_DTA_CFG_SNEP */
+    tNFA_DTA_EMVCO_PCD_MODE emvco_pcd_mode; /* NFA_DTA_CFG_EMVCO_PCD */
+} tNFA_DTA_CONFIG;
+
+/*****************************************************************************
+* DTA state machine definitions
+*****************************************************************************/
+/* DTA events */
+enum
+{
+    /* device manager local device API events */
+    NFA_DTA_API_ENABLE_EVT = NFA_SYS_EVT_START (NFA_ID_DTA),
+    NFA_DTA_API_DISABLE_EVT,
+    NFA_DTA_API_CONFIG_EVT,
+    NFA_DTA_API_START_EVT,
+    NFA_DTA_API_STOP_EVT,
+    NFA_DTA_ACTIVATE_EVT,
+    NFA_DTA_DEACTIVATE_EVT,
+    NFA_DTA_DATA_CBACK_EVT,
+
+    NFA_DTA_MAX_EVT
+};
+
+
+/* data type for NFA_DTA_API_ENABLE_EVT */
+typedef struct
+{
+    BT_HDR          hdr;
+    BOOLEAN         auto_start;
+    tNFA_DTA_CBACK  *p_cback;
+} tNFA_DTA_API_ENABLE;
+
+/* data type for NFA_DTA_API_START_EVT  */
+typedef struct
+{
+    BT_HDR                  hdr;
+    UINT8                   pattern_number;
+    UINT8                   tlv_len;
+    UINT8                   *p_tlv_params;
+} tNFA_DTA_API_START;
+
+/* data type for NFA_DTA_API_CONFIG  */
+typedef struct
+{
+    BT_HDR                  hdr;
+    tNFA_DTA_CFG_ITEM       item;
+    tNFA_DTA_CFG            cfg_data;
+} tNFA_DTA_API_CONFIG;
+
+/* data type for NFA_DTA_DATA_CBACK_EVT */
+typedef struct
+{
+    UINT8                   event;
+    tRW_DATA                data;
+} tNFA_DTA_RW_DATA;
+
+typedef struct
+{
+    UINT8                   event;
+    tCE_DATA                data;
+} tNFA_DTA_CE_DATA;
+
+typedef struct
+{
+    tNFC_CONN_EVT           event;
+    tNFC_CONN               data;
+} tNFA_DTA_NFCDEP_DATA;
+
+
+enum
+{
+    NFA_DTA_LLCP_CONNECT_CO_ECHO_OUT,
+    NFA_DTA_LLCP_DISCONNECT_CO_ECHO_OUT
+};
+typedef UINT8 tNFA_DTA_LLCP_EVT;
+
+enum
+{
+    NFA_DTA_RW_DATA,
+    NFA_DTA_CE_DATA,
+    NFA_DTA_NFCDEP_DATA,
+    NFA_DTA_LLCP_DATA
+};
+
+typedef UINT8 tNFA_DTA_DATA_TYPE;
+
+typedef struct
+{
+    BT_HDR                  hdr;
+    tNFA_DTA_DATA_TYPE      type;
+    union
+    {
+        tNFA_DTA_RW_DATA        rw;
+        tNFA_DTA_CE_DATA        ce;
+        tNFA_DTA_NFCDEP_DATA    nfcdep;
+        tNFA_DTA_LLCP_EVT       llcp_evt;
+    } data;
+} tNFA_DTA_DATA_CBACK;
+
+/* All API message type */
+typedef union
+{
+    BT_HDR              hdr;
+    tNFA_DTA_API_ENABLE enable;
+    tNFA_DTA_API_CONFIG cfg;
+    tNFA_DTA_API_START  start;
+    tNFA_DTA_DATA_CBACK data_cback;
+}tNFA_DTA_MSG;
+
+
+
+/* DTA states */
+enum
+{
+    NFA_DTA_ST_IDLE,
+    NFA_DTA_ST_DISCOVER,        /* Polling/Listening */
+    NFA_DTA_ST_ACTIVATED        /* Activated, listen mode */
+};
+typedef UINT8 tNFA_DTA_STATE;
+
+/* DTA Substates (while in ACTIVATED state) - substate enumerations are found in protocol-specific files (nfa_dta_XXX.c) */
+#define NFA_DTA_SST_IDLE    0
+typedef UINT8 tNFA_DTA_SUBSTATE;
+
+/* DTA discovery states */
+enum
+{
+    NFA_DTA_DISC_STATE_IDLE,
+    NFA_DTA_DISC_STATE_DISCOVERY,
+    NFA_DTA_DISC_STATE_POLL_ACTIVE,
+    NFA_DTA_DISC_STATE_W4_ALL_DISCOVERIES,
+    NFA_DTA_DISC_STATE_W4_HOST_SELECT,
+    NFA_DTA_DISC_STATE_LISTEN_ACTIVE,
+    NFA_DTA_DISC_STATE_LISTEN_SLEEP,
+    NFA_DTA_DISC_STATE_MAX
+};
+
+/*****************************************************************************
+* DTA control block definitions
+*****************************************************************************/
+
+/* NDEF buffer definitions */
+enum {
+    NFA_DTA_BUF_READ,               /* Buffer for RW Read requests */
+    NFA_DTA_BUF_WRITE,              /* Buffer for RW Write requests */
+    NFA_DTA_BUF_MAX
+};
+
+typedef struct {
+    UINT8   *p_data;
+    UINT32  max_size;
+    UINT32  cur_size;
+    UINT32  offset;     /* current read/write offset */
+} tNFA_DTA_BUF_CB;
+
+
+/* T4T listen mode test application */
+enum {
+    NFA_DTA_T4T_CE_APP_NONE,        /* Not selected */
+    NFA_DTA_T4T_CE_APP_LOOPBACK,    /* loopback test applicaiton */
+    NFA_DTA_T4T_CE_APP_PROP         /* propretary test application */
+};
+
+/* DTA test step command */
+typedef tNFC_STATUS (*tNFA_DTA_CMD_FCN) (void *);
+
+/* dta control block flags */
+#define NFA_DTA_FL_ENABLED                      0x00000001  /* DTA is enabled */
+#define NFA_DTA_FL_AUTOSTART                    0x00000002  /* Automatically start discovery when NFC is enabled */
+#define NFA_DTA_FL_STOPPING                     0x00000004  /* DTA is stopping (NFA_DtaStop called) */
+#define NFA_DTA_FL_DISABLING                    0x00000008  /* DTA is being disabled (NFA_DtaDisable called) */
+#define NFA_DTA_FL_T4T_DESELECT_DEACT           0x00000010  /* T4T/NFCDEP is deactivating to IDLE (need to DESELECT first) */
+
+/* DTA control block */
+typedef struct {
+    UINT32                  dta_flags;      /* dta_flags must be first item in structure (statically intialized to 0 on startup) */
+
+    /* Configuration */
+    tNFA_DTA_CONFIG         cfg;
+
+    /* DTA State Machine */
+    tNFA_DTA_STATE          state;
+    tNFA_DTA_SUBSTATE       substate;       /* Current protocol-specific sub-state */
+    tNFA_DTA_CBACK          *p_cback;       /* Applicatation for DTA event notification */
+
+    /* DTA test parameters */
+    UINT32                  pattern_number;
+    UINT32                  pattern_number_old;
+
+    /* Discovery Parameters */
+    UINT8                   disc_state;
+    UINT8                   disc_params_num;
+    tNFC_DISCOVER_PARAMS    disc_params[NFA_DTA_DISCOVER_PARAMS_MAX];
+
+    /* Activation parameters */
+    tNFC_ACTIVATE_DEVT      activate_params;
+    UINT8                   cur_protocol_rank;  /* perference ranking of currently discovered protocol */
+
+    tRW_CBACK              *p_rw_cback;
+    tCE_CBACK              *p_ce_cback;
+
+    TIMER_LIST_ENT          protocol_timer;     /* timer for the activated protocol if needed */
+
+    UINT8                   t4t_ce_app;         /* T4T listen mode test application */
+    tCE_T4T_AID_HANDLE      t4t_dta_aid_hdl;    /* T4T registration handle for proprietary dta aid */
+    tCE_T4T_AID_HANDLE      t4t_prop_aid_hdl;   /* T4T registration handle for proprietary aid */
+    UINT8                   nfc_dep_wt;
+
+    BOOLEAN                 llcp_cl_more_to_read;    /* TRUE if there is more to read in llcp cl link*/
+    BOOLEAN                 llcp_co_more_to_read;    /* TRUE if there is more to read in llcp recieve window*/
+    BOOLEAN                 llcp_is_initiator;      /* TURE if IUT is LLCP initiator */
+    UINT16                  llcp_local_link_miu;    /* link MIU of IUT               */
+    UINT16                  llcp_remote_link_miu;   /* link MIU of LT                */
+
+    UINT8                   llcp_cl_in_local_sap;   /* SAP of IUT-CL-IN-DEST */
+    UINT8                   llcp_cl_out_local_sap;  /* SAP of IUT-CL-OUT-SRC */
+    UINT8                   llcp_cl_out_remote_sap; /* SAP of LT-CL-OUT-DEST */
+
+    UINT8                   llcp_co_in_local_sap;   /* SAP of IUT-CO-IN-DEST */
+    UINT8                   llcp_co_in_remote_sap;  /* SAP of LT-CO-IN-SRC   */
+    UINT8                   llcp_co_out_local_sap;  /* SAP of IUT-CO-OUT-SRC */
+    UINT8                   llcp_co_out_remote_sap; /* SAP of LT-CO-OUT-DEST */
+
+    UINT16                  llcp_co_out_remote_miu; /* MIU of LT-CO-OUT-DEST */
+    UINT8                   llcp_co_out_remote_rw;  /* RW of LT-CO-OUT-DEST  */
+
+#define NFA_DTA_LLCP_FLAGS_CO_OUT_CONNECTING    0x01    /* establishing outbound on connection-oriented */
+#define NFA_DTA_LLCP_FLAGS_CO_OUT_CONNECTED     0x02    /* established outbound on connection-oriented  */
+
+    UINT8                   llcp_flags;             /* internal flags for LLCP echo test */
+    UINT8                   llcp_sdp_tid;           /* transaction ID for SDP */
+
+    TIMER_LIST_ENT          llcp_cl_echo_timer;     /* timer for the connectionless echo test application      */
+    TIMER_LIST_ENT          llcp_co_echo_timer;     /* timer for the connection-oriented echo test application */
+    BUFFER_Q                llcp_cl_buffer;         /* buffer for the connectionless echo test application     */
+    BUFFER_Q                llcp_co_buffer;         /* buffer for the connection-oriented echo test application*/
+
+    tNFA_HANDLE             snep_server_handle;
+    tNFA_HANDLE             snep_server_conn_handle;
+    tNFA_HANDLE             snep_client_handle;
+
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_DEFAULT_SERVER    0x01
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_EXTENDED_SERVER   0x02
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_PUT_SHORT_NDEF    0x04
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_PUT_LONG_NDEF     0x08
+#define NFA_DTA_SNEP_CLIENT_TEST_FLAGS_GET               0x10
+
+    UINT8                   snep_client_test_flags;
+
+    UINT8                   *p_snep_short_ndef;
+    UINT32                  snep_short_ndef_size;
+    UINT8                   *p_snep_long_ndef;
+    UINT32                  snep_long_ndef_size;
+
+    /* DTA buffer for NDEF read/write */
+    tNFA_DTA_BUF_CB buf_cb[NFA_DTA_BUF_MAX];
+    UINT32              ndef_size;      /* Size of NDEF message from NDEF detection */
+
+    /* Scratch buffer for miscelaneous use */
+    UINT8               scratch_buf[NFA_DTA_SCRATCH_BUF_SIZE];
+
+    /* DTA Test command table */
+    tNFA_DTA_CMD_FCN    *p_cur_cmd_tbl; /* Current table of commands for current test */
+    UINT8               cur_cmd_idx;
+} tNFA_DTA_CB;
+extern tNFA_DTA_CB nfa_dta_cb;
+
+/* NFA_SYS info for DTA */
+extern const tNFA_SYS_REG nfa_dta_sys_reg;
+
+/* DTA startup setconfig parameters */
+extern UINT8 *p_nfa_dta_start_up_cfg;
+extern UINT8 nfa_dta_start_up_cfg_len;
+
+/*****************************************************************************
+* DTA internal funciton protoytpes
+*****************************************************************************/
+/* Internal function prototypes */
+void nfa_dta_deactivate (UINT8 deactivate_type);
+void nfa_dta_shutdown (void);
+void nfa_dta_discover_start (void);
+
+/* nfa_sys handler for DTA */
+BOOLEAN nfa_dta_evt_hdlr (BT_HDR *p_msg);
+void nfa_dta_sys_disable (void);
+
+/* State machine action functions */
+BOOLEAN nfa_dta_enable (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_disable (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_config (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_start (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_handle_deact (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_stop (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_run_test (tNFA_DTA_MSG *p_data);
+BOOLEAN nfa_dta_proc_data (tNFA_DTA_MSG *p_msg_data);
+
+/* Utility functions */
+void nfa_dta_test_set_state (tNFA_DTA_STATE state);
+void nfa_dta_test_set_substate (tNFA_DTA_SUBSTATE substate);
+void nfa_dta_free_ndef_buf (UINT8 ndef_idx);
+UINT8 *nfa_dta_realloc_buf (UINT8 ndef_idx, UINT32 size);
+void nfa_dta_t3t_nfcid_rand (UINT8 nfcid2[NCI_RF_F_UID_LEN]);
+
+/* Test function entry points (in nfa_dta_XXX.c) */
+void nfa_dta_nfcdep_poll_test_start (void);
+void nfa_dta_nfcdep_proc_data (tNFC_CONN_EVT event, tNFC_CONN *p_data);
+void nfa_dta_t1t_poll_test_start (void);
+void nfa_dta_t2t_poll_test_start (void);
+void nfa_dta_t3t_poll_test_start (void);
+void nfa_dta_t4t_poll_test_start (void);
+
+void nfa_dta_nfcdep_listen_test_start (void);
+void nfa_dta_t3t_listen_test_start (void);
+void nfa_dta_t4t_listen_test_start (void);
+
+void nfa_dta_t1t_rw_cback (UINT8 event, tRW_DATA *p_data);
+void nfa_dta_t2t_rw_cback (UINT8 event, tRW_DATA *p_data);
+void nfa_dta_t3t_rw_cback (UINT8 event, tRW_DATA *p_data);
+void nfa_dta_t4t_rw_cback (UINT8 event, tRW_DATA *p_data);
+
+void nfa_dta_t3t_ce_cback (UINT8 event, tCE_DATA *p_data);
+void nfa_dta_t4t_ce_cback (UINT8 event, tCE_DATA *p_data);
+
+void nfa_dta_ce_cback (UINT8 event, tCE_DATA *p_ce_data);
+
+void nfa_dta_t4t_register_apps (void);
+void nfa_dta_t4t_deregister_apps (void);
+
+void nfa_dta_llcp_register_echo (void);
+void nfa_dta_llcp_deregister_echo (void);
+void nfa_dta_llcp_activate_link (void);
+void nfa_dta_llcp_connect_co_echo_out (void);
+void nfa_dta_llcp_disconnect_co_echo_out (void);
+
+void nfa_dta_snep_register (void);
+void nfa_dta_snep_deregister (void);
+void nfa_dta_snep_mode (tNFA_DTA_SNEP_MODE mode);
+
+void nfa_dta_emvco_pcd_config_nfcc (BOOLEAN enable);
+void nfa_dta_emvco_pcd_start (void);
+void nfa_dta_emvco_pcd_cback (UINT8 event, tRW_DATA *p_data);
+
+extern UINT8 *p_nfa_dta_brcm_start_up_cfg;
+extern UINT8 nfa_dta_brcm_start_up_cfg_len;
+extern UINT8 *p_nfa_dta_start_up_vsc_cfg;
+
+#endif /* (NFA_DTA_INCLUDED == TRUE) */
+#endif /* NFA_DTA_INT_H */
+
diff --git a/src/nfa/int/nfa_ee_int.h b/src/nfa/int/nfa_ee_int.h
new file mode 100644
index 0000000..bdcd8c5
--- /dev/null
+++ b/src/nfa/int/nfa_ee_int.h
@@ -0,0 +1,456 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA EE.
+ *
+ ******************************************************************************/
+#ifndef NFA_EE_INT_H
+#define NFA_EE_INT_H
+#include "nfc_api.h"
+#include "nfa_ee_api.h"
+#include "nfa_sys.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_EE_DEBUG            BT_TRACE_VERBOSE
+#define NFA_EE_NUM_ECBS         (NFA_EE_MAX_EE_SUPPORTED+1) /* the number of tNFA_EE_ECBs (for NFCEEs and DH) */
+#define NFA_EE_CB_4_DH          NFA_EE_MAX_EE_SUPPORTED     /* The index for DH in nfa_ee_cb.ee_cb[] */
+#define NFA_EE_INVALID          0xFF
+#define NFA_EE_MAX_TECH_ROUTE   4 /* only A, B, F, Bprime are supported by UICC now */
+
+#ifndef NFA_EE_AID_CFG_TAG_NAME
+#define NFA_EE_AID_CFG_TAG_NAME         0x4F /* AID                             */
+#endif
+
+/* NFA EE events */
+enum
+{
+    NFA_EE_API_DISCOVER_EVT  = NFA_SYS_EVT_START(NFA_ID_EE),
+    NFA_EE_API_REGISTER_EVT,
+    NFA_EE_API_DEREGISTER_EVT,
+    NFA_EE_API_MODE_SET_EVT,
+    NFA_EE_API_SET_TECH_CFG_EVT,
+    NFA_EE_API_SET_PROTO_CFG_EVT,
+    NFA_EE_API_ADD_AID_EVT,
+    NFA_EE_API_REMOVE_AID_EVT,
+    NFA_EE_API_UPDATE_NOW_EVT,
+    NFA_EE_API_CONNECT_EVT,
+    NFA_EE_API_SEND_DATA_EVT,
+    NFA_EE_API_DISCONNECT_EVT,
+
+    NFA_EE_NCI_DISC_RSP_EVT,
+    NFA_EE_NCI_DISC_NTF_EVT,
+    NFA_EE_NCI_MODE_SET_RSP_EVT,
+    NFA_EE_NCI_CONN_EVT,
+    NFA_EE_NCI_DATA_EVT,
+    NFA_EE_NCI_ACTION_NTF_EVT,
+    NFA_EE_NCI_DISC_REQ_NTF_EVT,
+
+    NFA_EE_ROUT_TIMEOUT_EVT,
+    NFA_EE_DISCV_TIMEOUT_EVT,
+    NFA_EE_CFG_TO_NFCC_EVT,
+    NFA_EE_MAX_EVT
+
+};
+
+
+typedef UINT16 tNFA_EE_INT_EVT;
+#define NFA_EE_AE_ROUTE             0x80        /* for listen mode routing table*/
+#define NFA_EE_AE_VS                0x40
+
+
+/* NFA EE Management state */
+enum
+{
+    NFA_EE_EM_STATE_INIT = 0,
+    NFA_EE_EM_STATE_INIT_DONE,
+    NFA_EE_EM_STATE_RESTORING,
+    NFA_EE_EM_STATE_DISABLING,
+    NFA_EE_EM_STATE_DISABLED,
+
+    NFA_EE_EM_STATE_MAX
+};
+typedef UINT8 tNFA_EE_EM_STATE;
+
+/* NFA EE connection status */
+enum
+{
+    NFA_EE_CONN_ST_NONE,    /* not connected */
+    NFA_EE_CONN_ST_WAIT,    /* connection is initiated; waiting for ack */
+    NFA_EE_CONN_ST_CONN,    /* connected; can send/receive data */
+    NFA_EE_CONN_ST_DISC,    /* disconnecting; waiting for ack */
+    NFA_EE_CONN_ST_MAX
+};
+typedef UINT8 tNFA_EE_CONN_ST;
+
+#define NFA_EE_MAX_AID_CFG_LEN  (510)
+#define NFA_EE_7816_STATUS_LEN  (2)
+
+/* NFA EE control block flags:
+ * use to indicate an API function has changed the configuration of the associated NFCEE
+ * The flags are cleared when the routing table/VS is updated */
+#define NFA_EE_ECB_FLAGS_TECH       0x02      /* technology routing changed         */
+#define NFA_EE_ECB_FLAGS_PROTO      0x04      /* protocol routing changed           */
+#define NFA_EE_ECB_FLAGS_AID        0x08      /* AID routing changed                */
+#define NFA_EE_ECB_FLAGS_VS         0x10      /* VS changed                         */
+#define NFA_EE_ECB_FLAGS_RESTORE    0x20      /* Restore related                    */
+#define NFA_EE_ECB_FLAGS_ROUTING    0x0E      /* routing flags changed              */
+#define NFA_EE_ECB_FLAGS_DISC_REQ   0x40      /* NFCEE Discover Request NTF is set  */
+#define NFA_EE_ECB_FLAGS_ORDER      0x80      /* DISC_REQ N reported before DISC N  */
+typedef UINT8 tNFA_EE_ECB_FLAGS;
+
+/* part of tNFA_EE_STATUS; for internal use only  */
+#define NFA_EE_STATUS_RESTORING 0x20      /* waiting for restore to full power mode to complete */
+#define NFA_EE_STATUS_INT_MASK  0x20      /* this bit is in ee_status for internal use only */
+
+/* NFA-EE information for a particular NFCEE Entity (including DH) */
+typedef struct
+{
+    tNFA_TECHNOLOGY_MASK    tech_switch_on;     /* default routing - technologies switch_on  */
+    tNFA_TECHNOLOGY_MASK    tech_switch_off;    /* default routing - technologies switch_off */
+    tNFA_TECHNOLOGY_MASK    tech_battery_off;   /* default routing - technologies battery_off*/
+    tNFA_PROTOCOL_MASK      proto_switch_on;    /* default routing - protocols switch_on     */
+    tNFA_PROTOCOL_MASK      proto_switch_off;   /* default routing - protocols switch_off    */
+    tNFA_PROTOCOL_MASK      proto_battery_off;  /* default routing - protocols battery_off   */
+    tNFA_EE_CONN_ST         conn_st;            /* connection status */
+    UINT8                   conn_id;            /* connection id */
+    tNFA_EE_CBACK           *p_ee_cback;        /* the callback function */
+
+    /* Each AID entry has an ssociated aid_len, aid_pwr_cfg, aid_rt_info.
+     * aid_cfg[] contains AID and maybe some other VS information in TLV format
+     * The first T is always NFA_EE_AID_CFG_TAG_NAME, the L is the actual AID length
+     * the aid_len is the total length of all the TLVs associated with this AID entry
+     */
+    UINT8                   aid_len[NFA_EE_MAX_AID_ENTRIES];/* the actual lengths in aid_cfg */
+    UINT8                   aid_pwr_cfg[NFA_EE_MAX_AID_ENTRIES];/* power configuration of this AID entry */
+    UINT8                   aid_rt_info[NFA_EE_MAX_AID_ENTRIES];/* route/vs info for this AID entry */
+    UINT8                   aid_cfg[NFA_EE_MAX_AID_CFG_LEN];/* routing entries based on AID */
+    UINT8                   aid_entries;        /* The number of AID entries in aid_cfg */
+    UINT8                   nfcee_id;           /* ID for this NFCEE */
+    UINT8                   ee_status;          /* The NFCEE status */
+    UINT8                   ee_old_status;      /* The NFCEE status before going to low power mode */
+    tNFA_EE_INTERFACE       ee_interface[NFC_MAX_EE_INTERFACE];/* NFCEE supported interface */
+    tNFA_EE_TLV             ee_tlv[NFC_MAX_EE_TLVS];/* the TLV */
+    UINT8                   num_interface;      /* number of Target interface */
+    UINT8                   num_tlvs;           /* number of TLVs */
+    tNFA_EE_ECB_FLAGS       ecb_flags;          /* the flags of this control block */
+    tNFA_EE_INTERFACE       use_interface;      /* NFCEE interface used for the connection */
+    tNFA_NFC_PROTOCOL       la_protocol;        /* Listen A protocol    */
+    tNFA_NFC_PROTOCOL       lb_protocol;        /* Listen B protocol    */
+    tNFA_NFC_PROTOCOL       lf_protocol;        /* Listen F protocol    */
+    tNFA_NFC_PROTOCOL       lbp_protocol;       /* Listen B' protocol   */
+} tNFA_EE_ECB;
+
+/* data type for NFA_EE_API_DISCOVER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_CBACK       *p_cback;
+} tNFA_EE_API_DISCOVER;
+
+/* data type for NFA_EE_API_REGISTER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_CBACK       *p_cback;
+} tNFA_EE_API_REGISTER;
+
+/* data type for NFA_EE_API_DEREGISTER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    int                 index;
+} tNFA_EE_API_DEREGISTER;
+
+/* data type for NFA_EE_API_MODE_SET_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+    UINT8               mode;
+} tNFA_EE_API_MODE_SET;
+
+/* data type for NFA_EE_API_SET_TECH_CFG_EVT */
+typedef struct
+{
+    BT_HDR                  hdr;
+    tNFA_EE_ECB            *p_cb;
+    UINT8                   nfcee_id;
+    tNFA_TECHNOLOGY_MASK    technologies_switch_on;
+    tNFA_TECHNOLOGY_MASK    technologies_switch_off;
+    tNFA_TECHNOLOGY_MASK    technologies_battery_off;
+} tNFA_EE_API_SET_TECH_CFG;
+
+/* data type for NFA_EE_API_SET_PROTO_CFG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+    tNFA_PROTOCOL_MASK  protocols_switch_on;
+    tNFA_PROTOCOL_MASK  protocols_switch_off;
+    tNFA_PROTOCOL_MASK  protocols_battery_off;
+} tNFA_EE_API_SET_PROTO_CFG;
+
+/* data type for NFA_EE_API_ADD_AID_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+    UINT8               aid_len;
+    UINT8               *p_aid;
+    tNFA_EE_PWR_STATE   power_state;
+} tNFA_EE_API_ADD_AID;
+
+/* data type for NFA_EE_API_REMOVE_AID_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               aid_len;
+    UINT8               *p_aid;
+} tNFA_EE_API_REMOVE_AID;
+
+/* data type for NFA_EE_API_CONNECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+    UINT8               ee_interface;
+    tNFA_EE_CBACK       *p_cback;
+} tNFA_EE_API_CONNECT;
+
+/* data type for NFA_EE_API_SEND_DATA_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+    UINT16              data_len;
+    UINT8               *p_data;
+} tNFA_EE_API_SEND_DATA;
+
+/* data type for NFA_EE_API_DISCONNECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+} tNFA_EE_API_DISCONNECT;
+
+
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFC_STATUS         status;                 /* The event status. */
+} tNFA_EE_MSG_STATUS;
+
+/* common data type for internal events with nfa_ee_use_cfg_cb[] as TRUE */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_EE_ECB        *p_cb;
+    UINT8               nfcee_id;
+} tNFA_EE_CFG_HDR;
+
+/* data type for tNFC_RESPONSE_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    void                        *p_data;
+} tNFA_EE_NCI_RESPONSE;
+
+/* data type for NFA_EE_NCI_DISC_RSP_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    tNFC_NFCEE_DISCOVER_REVT    *p_data;
+} tNFA_EE_NCI_DISC_RSP;
+
+/* data type for NFA_EE_NCI_DISC_NTF_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    tNFC_NFCEE_INFO_REVT        *p_data;
+} tNFA_EE_NCI_DISC_NTF;
+
+/* data type for NFA_EE_NCI_MODE_SET_RSP_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    tNFC_NFCEE_MODE_SET_REVT    *p_data;
+} tNFA_EE_NCI_MODE_SET;
+
+/* data type for NFA_EE_NCI_CONN_EVT and NFA_EE_NCI_DATA_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    UINT8                       conn_id;
+    tNFC_CONN_EVT               event;
+    tNFC_CONN                   *p_data;
+} tNFA_EE_NCI_CONN;
+
+/* data type for NFA_EE_NCI_ACTION_NTF_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    tNFC_EE_ACTION_REVT         *p_data;
+} tNFA_EE_NCI_ACTION;
+
+/* data type for NFA_EE_NCI_DISC_REQ_NTF_EVT */
+typedef struct
+{
+    BT_HDR                      hdr;
+    tNFC_EE_DISCOVER_REQ_REVT   *p_data;
+} tNFA_EE_NCI_DISC_REQ;
+
+/* union of all event data types */
+typedef union
+{
+    BT_HDR                      hdr;
+    tNFA_EE_CFG_HDR             cfg_hdr;
+    tNFA_EE_API_DISCOVER        ee_discover;
+    tNFA_EE_API_REGISTER        ee_register;
+    tNFA_EE_API_DEREGISTER      deregister;
+    tNFA_EE_API_MODE_SET        mode_set;
+    tNFA_EE_API_SET_TECH_CFG    set_tech;
+    tNFA_EE_API_SET_PROTO_CFG   set_proto;
+    tNFA_EE_API_ADD_AID         add_aid;
+    tNFA_EE_API_REMOVE_AID      rm_aid;
+    tNFA_EE_API_CONNECT         connect;
+    tNFA_EE_API_SEND_DATA       send_data;
+    tNFA_EE_API_DISCONNECT      disconnect;
+    tNFA_EE_NCI_DISC_RSP        disc_rsp;
+    tNFA_EE_NCI_DISC_NTF        disc_ntf;
+    tNFA_EE_NCI_MODE_SET        mode_set_rsp;
+    tNFA_EE_NCI_CONN            conn;
+    tNFA_EE_NCI_ACTION          act;
+    tNFA_EE_NCI_DISC_REQ        disc_req;
+} tNFA_EE_MSG;
+
+/* type for State Machine (SM) action functions */
+typedef void (*tNFA_EE_SM_ACT)(tNFA_EE_MSG *p_data);
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+#define NFA_EE_CFGED_UPDATE_NOW         0x80
+#define NFA_EE_CFGED_OFF_ROUTING        0x40    /* either switch off or battery off is configured */
+
+/* the following status are the definition used in ee_cfg_sts */
+#define NFA_EE_STS_CHANGED_ROUTING      0x01
+#define NFA_EE_STS_CHANGED_VS           0x02
+#define NFA_EE_STS_CHANGED              0x0f
+#define NFA_EE_STS_PREV                 0xf0
+#define NFA_EE_STS_PREV_ROUTING         0x10
+
+#define NFA_EE_FLAG_WAIT_HCI            0x01    /* set this bit when waiting for HCI to finish the initialization process in NFA_EE_EM_STATE_RESTORING */
+#define NFA_EE_FLAG_NOTIFY_HCI          0x02    /* set this bit when EE needs to notify the p_enable_cback at the end of NFCEE discover process in NFA_EE_EM_STATE_RESTORING */
+typedef UINT8 tNFA_EE_FLAGS;
+
+typedef void (tNFA_EE_ENABLE_DONE_CBACK)(BOOLEAN disable_discover);
+
+/* NFA EE Management control block */
+typedef struct
+{
+    tNFA_EE_ECB          ecb[NFA_EE_NUM_ECBS];   /* control block for DH and NFCEEs  */
+    TIMER_LIST_ENT       timer;                  /* timer to send info to NFCC       */
+    TIMER_LIST_ENT       discv_timer;            /* timer to end NFCEE discovery     */
+    tNFA_EE_CBACK        *p_ee_cback[NFA_EE_MAX_CBACKS];/* to report EE events       */
+    tNFA_EE_CBACK        *p_ee_disc_cback;       /* to report EE discovery result    */
+    tNFA_EE_ENABLE_DONE_CBACK *p_enable_cback;   /* callback to notify on enable done*/
+    tNFA_EE_EM_STATE     em_state;               /* NFA-EE state initialized or not  */
+    UINT8                num_ee_expecting;       /* number of ee_info still expecting*/
+    UINT8                cur_ee;                 /* the number of ee_info in cb      */
+    UINT8                ee_cfged;               /* the bit mask of configured ECBs  */
+    UINT8                ee_cfg_sts;             /* configuration status             */
+    tNFA_EE_FLAGS        ee_flags;               /* flags                           */
+} tNFA_EE_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA EE control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_EE_CB nfa_ee_cb;
+#else
+extern tNFA_EE_CB *nfa_ee_cb_ptr;
+#define nfa_ee_cb (*nfa_ee_cb_ptr)
+#endif
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/* function prototypes - exported from nfa_ee_main.c */
+void nfa_ee_sys_enable (void);
+void nfa_ee_sys_disable (void);
+
+/* event handler function type */
+BOOLEAN nfa_ee_evt_hdlr (BT_HDR *p_msg);
+void nfa_ee_proc_nfcc_power_mode (UINT8 nfcc_power_mode);
+#if (NFC_NFCEE_INCLUDED == TRUE)
+void nfa_ee_get_tech_route (UINT8 power_state, UINT8 *p_handles);
+#endif
+void nfa_ee_proc_evt(tNFC_RESPONSE_EVT event, void *p_data);
+tNFA_EE_ECB * nfa_ee_find_ecb (UINT8 nfcee_id);
+tNFA_EE_ECB * nfa_ee_find_ecb_by_conn_id (UINT8 conn_id);
+UINT8 nfa_ee_ecb_to_mask (tNFA_EE_ECB *p_cb);
+void nfa_ee_restore_one_ecb (tNFA_EE_ECB *p_cb);
+BOOLEAN nfa_ee_is_active (tNFA_HANDLE nfcee_id);
+
+/* Action function prototypes - nfa_ee_act.c */
+void nfa_ee_api_discover(tNFA_EE_MSG *p_data);
+void nfa_ee_api_register(tNFA_EE_MSG *p_data);
+void nfa_ee_api_deregister(tNFA_EE_MSG *p_data);
+void nfa_ee_api_mode_set(tNFA_EE_MSG *p_data);
+void nfa_ee_api_set_tech_cfg(tNFA_EE_MSG *p_data);
+void nfa_ee_api_set_proto_cfg(tNFA_EE_MSG *p_data);
+void nfa_ee_api_add_aid(tNFA_EE_MSG *p_data);
+void nfa_ee_api_remove_aid(tNFA_EE_MSG *p_data);
+void nfa_ee_api_update_now(tNFA_EE_MSG *p_data);
+void nfa_ee_api_connect(tNFA_EE_MSG *p_data);
+void nfa_ee_api_send_data(tNFA_EE_MSG *p_data);
+void nfa_ee_api_disconnect(tNFA_EE_MSG *p_data);
+void nfa_ee_report_disc_done(BOOLEAN notify_sys);
+void nfa_ee_nci_disc_rsp(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_disc_ntf(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_mode_set_rsp(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_conn(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_action_ntf(tNFA_EE_MSG *p_data);
+void nfa_ee_nci_disc_req_ntf(tNFA_EE_MSG *p_data);
+void nfa_ee_rout_timeout(tNFA_EE_MSG *p_data);
+void nfa_ee_discv_timeout(tNFA_EE_MSG *p_data);
+void nfa_ee_lmrt_to_nfcc(tNFA_EE_MSG *p_data);
+void nfa_ee_update_rout(void);
+void nfa_ee_report_event(tNFA_EE_CBACK *p_cback, tNFA_EE_EVT event, tNFA_EE_CBACK_DATA *p_data);
+tNFA_EE_ECB * nfa_ee_find_aid_offset(UINT8 aid_len, UINT8 *p_aid, int *p_offset, int *p_entry);
+void nfa_ee_remove_labels(void);
+int nfa_ee_find_total_aid_len(tNFA_EE_ECB *p_cb, int start_entry);
+void nfa_ee_start_timer(void);
+void nfa_ee_reg_cback_enable_done (tNFA_EE_ENABLE_DONE_CBACK *p_cback);
+
+extern void nfa_ee_proc_hci_info_cback (void);
+
+
+#endif /* NFA_P2P_INT_H */
diff --git a/src/nfa/int/nfa_hci_int.h b/src/nfa/int/nfa_hci_int.h
new file mode 100644
index 0000000..a1763ac
--- /dev/null
+++ b/src/nfa/int/nfa_hci_int.h
@@ -0,0 +1,513 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA HCI.
+ *
+ ******************************************************************************/
+#ifndef NFA_HCI_INT_H
+#define NFA_HCI_INT_H
+
+#include "nfa_hci_api.h"
+
+extern BOOLEAN HCI_LOOPBACK_DEBUG;
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+
+#define NFA_HCI_HOST_ID_UICC0           0x02
+#define NFA_HCI_HOST_ID_UICC1           0x03
+#define NFA_HCI_LAST_HOST_SPECIFIC_GATE 0xEF
+
+#define NFA_HCI_SESSION_ID_LEN          8           /* HCI Session ID length */
+#define NFA_MAX_PIPES_IN_GENERIC_GATE   0x0F        /* Maximum pipes that can be created on a generic pipe  */
+
+#define NFA_HCI_VERSION_SW              0x090000    /* HCI SW Version number                       */
+#define NFA_HCI_VERSION_HW              0x000000    /* HCI HW Version number                       */
+#define NFA_HCI_VENDOR_NAME             "HCI"       /* Vendor Name                                 */
+#define NFA_HCI_MODEL_ID                00          /* Model ID                                    */
+#define NFA_HCI_VERSION                 90          /* HCI Version                                 */
+
+/* NFA HCI states */
+#define NFA_HCI_STATE_DISABLED          0x00     /* HCI is disabled  */
+#define NFA_HCI_STATE_STARTUP           0x01     /* HCI performing Initialization sequence */
+#define NFA_HCI_STATE_WAIT_NETWK_ENABLE 0x02     /* HCI is waiting for initialization of other host in the network */
+#define NFA_HCI_STATE_IDLE              0x03     /* HCI is waiting to handle api commands  */
+#define NFA_HCI_STATE_WAIT_RSP          0x04     /* HCI is performing api command request  */
+#define NFA_HCI_STATE_REMOVE_GATE       0x05     /* Removing all pipes prior to removing the gate */
+#define NFA_HCI_STATE_APP_DEREGISTER    0x06     /* Removing all pipes and gates prior to deregistering the app */
+#define NFA_HCI_STATE_RESTORE           0x07     /* HCI restore */
+
+typedef UINT8 tNFA_HCI_STATE;
+
+/* NFA HCI PIPE states */
+#define NFA_HCI_PIPE_CLOSED             0x00     /* Pipe is closed */
+#define NFA_HCI_PIPE_OPENED             0x01     /* Pipe is opened */
+
+#define NFA_HCI_INVALID_INX             0xFF
+
+
+typedef UINT8 tNFA_HCI_COMMAND;
+typedef UINT8 tNFA_HCI_RESPONSE;
+
+
+/* NFA HCI Internal events */
+enum
+{
+    NFA_HCI_API_REGISTER_APP_EVT = NFA_SYS_EVT_START (NFA_ID_HCI),/* Register APP with HCI */
+    NFA_HCI_API_DEREGISTER_APP_EVT,                               /* Deregister an app from HCI */
+    NFA_HCI_API_GET_APP_GATE_PIPE_EVT,                            /* Get the list of gate and pipe associated to the application */
+    NFA_HCI_API_ALLOC_GATE_EVT,                                   /* Allocate a dyanmic gate for the application */
+    NFA_HCI_API_DEALLOC_GATE_EVT,                                 /* Deallocate a previously allocated gate to the application */
+    NFA_HCI_API_GET_HOST_LIST_EVT,                                /* Get the list of Host in the network */
+    NFA_HCI_API_GET_REGISTRY_EVT,                                 /* Get a registry entry from a host */
+    NFA_HCI_API_SET_REGISTRY_EVT,                                 /* Set a registry entry on a host */
+    NFA_HCI_API_CREATE_PIPE_EVT,                                  /* Create a pipe between two gates */
+    NFA_HCI_API_OPEN_PIPE_EVT,                                    /* Open a pipe */
+    NFA_HCI_API_CLOSE_PIPE_EVT,                                   /* Close a pipe */
+    NFA_HCI_API_DELETE_PIPE_EVT,                                  /* Delete a pipe */
+    NFA_HCI_API_ADD_STATIC_PIPE_EVT,                              /* Add a static pipe */
+    NFA_HCI_API_SEND_CMD_EVT,                                     /* Send command via pipe */
+    NFA_HCI_API_SEND_RSP_EVT,                                     /* Application Response to a command */
+    NFA_HCI_API_SEND_EVENT_EVT,                                   /* Send event via pipe */
+
+    NFA_HCI_RSP_NV_READ_EVT,                                      /* Non volatile read complete event */
+    NFA_HCI_RSP_NV_WRITE_EVT,                                     /* Non volatile write complete event */
+    NFA_HCI_RSP_TIMEOUT_EVT,
+    NFA_HCI_CHECK_QUEUE_EVT
+};
+
+#define NFA_HCI_FIRST_API_EVENT     NFA_HCI_API_REGISTER_APP_EVT
+#define NFA_HCI_LAST_API_EVENT      NFA_HCI_API_SEND_EVENT_EVT
+
+typedef UINT16 tNFA_HCI_INT_EVT;
+
+/* Internal event structures.
+**
+** Note, every internal structure starts with a BT_HDR and an app handle
+*/
+
+/* data type for NFA_HCI_API_REGISTER_APP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    char                app_name[NFA_MAX_HCI_APP_NAME_LEN + 1];
+    tNFA_HCI_CBACK      *p_cback;
+    BOOLEAN             b_send_conn_evts;
+} tNFA_HCI_API_REGISTER_APP;
+
+/* data type for NFA_HCI_API_DEREGISTER_APP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    char                app_name[NFA_MAX_HCI_APP_NAME_LEN + 1];
+} tNFA_HCI_API_DEREGISTER_APP;
+
+/* data type for NFA_HCI_API_GET_APP_GATE_PIPE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+} tNFA_HCI_API_GET_APP_GATE_PIPE;
+
+/* data type for NFA_HCI_API_ALLOC_GATE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+} tNFA_HCI_API_ALLOC_GATE;
+
+
+/* data type for NFA_HCI_API_DEALLOC_GATE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    UINT8               gate;
+} tNFA_HCI_API_DEALLOC_GATE;
+
+/* data type for NFA_HCI_API_GET_HOST_LIST_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    tNFA_STATUS         status;
+} tNFA_HCI_API_GET_HOST_LIST;
+
+/* data type for NFA_HCI_API_GET_REGISTRY_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    UINT8               pipe;
+    UINT8               reg_inx;
+} tNFA_HCI_API_GET_REGISTRY;
+
+/* data type for NFA_HCI_API_SET_REGISTRY_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    UINT8               pipe;
+    UINT8               reg_inx;
+    UINT8               size;
+    UINT8               data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_API_SET_REGISTRY;
+
+/* data type for NFA_HCI_API_CREATE_PIPE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    tNFA_STATUS         status;
+    UINT8               source_gate;
+    UINT8               dest_host;
+    UINT8               dest_gate;
+} tNFA_HCI_API_CREATE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_OPEN_PIPE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    tNFA_STATUS         status;
+    UINT8               pipe;
+} tNFA_HCI_API_OPEN_PIPE_EVT;
+
+/* data type for NFA_HCI_API_CLOSE_PIPE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    tNFA_STATUS         status;
+    UINT8               pipe;
+} tNFA_HCI_API_CLOSE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_DELETE_PIPE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    tNFA_STATUS         status;
+    UINT8               pipe;
+} tNFA_HCI_API_DELETE_PIPE_EVT;
+
+/* data type for NFA_HCI_API_ADD_STATIC_PIPE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    tNFA_STATUS         status;
+    UINT8               host;
+    UINT8               gate;
+    UINT8               pipe;
+} tNFA_HCI_API_ADD_STATIC_PIPE_EVT;
+
+/* data type for NFA_HCI_API_SEND_EVENT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    UINT8               pipe;
+    UINT8               evt_code;
+    UINT16              evt_len;
+    UINT8               *p_evt_buf;
+    UINT16              rsp_len;
+    UINT8               *p_rsp_buf;
+    UINT16              rsp_timeout;
+} tNFA_HCI_API_SEND_EVENT_EVT;
+
+/* data type for NFA_HCI_API_SEND_CMD_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    UINT8               pipe;
+    UINT8               cmd_code;
+    UINT16              cmd_len;
+    UINT8               data[NFA_MAX_HCI_CMD_LEN];
+} tNFA_HCI_API_SEND_CMD_EVT;
+
+/* data type for NFA_HCI_RSP_NV_READ_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               block;
+    UINT16              size;
+    tNFA_STATUS         status;
+} tNFA_HCI_RSP_NV_READ_EVT;
+
+/* data type for NFA_HCI_RSP_NV_WRITE_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_STATUS         status;
+} tNFA_HCI_RSP_NV_WRITE_EVT;
+
+/* data type for NFA_HCI_API_SEND_RSP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+    UINT8               pipe;
+    UINT8               response;
+    UINT8               size;
+    UINT8               data[NFA_MAX_HCI_RSP_LEN];
+} tNFA_HCI_API_SEND_RSP_EVT;
+
+/* common data type for internal events */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         hci_handle;
+} tNFA_HCI_COMM_DATA;
+
+/* union of all event data types */
+typedef union
+{
+    BT_HDR                              hdr;
+    tNFA_HCI_COMM_DATA                  comm;
+
+    /* API events */
+    tNFA_HCI_API_REGISTER_APP           app_info;                       /* Register/Deregister an application */
+    tNFA_HCI_API_GET_APP_GATE_PIPE      get_gate_pipe_list;             /* Get the list of gates and pipes created for the application */
+    tNFA_HCI_API_ALLOC_GATE             gate_info;                      /* Allocate a dynamic gate to the application */
+    tNFA_HCI_API_DEALLOC_GATE           gate_dealloc;                   /* Deallocate the gate allocated to the application */
+    tNFA_HCI_API_CREATE_PIPE_EVT        create_pipe;                    /* Create a pipe */
+    tNFA_HCI_API_OPEN_PIPE_EVT          open_pipe;                      /* Open a pipe */
+    tNFA_HCI_API_CLOSE_PIPE_EVT         close_pipe;                     /* Close a pipe */
+    tNFA_HCI_API_DELETE_PIPE_EVT        delete_pipe;                    /* Delete a pipe */
+    tNFA_HCI_API_ADD_STATIC_PIPE_EVT    add_static_pipe;                /* Add a static pipe */
+    tNFA_HCI_API_GET_HOST_LIST          get_host_list;                  /* Get the list of Host in the network */
+    tNFA_HCI_API_GET_REGISTRY           get_registry;                   /* Get a registry entry on a host */
+    tNFA_HCI_API_SET_REGISTRY           set_registry;                   /* Set a registry entry on a host */
+    tNFA_HCI_API_SEND_CMD_EVT           send_cmd;                       /* Send a event on a pipe to a host */
+    tNFA_HCI_API_SEND_RSP_EVT           send_rsp;                       /* Response to a command sent on a pipe to a host */
+    tNFA_HCI_API_SEND_EVENT_EVT         send_evt;                       /* Send a command on a pipe to a host */
+
+    /* Internal events */
+    tNFA_HCI_RSP_NV_READ_EVT            nv_read;
+    tNFA_HCI_RSP_NV_WRITE_EVT           nv_write;
+} tNFA_HCI_EVENT_DATA;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+
+/* Dynamic pipe control block */
+typedef struct
+{
+    UINT8                   pipe_id;                /* Pipe ID */
+    tNFA_HCI_PIPE_STATE     pipe_state;             /* State of the Pipe */
+    UINT8                   local_gate;             /* local gate id */
+    UINT8                   dest_host;              /* Peer host to which this pipe is connected */
+    UINT8                   dest_gate;              /* Peer gate to which this pipe is connected */
+} tNFA_HCI_DYN_PIPE;
+
+/* Dynamic gate control block */
+typedef struct
+{
+    UINT8                   gate_id;                /* local gate id */
+    tNFA_HANDLE             gate_owner;             /* NFA-HCI handle assigned to the application which owns the gate */
+    UINT32                  pipe_inx_mask;          /* Bit 0 == pipe inx 0, etc */
+} tNFA_HCI_DYN_GATE;
+
+/* Admin gate control block */
+typedef struct
+{
+    tNFA_HCI_PIPE_STATE pipe01_state;                       /* State of Pipe '01' */
+    UINT8               session_id[NFA_HCI_SESSION_ID_LEN]; /* Session ID of the host network */
+} tNFA_ADMIN_GATE_INFO;
+
+/* Link management gate control block */
+typedef struct
+{
+    tNFA_HCI_PIPE_STATE pipe00_state;               /* State of Pipe '00' */
+    UINT16              rec_errors;                 /* Receive errors */
+} tNFA_LINK_MGMT_GATE_INFO;
+
+/* Identity management gate control block */
+typedef struct
+{
+    UINT32              pipe_inx_mask;                  /* Bit 0 == pipe inx 0, etc */
+    UINT16              version_sw;                     /* Software version number */
+    UINT16              version_hw;                     /* Hardware version number */
+    UINT8               vendor_name[20];                /* Vendor name */
+    UINT8               model_id;                       /* Model ID */
+    UINT8               hci_version;                    /* HCI Version */
+} tNFA_ID_MGMT_GATE_INFO;
+
+/* Internal flags */
+#define NFA_HCI_FL_DISABLING        0x01                /* sub system is being disabled */
+#define NFA_HCI_FL_NV_CHANGED       0x02                /* NV Ram changed */
+
+
+/* NFA HCI control block */
+typedef struct
+{
+    tNFA_HCI_STATE                  hci_state;                          /* state of the HCI */
+    UINT8                           num_nfcee;
+    UINT8                           inactive_host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* Inactive host in the host network */
+    UINT8                           reset_host[NFA_HCI_MAX_HOST_IN_NETWORK]; /* List of host reseting */
+    BOOLEAN                         b_low_power_mode;                   /* Host controller in low power mode */
+    BOOLEAN                         b_hci_netwk_reset;                  /* Command sent to reset HCI Network */
+    BOOLEAN                         w4_hci_netwk_init;                  /* Wait for other host in network to initialize */
+    TIMER_LIST_ENT                  timer;                              /* Timer to avoid indefinitely waiting for response */
+    UINT8                           conn_id;                            /* Connection ID */
+    UINT8                           buff_size;                          /* Connection buffer size */
+    BOOLEAN                         nv_read_cmplt;                      /* NV Read completed */
+    BOOLEAN                         nv_write_needed;                    /* Something changed - NV write is needed */
+    BOOLEAN                         assembling;                         /* Set true if in process of assembling a message  */
+    BOOLEAN                         assembly_failed;                    /* Set true if Insufficient buffer to Reassemble incoming message */
+    BOOLEAN                         w4_rsp_evt;                         /* Application command sent on HCP Event */
+    tNFA_HANDLE                     app_in_use;                         /* Index of the application that is waiting for response */
+    UINT8                           local_gate_in_use;                  /* Local gate currently working with */
+    UINT8                           remote_gate_in_use;                 /* Remote gate currently working with */
+    UINT8                           remote_host_in_use;                 /* The remote host to which a command is sent */
+    UINT8                           pipe_in_use;                        /* The pipe currently working with */
+    UINT8                           param_in_use;                       /* The registry parameter currently working with */
+    tNFA_HCI_COMMAND                cmd_sent;                           /* The last command sent */
+    BOOLEAN                         ee_disc_cmplt;                      /* EE Discovery operation completed */
+    UINT16                          msg_len;                            /* For segmentation - length of the combined message */
+    UINT16                          max_msg_len;                        /* Maximum reassembled message size */
+    UINT8                           msg_data[NFA_MAX_HCI_EVENT_LEN];    /* For segmentation - the combined message data */
+    UINT8                           *p_msg_data;                        /* For segmentation - reassembled message */
+    UINT8                           type;                               /* Instruction type of incoming message */
+    UINT8                           inst;                               /* Instruction of incoming message */
+
+    BUFFER_Q                        hci_api_q;                          /* Buffer Q to hold incoming API commands */
+    BUFFER_Q                        hci_host_reset_api_q;               /* Buffer Q to hold incoming API commands to a host that is reactivating */
+    tNFA_HCI_CBACK                  *p_app_cback[NFA_HCI_MAX_APP_CB];   /* Callback functions registered by the applications */
+    UINT16                          rsp_buf_size;                       /* Maximum size of APDU buffer */
+    UINT8                           *p_rsp_buf;                         /* Buffer to hold response to sent event */
+    struct
+    {
+        char                        reg_app_names[NFA_HCI_MAX_APP_CB][NFA_MAX_HCI_APP_NAME_LEN + 1];
+
+        tNFA_HCI_DYN_GATE           dyn_gates[NFA_HCI_MAX_GATE_CB];
+        tNFA_HCI_DYN_PIPE           dyn_pipes[NFA_HCI_MAX_PIPE_CB];
+
+        BOOLEAN                     b_send_conn_evts[NFA_HCI_MAX_APP_CB];
+        tNFA_ADMIN_GATE_INFO        admin_gate;
+        tNFA_LINK_MGMT_GATE_INFO    link_mgmt_gate;
+        tNFA_ID_MGMT_GATE_INFO      id_mgmt_gate;
+    } cfg;
+
+} tNFA_HCI_CB;
+
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA HCI control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_HCI_CB nfa_hci_cb;
+#else
+extern tNFA_HCI_CB *nfa_hci_cb_ptr;
+#define nfa_hci_cb (*nfa_hci_cb_ptr)
+#endif
+
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+
+/* Functions in nfa_hci_main.c
+*/
+extern void nfa_hci_init (void);
+extern void nfa_hci_proc_nfcc_power_mode (UINT8 nfcc_power_mode);
+extern void nfa_hci_dh_startup_complete (void);
+extern void nfa_hci_startup_complete (tNFA_STATUS status);
+extern void nfa_hci_startup (void);
+extern void nfa_hci_restore_default_config (UINT8 *p_session_id);
+extern void nfa_hci_vsc_cback (tNFC_VS_EVT event, UINT16 data_len, UINT8 *p_data);
+
+/* Action functions in nfa_hci_act.c
+*/
+extern void nfa_hci_check_pending_api_requests (void);
+extern void nfa_hci_check_api_requests (void);
+extern void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data);
+extern void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len);
+extern void nfa_hci_handle_admin_gate_evt (UINT8 *p_data);
+extern void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data);
+extern void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe, UINT8  *p_data, UINT16 data_len);
+extern void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe);
+extern void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data);
+extern void nfa_hci_api_deregister (tNFA_HCI_EVENT_DATA *p_evt_data);
+
+/* Utility functions in nfa_hci_utils.c
+*/
+extern tNFA_HCI_DYN_GATE  *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_GATE  *nfa_hciu_find_gate_by_gid (UINT8 gate_id);
+extern tNFA_HCI_DYN_GATE  *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_GATE  *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE  *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id);
+extern tNFA_HCI_DYN_PIPE  *nfa_hciu_find_pipe_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE  *nfa_hciu_find_active_pipe_by_owner (tNFA_HANDLE app_handle);
+extern tNFA_HCI_DYN_PIPE  *nfa_hciu_find_pipe_on_gate (UINT8 gate_id);
+extern tNFA_HANDLE         nfa_hciu_get_gate_owner (UINT8 gate_id);
+extern BOOLEAN             nfa_hciu_is_active_host (UINT8 host_id);
+extern BOOLEAN             nfa_hciu_is_host_reseting (UINT8 host_id);
+extern BOOLEAN             nfa_hciu_is_no_host_resetting (void);
+extern tNFA_HCI_DYN_PIPE  *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id);
+extern tNFA_HANDLE         nfa_hciu_get_pipe_owner (UINT8 pipe_id);
+extern UINT8               nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate);
+extern UINT8               nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate);
+extern tNFA_STATUS         nfa_hciu_asmbl_dyn_pipe_pkt (UINT8 *p_data, UINT8 data_len);
+
+extern tNFA_HCI_RESPONSE   nfa_hciu_add_pipe_to_gate (UINT8 pipe, UINT8 local_gate, UINT8 dest_host, UINT8 dest_gate);
+extern tNFA_HCI_RESPONSE   nfa_hciu_add_pipe_to_static_gate (UINT8 local_gate, UINT8 pipe_id, UINT8 dest_host, UINT8 dest_gate);
+
+extern tNFA_HCI_RESPONSE   nfa_hciu_release_pipe (UINT8 pipe_id);
+extern void                nfa_hciu_release_gate (UINT8 gate);
+extern void                nfa_hciu_remove_all_pipes_from_host (UINT8 host);
+extern UINT8               nfa_hciu_get_allocated_gate_list (UINT8 *p_gate_list);
+
+extern void                nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle);
+extern void                nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt);
+extern void                nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt);
+
+extern tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe);
+extern tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe);
+extern tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void);
+extern tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe);
+extern tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index);
+extern tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate);
+extern tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data);
+extern tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 pkt_len, UINT8 *p_pkt);
+
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+extern char *nfa_hciu_type_2_str (UINT8 type);
+extern char *nfa_hciu_instr_2_str (UINT8 type);
+extern char *nfa_hciu_get_event_name (UINT16 event);
+extern char *nfa_hciu_get_response_name (UINT8 rsp_code);
+extern char *nfa_hciu_get_state_name (UINT8 state);
+extern char *nfa_hciu_get_type_inst_names (UINT8 pipe, UINT8 type, UINT8 inst);
+extern char *nfa_hciu_evt_2_str (UINT8 pipe_id, UINT8 evt);
+#endif
+
+
+#endif /* NFA_HCI_INT_H */
diff --git a/src/nfa/int/nfa_p2p_int.h b/src/nfa/int/nfa_p2p_int.h
new file mode 100644
index 0000000..7eedbe0
--- /dev/null
+++ b/src/nfa/int/nfa_p2p_int.h
@@ -0,0 +1,332 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA P2P.
+ *
+ ******************************************************************************/
+#ifndef NFA_P2P_INT_H
+#define NFA_P2P_INT_H
+
+#if (defined (NFA_P2P_INCLUDED) && (NFA_P2P_INCLUDED==TRUE))
+#include "nfa_p2p_api.h"
+#include "nfa_dm_int.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_P2P_DEBUG   BT_TRACE_VERBOSE
+
+/* NFA P2P LLCP link state */
+enum
+{
+    NFA_P2P_LLCP_STATE_IDLE,
+    NFA_P2P_LLCP_STATE_LISTENING,
+    NFA_P2P_LLCP_STATE_ACTIVATED,
+
+    NFA_P2P_LLCP_STATE_MAX
+};
+
+typedef UINT8 tNFA_P2P_LLCP_STATE;
+
+/* NFA P2P events */
+enum
+{
+    NFA_P2P_API_REG_SERVER_EVT  = NFA_SYS_EVT_START (NFA_ID_P2P),
+    NFA_P2P_API_REG_CLIENT_EVT,
+    NFA_P2P_API_DEREG_EVT,
+    NFA_P2P_API_ACCEPT_CONN_EVT,
+    NFA_P2P_API_REJECT_CONN_EVT,
+    NFA_P2P_API_DISCONNECT_EVT,
+    NFA_P2P_API_CONNECT_EVT,
+    NFA_P2P_API_SEND_UI_EVT,
+    NFA_P2P_API_SEND_DATA_EVT,
+    NFA_P2P_API_SET_LOCAL_BUSY_EVT,
+    NFA_P2P_API_GET_LINK_INFO_EVT,
+    NFA_P2P_API_GET_REMOTE_SAP_EVT,
+    NFA_P2P_API_SET_LLCP_CFG_EVT,
+
+    NFA_P2P_LAST_EVT
+};
+
+/* data type for NFA_P2P_API_REG_SERVER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               server_sap;
+    tNFA_P2P_LINK_TYPE  link_type;
+    char                service_name[LLCP_MAX_SN_LEN + 1];
+    tNFA_P2P_CBACK     *p_cback;
+} tNFA_P2P_API_REG_SERVER;
+
+/* data type for NFA_P2P_API_REG_CLIENT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_P2P_LINK_TYPE  link_type;
+    tNFA_P2P_CBACK     *p_cback;
+} tNFA_P2P_API_REG_CLIENT;
+
+/* data type for NFA_P2P_API_DEREG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         handle;
+} tNFA_P2P_API_DEREG;
+
+/* data type for NFA_P2P_API_ACCEPT_CONN_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;
+    UINT16              miu;
+    UINT8               rw;
+} tNFA_P2P_API_ACCEPT_CONN;
+
+/* data type for NFA_P2P_API_REJECT_CONN_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;
+} tNFA_P2P_API_REJECT_CONN;
+
+/* data type for NFA_P2P_API_DISCONNECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;
+    BOOLEAN             flush;
+} tNFA_P2P_API_DISCONNECT;
+
+/* data type for NFA_P2P_API_CONNECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         client_handle;
+    char                service_name[LLCP_MAX_SN_LEN + 1];
+    UINT8               dsap;
+    UINT16              miu;
+    UINT8               rw;
+} tNFA_P2P_API_CONNECT;
+
+/* data type for NFA_P2P_API_SEND_UI_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         handle;
+    UINT8               dsap;
+    BT_HDR             *p_msg;
+} tNFA_P2P_API_SEND_UI;
+
+/* data type for NFA_P2P_API_SEND_DATA_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;
+    BT_HDR             *p_msg;
+} tNFA_P2P_API_SEND_DATA;
+
+/* data type for NFA_P2P_API_SET_LOCAL_BUSY_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;
+    BOOLEAN             is_busy;
+} tNFA_P2P_API_SET_LOCAL_BUSY;
+
+/* data type for NFA_P2P_API_GET_LINK_INFO_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         handle;
+} tNFA_P2P_API_GET_LINK_INFO;
+
+/* data type for NFA_P2P_API_GET_REMOTE_SAP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         handle;
+    char                service_name[LLCP_MAX_SN_LEN + 1];
+} tNFA_P2P_API_GET_REMOTE_SAP;
+
+/* data type for NFA_P2P_API_SET_LLCP_CFG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT16              link_miu;
+    UINT8               opt;
+    UINT8               wt;
+    UINT16              link_timeout;
+    UINT16              inact_timeout_init;
+    UINT16              inact_timeout_target;
+    UINT16              symm_delay;
+    UINT16              data_link_timeout;
+    UINT16              delay_first_pdu_timeout;
+} tNFA_P2P_API_SET_LLCP_CFG;
+
+/* union of all event data types */
+typedef union
+{
+    BT_HDR                      hdr;
+    tNFA_P2P_API_REG_SERVER     api_reg_server;
+    tNFA_P2P_API_REG_CLIENT     api_reg_client;
+    tNFA_P2P_API_DEREG          api_dereg;
+    tNFA_P2P_API_ACCEPT_CONN    api_accept;
+    tNFA_P2P_API_REJECT_CONN    api_reject;
+    tNFA_P2P_API_DISCONNECT     api_disconnect;
+    tNFA_P2P_API_CONNECT        api_connect;
+    tNFA_P2P_API_SEND_UI        api_send_ui;
+    tNFA_P2P_API_SEND_DATA      api_send_data;
+    tNFA_P2P_API_SET_LOCAL_BUSY api_local_busy;
+    tNFA_P2P_API_GET_LINK_INFO  api_link_info;
+    tNFA_P2P_API_GET_REMOTE_SAP api_remote_sap;
+    tNFA_P2P_API_SET_LLCP_CFG   api_set_llcp_cfg;
+} tNFA_P2P_MSG;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+#define NFA_P2P_HANDLE_FLAG_CONN             0x80   /* Bit flag for connection handle           */
+
+/* NFA P2P Connection block */
+#define NFA_P2P_CONN_FLAG_IN_USE             0x01   /* Connection control block is used         */
+#define NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO     0x02   /* Remote set RW to 0 (flow off)            */
+#define NFA_P2P_CONN_FLAG_CONGESTED          0x04   /* data link connection is congested        */
+
+typedef struct
+{
+    UINT8               flags;                      /* internal flags for data link connection  */
+    UINT8               local_sap;                  /* local SAP of data link connection        */
+    UINT8               remote_sap;                 /* remote SAP of data link connection       */
+    UINT16              remote_miu;                 /* MIU of remote end point                  */
+    UINT8               num_pending_i_pdu;          /* number of tx I PDU not processed by NFA  */
+} tNFA_P2P_CONN_CB;
+
+/* NFA P2P SAP control block */
+#define NFA_P2P_SAP_FLAG_SERVER             0x01    /* registered server                        */
+#define NFA_P2P_SAP_FLAG_CLIENT             0x02    /* registered client                        */
+#define NFA_P2P_SAP_FLAG_LLINK_CONGESTED    0x04    /* logical link connection is congested     */
+
+typedef struct
+{
+    UINT8              flags;                       /* internal flags for local SAP             */
+    tNFA_P2P_CBACK     *p_cback;                    /* callback function for local SAP          */
+    UINT8              num_pending_ui_pdu;          /* number of tx UI PDU not processed by NFA */
+} tNFA_P2P_SAP_CB;
+
+/* NFA P2P SDP control block */
+typedef struct
+{
+    UINT8            tid;                           /* transaction ID */
+    UINT8            local_sap;
+} tNFA_P2P_SDP_CB;
+
+#define NFA_P2P_NUM_SAP         64
+
+/* NFA P2P control block */
+typedef struct
+{
+    tNFA_HANDLE         dm_disc_handle;
+
+    tNFA_P2P_LLCP_STATE llcp_state;
+    BOOLEAN             is_initiator;
+    UINT16              local_link_miu;
+    UINT16              remote_link_miu;
+
+    tNFA_TECHNOLOGY_MASK listen_tech_mask;          /* for P2P listening */
+    BOOLEAN             is_p2p_listening;
+    BOOLEAN             is_cho_listening;
+    BOOLEAN             is_snep_listening;
+
+    tNFA_P2P_SAP_CB     sap_cb[NFA_P2P_NUM_SAP];
+    tNFA_P2P_CONN_CB    conn_cb[LLCP_MAX_DATA_LINK];
+    tNFA_P2P_SDP_CB     sdp_cb[LLCP_MAX_SDP_TRANSAC];
+
+    UINT8               total_pending_ui_pdu;       /* total number of tx UI PDU not processed by NFA */
+    UINT8               total_pending_i_pdu;        /* total number of tx I PDU not processed by NFA */
+
+    UINT8               trace_level;
+} tNFA_P2P_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA P2P control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_P2P_CB nfa_p2p_cb;
+#else
+extern tNFA_P2P_CB *nfa_p2p_cb_ptr;
+#define nfa_p2p_cb (*nfa_p2p_cb_ptr)
+#endif
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/*
+**  nfa_p2p_main.c
+*/
+void nfa_p2p_init (void);
+void nfa_p2p_update_listen_tech (tNFA_TECHNOLOGY_MASK tech_mask);
+void nfa_p2p_enable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks);
+void nfa_p2p_disable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks);
+void nfa_p2p_activate_llcp (tNFC_DISCOVER *p_data);
+void nfa_p2p_deactivate_llcp (void);
+void nfa_p2p_set_config (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask);
+
+/*
+**  nfa_p2p_act.c
+*/
+void nfa_p2p_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_p2p_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_p2p_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_p2p_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_p2p_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_p2p_proc_llcp_congestion (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_p2p_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA  *p_data);
+
+BOOLEAN nfa_p2p_start_sdp (char *p_service_name, UINT8 local_sap);
+
+BOOLEAN nfa_p2p_reg_server (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_reg_client (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_dereg (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_accept_connection (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_reject_connection (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_disconnect (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_create_data_link_connection (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_send_ui (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_send_data (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_set_local_busy (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_get_link_info (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_get_remote_sap (tNFA_P2P_MSG *p_msg);
+BOOLEAN nfa_p2p_set_llcp_cfg (tNFA_P2P_MSG *p_msg);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+char *nfa_p2p_evt_code (UINT16 evt_code);
+#endif
+
+#else
+
+#define nfa_p2p_init ()
+#define nfa_p2p_activate_llcp (a) {};
+#define nfa_p2p_deactivate_llcp ()
+#define nfa_p2p_set_config ()
+
+#endif /* (defined (NFA_P2P_INCLUDED) && (NFA_P2P_INCLUDED==TRUE)) */
+#endif /* NFA_P2P_INT_H */
diff --git a/src/nfa/int/nfa_rw_int.h b/src/nfa/int/nfa_rw_int.h
new file mode 100644
index 0000000..377a7aa
--- /dev/null
+++ b/src/nfa/int/nfa_rw_int.h
@@ -0,0 +1,337 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for NFA_RW
+ *
+ ******************************************************************************/
+#ifndef NFA_RW_INT_H
+#define NFA_RW_INT_H
+
+#include "nfa_sys.h"
+#include "nfa_api.h"
+#include "nfa_rw_api.h"
+#include "nfc_api.h"
+#include "rw_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* Interval for performing presence check (in ms) */
+#ifndef NFA_RW_PRESENCE_CHECK_INTERVAL
+#define NFA_RW_PRESENCE_CHECK_INTERVAL  750
+#endif
+
+/* TLV detection status */
+#define NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED         0x00 /* No Tlv detected */
+#define NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE   0x01 /* Lock control tlv detected */
+#define NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE    0x02 /* Memory control tlv detected */
+#define NFA_RW_TLV_DETECT_ST_COMPLETE               0x03 /* Both Lock and Memory control Tlvs are detected */
+
+typedef UINT8 tNFA_RW_TLV_ST;
+
+
+/* RW events */
+enum
+{
+    NFA_RW_OP_REQUEST_EVT = NFA_SYS_EVT_START (NFA_ID_RW),
+    NFA_RW_ACTIVATE_NTF_EVT,
+    NFA_RW_DEACTIVATE_NTF_EVT,
+    NFA_RW_PRESENCE_CHECK_TICK_EVT,
+    NFA_RW_MAX_EVT
+};
+
+
+
+/* BTA_RW operations */
+enum
+{
+    NFA_RW_OP_DETECT_NDEF,
+    NFA_RW_OP_READ_NDEF,
+    NFA_RW_OP_WRITE_NDEF,
+    NFA_RW_OP_PRESENCE_CHECK,
+    NFA_RW_OP_FORMAT_TAG,
+    NFA_RW_OP_SEND_RAW_FRAME,
+
+    /* Exclusive Type-1,Type-2 tag operations */
+    NFA_RW_OP_DETECT_LOCK_TLV,
+    NFA_RW_OP_DETECT_MEM_TLV,
+    NFA_RW_OP_SET_TAG_RO,
+
+    /* Exclusive Type-1 tag operations */
+    NFA_RW_OP_T1T_RID,
+    NFA_RW_OP_T1T_RALL,
+    NFA_RW_OP_T1T_READ,
+    NFA_RW_OP_T1T_WRITE,
+    NFA_RW_OP_T1T_RSEG,
+    NFA_RW_OP_T1T_READ8,
+    NFA_RW_OP_T1T_WRITE8,
+
+    /* Exclusive Type-2 tag operations */
+    NFA_RW_OP_T2T_READ,
+    NFA_RW_OP_T2T_WRITE,
+    NFA_RW_OP_T2T_SECTOR_SELECT,
+
+    /* Exclusive Type-3 tag operations */
+    NFA_RW_OP_T3T_READ,
+    NFA_RW_OP_T3T_WRITE,
+    NFA_RW_OP_T3T_GET_SYSTEM_CODES,
+
+    /* Exclusive ISO 15693 tag operations */
+    NFA_RW_OP_I93_INVENTORY,
+    NFA_RW_OP_I93_STAY_QUIET,
+    NFA_RW_OP_I93_READ_SINGLE_BLOCK,
+    NFA_RW_OP_I93_WRITE_SINGLE_BLOCK,
+    NFA_RW_OP_I93_LOCK_BLOCK,
+    NFA_RW_OP_I93_READ_MULTI_BLOCK,
+    NFA_RW_OP_I93_WRITE_MULTI_BLOCK,
+    NFA_RW_OP_I93_SELECT,
+    NFA_RW_OP_I93_RESET_TO_READY,
+    NFA_RW_OP_I93_WRITE_AFI,
+    NFA_RW_OP_I93_LOCK_AFI,
+    NFA_RW_OP_I93_WRITE_DSFID,
+    NFA_RW_OP_I93_LOCK_DSFID,
+    NFA_RW_OP_I93_GET_SYS_INFO,
+    NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS,
+
+    NFA_RW_OP_MAX
+};
+typedef UINT8 tNFA_RW_OP;
+
+/* Enumeration of parameter structios for nfa_rw operations */
+
+/* NFA_RW_OP_WRITE_NDEF params */
+typedef struct
+{
+    UINT32          len;
+    UINT8           *p_data;
+} tNFA_RW_OP_PARAMS_WRITE_NDEF;
+
+/* NFA_RW_OP_SEND_RAW_FRAME params */
+typedef struct
+{
+    BT_HDR          *p_data;
+} tNFA_RW_OP_PARAMS_SEND_RAW_FRAME;
+
+/* NFA_RW_OP_SET_TAG_RO params */
+typedef struct
+{
+    BOOLEAN         b_hard_lock;
+} tNFA_RW_OP_PARAMS_CONFIG_READ_ONLY;
+
+/* NFA_RW_OP_T1T_READ params */
+typedef struct
+{
+    UINT8           segment_number;
+    UINT8           block_number;
+    UINT8           index;
+} tNFA_RW_OP_PARAMS_T1T_READ;
+
+/* NFA_RW_OP_T1T_WRITE_E8,NFA_RW_OP_T1T_WRITE_NE8
+   NFA_RW_OP_T1T_WRITE_E, NFA_RW_OP_T1T_WRITE_NE params  */
+typedef struct
+{
+    BOOLEAN         b_erase;
+    UINT8           block_number;
+    UINT8           index;
+    UINT8           p_block_data[8];
+} tNFA_RW_OP_PARAMS_T1T_WRITE;
+
+/* NFA_RW_OP_T2T_READ params */
+typedef struct
+{
+    UINT8           block_number;
+} tNFA_RW_OP_PARAMS_T2T_READ;
+
+/* NFA_RW_OP_T2T_WRITE params */
+typedef struct
+{
+    UINT8           block_number;
+    UINT8           p_block_data[4];
+} tNFA_RW_OP_PARAMS_T2T_WRITE;
+
+/* NFA_RW_OP_T2T_SECTOR_SELECT params */
+typedef struct
+{
+    UINT8           sector_number;
+} tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT;
+
+/* NFA_RW_OP_T3T_READ params */
+typedef struct
+{
+    UINT8              num_blocks;
+    tNFA_T3T_BLOCK_DESC *p_block_desc;
+} tNFA_RW_OP_PARAMS_T3T_READ;
+
+/* NFA_RW_OP_T3T_WRITE params */
+typedef struct
+{
+    UINT8               num_blocks;
+    tNFA_T3T_BLOCK_DESC *p_block_desc;
+    UINT8               *p_block_data;
+} tNFA_RW_OP_PARAMS_T3T_WRITE;
+
+/* NFA_RW_OP_I93_INVENTORY params */
+typedef struct
+{
+    BOOLEAN             uid_present;
+    UINT8               uid[I93_UID_BYTE_LEN];
+    UINT8               afi;
+    UINT8               dsfid;
+    UINT8               first_block_number;
+    UINT16              number_blocks;
+    UINT8              *p_data;
+} tNFA_RW_OP_PARAMS_I93_CMD;
+
+/* Union of params for all reader/writer operations */
+typedef union
+{
+    /* params for NFA_RW_OP_WRITE_NDEF */
+    tNFA_RW_OP_PARAMS_WRITE_NDEF        write_ndef;
+
+    /* params for NFA_RW_OP_SEND_RAW_FRAME */
+    tNFA_RW_OP_PARAMS_SEND_RAW_FRAME    send_raw_frame;
+
+    /* params for NFA_RW_OP_SET_TAG_RO */
+    tNFA_RW_OP_PARAMS_CONFIG_READ_ONLY  set_readonly;
+
+    /* params for NFA_RW_OP_T2T_READ and NFA_RW_OP_T1T_WRITE */
+    tNFA_RW_OP_PARAMS_T1T_READ          t1t_read;
+    tNFA_RW_OP_PARAMS_T1T_WRITE         t1t_write;
+
+    /* params for NFA_RW_OP_T2T_READ,NFA_RW_OP_T2T_WRITE and NFA_RW_OP_T2T_SECTOR_SELECT */
+    tNFA_RW_OP_PARAMS_T2T_READ          t2t_read;
+    tNFA_RW_OP_PARAMS_T2T_WRITE         t2t_write;
+    tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT t2t_sector_select;
+
+    /* params for NFA_RW_OP_T3T_READ and NFA_RW_OP_T3T_WRITE */
+    tNFA_RW_OP_PARAMS_T3T_READ          t3t_read;
+    tNFA_RW_OP_PARAMS_T3T_WRITE         t3t_write;
+
+    /* params for ISO 15693 */
+    tNFA_RW_OP_PARAMS_I93_CMD           i93_cmd;
+
+} tNFA_RW_OP_PARAMS;
+
+/* data type for NFA_RW_op_req_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_RW_OP          op;     /* NFA RW operation */
+    tNFA_RW_OP_PARAMS   params;
+} tNFA_RW_OPERATION;
+
+/* data type for NFA_RW_ACTIVATE_NTF */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFC_ACTIVATE_DEVT  *p_activate_params; /* Data from NFC_ACTIVATE_DEVT      */
+    BOOLEAN             excl_rf_not_active; /* TRUE if not in exclusive RF mode */
+} tNFA_RW_ACTIVATE_NTF;
+
+/* union of all data types */
+typedef union
+{
+    /* GKI event buffer header */
+    BT_HDR                  hdr;
+    tNFA_RW_OPERATION       op_req;
+    tNFA_RW_ACTIVATE_NTF    activate_ntf;
+} tNFA_RW_MSG;
+
+/* NDEF detection status */
+enum
+{
+    NFA_RW_NDEF_ST_UNKNOWN =0,      /* NDEF detection not performed yet */
+    NFA_RW_NDEF_ST_TRUE,            /* Tag is NDEF */
+    NFA_RW_NDEF_ST_FALSE            /* Tag is not NDEF */
+};
+typedef UINT8 tNFA_RW_NDEF_ST;
+
+/* flags for RW control block */
+#define NFA_RW_FL_NOT_EXCL_RF_MODE              0x01    /* Activation while not in exclusive RF mode                                */
+#define NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY      0x02    /* Waiting for response from tag for auto-presence check                    */
+#define NFA_RW_FL_TAG_IS_READONLY               0x04    /* Read only tag                                                            */
+#define NFA_RW_FL_ACTIVATION_NTF_PENDING        0x08    /* Busy retrieving additional tag information                               */
+#define NFA_RW_FL_API_BUSY                      0x10    /* Tag operation is in progress                                             */
+#define NFA_RW_FL_ACTIVATED                     0x20    /* Tag is been activated                                                    */
+
+/* NFA RW control block */
+typedef struct
+{
+    tNFA_RW_OP      cur_op;         /* Current operation */
+
+    TIMER_LIST_ENT  tle;            /* list entry for nfa_rw timer */
+    tNFA_RW_MSG     *p_pending_msg; /* Pending API (if busy performing presence check) */
+
+    /* Tag info */
+    tNFC_PROTOCOL   protocol;
+    UINT8           pa_sel_res;
+    BOOLEAN         b_hard_lock;
+
+    tNFA_RW_MSG     *p_buffer_rw_msg; /* Buffer to hold incoming cmd while reading tag id */
+
+    /* TLV info */
+    tNFA_RW_TLV_ST  tlv_st;         /* TLV detection status */
+
+    /* NDEF info */
+    tNFA_RW_NDEF_ST ndef_st;        /* NDEF detection status */
+    UINT32          ndef_max_size;  /* max number of bytes available for NDEF data */
+    UINT32          ndef_cur_size;  /* current size of stored NDEF data (in bytes) */
+    UINT8           *p_ndef_buf;
+    UINT32          ndef_rd_offset; /* current read-offset of incoming NDEF data */
+
+    /* Current NDEF Write info */
+    UINT8           *p_ndef_wr_buf; /* Pointer to NDEF data being written */
+    UINT32          ndef_wr_len;    /* Length of NDEF data being written */
+
+    /* Flags (see defintions for NFA_RW_FL_* ) */
+    UINT8           flags;
+
+    /* ISO 15693 tag memory information */
+    UINT16          i93_afi_location;
+    UINT8           i93_dsfid;
+    UINT8           i93_block_size;
+    UINT16          i93_num_block;
+    UINT8           i93_uid[I93_UID_BYTE_LEN];
+} tNFA_RW_CB;
+extern tNFA_RW_CB nfa_rw_cb;
+
+
+
+/* type definition for action functions */
+typedef BOOLEAN (*tNFA_RW_ACTION) (tNFA_RW_MSG *p_data);
+
+/* Internal nfa_rw function prototypes */
+extern void    nfa_rw_stop_presence_check_timer (void);
+
+/* Action function prototypes */
+extern BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data);
+extern BOOLEAN nfa_rw_activate_ntf (tNFA_RW_MSG *p_data);
+extern BOOLEAN nfa_rw_deactivate_ntf (tNFA_RW_MSG *p_data);
+extern BOOLEAN nfa_rw_presence_check_tick (tNFA_RW_MSG *p_data);
+extern void    nfa_rw_handle_presence_check_rsp (tNFC_STATUS status);
+extern void    nfa_rw_command_complete (void);
+extern BOOLEAN nfa_rw_handle_event (BT_HDR *p_msg);
+
+extern void    nfa_rw_free_ndef_rx_buf (void);
+extern void    nfa_rw_sys_disable (void);
+
+#endif /* NFA_DM_INT_H */
+
diff --git a/src/nfa/int/nfa_snep_int.h b/src/nfa/int/nfa_snep_int.h
new file mode 100644
index 0000000..9cadec4
--- /dev/null
+++ b/src/nfa/int/nfa_snep_int.h
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA SNEP.
+ *
+ ******************************************************************************/
+#ifndef NFA_SNEP_INT_H
+#define NFA_SNEP_INT_H
+
+#if (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE))
+#include "llcp_api.h"
+#include "nfa_snep_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+#define NFA_SNEP_DEFAULT_SERVER_SAP     0x04    /* SNEP default server SAP   */
+#define NFA_SNEP_HEADER_SIZE            6       /* SNEP header size          */
+#define NFA_SNEP_ACCEPT_LEN_SIZE        4       /* SNEP Acceptable Length size */
+#define NFA_SNEP_CLIENT_TIMEOUT         1000    /* ms, waiting for response  */
+
+/* NFA SNEP events */
+enum
+{
+    NFA_SNEP_API_START_DEFAULT_SERVER_EVT  = NFA_SYS_EVT_START (NFA_ID_SNEP),
+    NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT,
+    NFA_SNEP_API_REG_SERVER_EVT,
+    NFA_SNEP_API_REG_CLIENT_EVT,
+    NFA_SNEP_API_DEREG_EVT,
+    NFA_SNEP_API_CONNECT_EVT,
+    NFA_SNEP_API_GET_REQ_EVT,
+    NFA_SNEP_API_PUT_REQ_EVT,
+    NFA_SNEP_API_GET_RESP_EVT,
+    NFA_SNEP_API_PUT_RESP_EVT,
+    NFA_SNEP_API_DISCONNECT_EVT,
+
+    NFA_SNEP_LAST_EVT
+};
+
+/* data type for NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_SNEP_CBACK     *p_cback;
+} tNFA_SNEP_API_START_DEFAULT_SERVER;
+
+/* data type for NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_SNEP_CBACK     *p_cback;
+} tNFA_SNEP_API_STOP_DEFAULT_SERVER;
+
+/* data type for NFA_SNEP_API_REG_SERVER_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    UINT8               server_sap;
+    char                service_name[LLCP_MAX_SN_LEN + 1];
+    tNFA_SNEP_CBACK     *p_cback;
+} tNFA_SNEP_API_REG_SERVER;
+
+/* data type for NFA_SNEP_API_REG_CLIENT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_SNEP_CBACK     *p_cback;
+} tNFA_SNEP_API_REG_CLIENT;
+
+/* data type for NFA_SNEP_API_DEREG_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         reg_handle;     /* handle for registered server/client */
+} tNFA_SNEP_API_DEREG;
+
+/* data type for NFA_SNEP_API_CONNECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         client_handle;  /* handle for client                   */
+    char                service_name[LLCP_MAX_SN_LEN + 1];
+} tNFA_SNEP_API_CONNECT;
+
+/* data type for NFA_SNEP_API_GET_REQ_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;    /* handle for data link connection      */
+    UINT32              buff_length;    /* length of buffer; acceptable length  */
+    UINT32              ndef_length;    /* length of current NDEF message       */
+    UINT8               *p_ndef_buff;   /* buffer for NDEF message              */
+} tNFA_SNEP_API_GET_REQ;
+
+/* data type for NFA_SNEP_API_PUT_REQ_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;    /* handle for data link connection */
+    UINT32              ndef_length;    /* length of NDEF message          */
+    UINT8               *p_ndef_buff;   /* buffer for NDEF message         */
+} tNFA_SNEP_API_PUT_REQ;
+
+/* data type for NFA_SNEP_API_GET_RESP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;    /* handle for data link connection */
+    tNFA_SNEP_RESP_CODE resp_code;      /* response code                   */
+    UINT32              ndef_length;    /* length of NDEF message          */
+    UINT8               *p_ndef_buff;   /* buffer for NDEF message         */
+} tNFA_SNEP_API_GET_RESP;
+
+/* data type for NFA_SNEP_API_PUT_RESP_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;    /* handle for data link connection */
+    tNFA_SNEP_RESP_CODE resp_code;      /* response code                   */
+} tNFA_SNEP_API_PUT_RESP;
+
+/* data type for NFA_SNEP_API_DISCONNECT_EVT */
+typedef struct
+{
+    BT_HDR              hdr;
+    tNFA_HANDLE         conn_handle;    /* response code                   */
+    BOOLEAN             flush;          /* TRUE if discard pending data    */
+} tNFA_SNEP_API_DISCONNECT;
+
+/* union of all event data types */
+typedef union
+{
+    BT_HDR                              hdr;
+    tNFA_SNEP_API_START_DEFAULT_SERVER  api_start_default_server;   /* NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+    tNFA_SNEP_API_STOP_DEFAULT_SERVER   api_stop_default_server;    /* NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT  */
+    tNFA_SNEP_API_REG_SERVER            api_reg_server;             /* NFA_SNEP_API_REG_SERVER_EVT   */
+    tNFA_SNEP_API_REG_CLIENT            api_reg_client;             /* NFA_SNEP_API_REG_CLIENT_EVT   */
+    tNFA_SNEP_API_DEREG                 api_dereg;                  /* NFA_SNEP_API_DEREG_EVT        */
+    tNFA_SNEP_API_CONNECT               api_connect;                /* NFA_SNEP_API_CONNECT_EVT      */
+    tNFA_SNEP_API_GET_REQ               api_get_req;                /* NFA_SNEP_API_GET_REQ_EVT      */
+    tNFA_SNEP_API_PUT_REQ               api_put_req;                /* NFA_SNEP_API_PUT_REQ_EVT      */
+    tNFA_SNEP_API_GET_RESP              api_get_resp;               /* NFA_SNEP_API_GET_RESP_EVT     */
+    tNFA_SNEP_API_PUT_RESP              api_put_resp;               /* NFA_SNEP_API_PUT_RESP_EVT     */
+    tNFA_SNEP_API_DISCONNECT            api_disc;                   /* NFA_SNEP_API_DISCONNECT_EVT   */
+} tNFA_SNEP_MSG;
+
+/*****************************************************************************
+**  control block
+*****************************************************************************/
+
+/* NFA SNEP service control block */
+#define NFA_SNEP_FLAG_ANY               0x00   /* ignore flags while searching   */
+#define NFA_SNEP_FLAG_SERVER            0x01   /* server */
+#define NFA_SNEP_FLAG_CLIENT            0x02   /* client */
+#define NFA_SNEP_FLAG_CONNECTING        0x04   /* waiting for connection confirm */
+#define NFA_SNEP_FLAG_CONNECTED         0x08   /* data link connected            */
+#define NFA_SNEP_FLAG_W4_RESP_CONTINUE  0x10   /* Waiting for continue response  */
+#define NFA_SNEP_FLAG_W4_REQ_CONTINUE   0x20   /* Waiting for continue request   */
+
+typedef struct
+{
+    UINT8               local_sap;      /* local SAP of service */
+    UINT8               remote_sap;     /* local SAP of service */
+    UINT8               flags;          /* internal flags       */
+    tNFA_SNEP_CBACK    *p_cback;        /* callback for event   */
+    TIMER_LIST_ENT      timer;          /* timer for client     */
+
+    UINT16              tx_miu;         /* adjusted MIU for throughput              */
+    BOOLEAN             congest;        /* TRUE if data link connection is congested */
+    BOOLEAN             rx_fragments;   /* TRUE if waiting more fragments            */
+
+    UINT8               tx_code;        /* transmitted code in request/response */
+    UINT8               rx_code;        /* received code in request/response    */
+
+    UINT32              acceptable_length;
+    UINT32              buff_length;    /* size of buffer for NDEF message   */
+    UINT32              ndef_length;    /* length of NDEF message            */
+    UINT32              cur_length;     /* currently sent or received length */
+    UINT8               *p_ndef_buff;   /* NDEF message buffer               */
+} tNFA_SNEP_CONN;
+
+/*
+** NFA SNEP control block
+*/
+typedef struct
+{
+    tNFA_SNEP_CONN      conn[NFA_SNEP_MAX_CONN];
+    BOOLEAN             listen_enabled;
+    BOOLEAN             is_dta_mode;
+    UINT8               trace_level;
+} tNFA_SNEP_CB;
+
+/*
+** NFA SNEP default server control block
+*/
+
+/* multiple data link connections for default server */
+typedef struct
+{
+    tNFA_HANDLE         conn_handle;    /* connection handle for default server   */
+    UINT8               *p_rx_ndef;     /* buffer to receive NDEF                 */
+} tNFA_SNEP_DEFAULT_CONN;
+
+#define NFA_SNEP_DEFAULT_MAX_CONN    3
+
+typedef struct
+{
+
+    tNFA_HANDLE             server_handle;                  /* registered handle for default server   */
+    tNFA_SNEP_DEFAULT_CONN  conn[NFA_SNEP_DEFAULT_MAX_CONN];/* connections for default server         */
+
+} tNFA_SNEP_DEFAULT_CB;
+
+/*****************************************************************************
+**  External variables
+*****************************************************************************/
+
+/* NFA SNEP control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_SNEP_CB nfa_snep_cb;
+#else
+extern tNFA_SNEP_CB *nfa_snep_cb_ptr;
+#define nfa_snep_cb (*nfa_snep_cb_ptr)
+#endif
+
+/* NFA SNEP default server control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_SNEP_DEFAULT_CB nfa_snep_default_cb;
+#else
+extern tNFA_SNEP_DEFAULT_CB *nfa_snep_default_cb_ptr;
+#define nfa_snep_default_cb (*nfa_snep_default_cb_ptr)
+#endif
+
+/*****************************************************************************
+**  External functions
+*****************************************************************************/
+/*
+**  nfa_snep_main.c
+*/
+void nfa_snep_init (BOOLEAN is_dta_mode);
+/*
+**  nfa_snep_default.c
+*/
+void nfa_snep_default_init (void);
+BOOLEAN nfa_snep_start_default_server (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_stop_default_server (tNFA_SNEP_MSG *p_msg);
+/*
+**  nfa_snep_srv.c
+*/
+UINT8 nfa_snep_allocate_cb (void);
+void nfa_snep_deallocate_cb (UINT8 xx);
+void nfa_snep_send_msg (UINT8 opcode, UINT8 dlink);
+
+void nfa_snep_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data);
+void nfa_snep_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_congest (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA  *p_data);
+void nfa_snep_proc_llcp_tx_complete (tLLCP_SAP_CBACK_DATA  *p_data);
+
+BOOLEAN nfa_snep_reg_server (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_reg_client (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_dereg (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_connect (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_put_resp (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_get_resp (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_put_req (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_get_req (tNFA_SNEP_MSG *p_msg);
+BOOLEAN nfa_snep_disconnect (tNFA_SNEP_MSG *p_msg);
+
+#endif /* (defined (NFA_SNEP_INCLUDED) && (NFA_SNEP_INCLUDED==TRUE)) */
+#endif /* NFA_SNEP_INT_H */
diff --git a/src/nfa/int/nfa_sys.h b/src/nfa/int/nfa_sys.h
new file mode 100644
index 0000000..0351636
--- /dev/null
+++ b/src/nfa/int/nfa_sys.h
@@ -0,0 +1,137 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the public interface file for the BTA system manager.
+ *
+ ******************************************************************************/
+#ifndef NFA_SYS_H
+#define NFA_SYS_H
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nfa_api.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+/* SW sub-systems */
+enum {
+    NFA_ID_SYS,         /* system manager                      */
+    NFA_ID_DM,          /* device manager                      */
+    NFA_ID_EE,          /* NFCEE sub-system                    */
+    NFA_ID_P2P,         /* Peer-to-Peer sub-system             */
+    NFA_ID_CHO,         /* Connection Handover sub-system      */
+    NFA_ID_SNEP,        /* SNEP sub-system                     */
+    NFA_ID_RW,          /* Reader/writer sub-system            */
+    NFA_ID_CE,          /* Card-emulation sub-system           */
+    NFA_ID_HCI,         /* Host controller interface sub-system*/
+#if (NFA_DTA_INCLUDED == TRUE)
+    NFA_ID_DTA,         /* Device Test Application sub-system  */
+#endif
+    NFA_ID_MAX
+};
+typedef UINT8 tNFA_SYS_ID;
+
+/* enable function type */
+typedef void (tNFA_SYS_ENABLE) (void);
+
+/* event handler function type */
+typedef BOOLEAN (tNFA_SYS_EVT_HDLR) (BT_HDR *p_msg);
+
+/* disable function type */
+typedef void (tNFA_SYS_DISABLE) (void);
+
+/* function type for processing the change of NFCC power mode */
+typedef void (tNFA_SYS_PROC_NFCC_PWR_MODE) (UINT8 nfcc_power_mode);
+
+typedef void (tNFA_SYS_CBACK) (void);
+typedef void (tNFA_SYS_ENABLE_CBACK) (void);
+typedef void (tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL) (void);
+
+/* registration structure */
+typedef struct
+{
+    tNFA_SYS_ENABLE                 *enable;
+    tNFA_SYS_EVT_HDLR               *evt_hdlr;
+    tNFA_SYS_DISABLE                *disable;
+    tNFA_SYS_PROC_NFCC_PWR_MODE     *proc_nfcc_pwr_mode;
+} tNFA_SYS_REG;
+
+/* system manager configuration structure */
+typedef struct
+{
+    UINT16          mbox_evt;                       /* GKI mailbox event */
+    UINT8           mbox;                           /* GKI mailbox id */
+    UINT8           timer;                          /* GKI timer id */
+    UINT8           trace_level;                    /* initial trace level */
+} tNFA_SYS_CFG;
+
+
+/*****************************************************************************
+**  Global data
+*****************************************************************************/
+
+/*****************************************************************************
+**  Macros
+*****************************************************************************/
+
+/* Calculate start of event enumeration; id is top 8 bits of event */
+#define NFA_SYS_EVT_START(id)       ((id) << 8)
+
+
+/*****************************************************************************
+**  Function declarations
+*****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+NFC_API extern void nfa_sys_init (void);
+NFC_API extern void nfa_sys_event (BT_HDR *p_msg);
+NFC_API extern void nfa_sys_timer_update (void);
+NFC_API extern void nfa_sys_disable_timers (void);
+NFC_API extern void nfa_sys_set_trace_level (UINT8 level);
+
+extern void nfa_sys_register (UINT8 id, const tNFA_SYS_REG *p_reg);
+extern void nfa_sys_deregister (UINT8 id);
+extern void nfa_sys_check_disabled (void);
+extern BOOLEAN nfa_sys_is_register (UINT8 id);
+extern void nfa_sys_disable_subsystems (BOOLEAN graceful);
+extern void nfa_sys_enable_subsystems (void);
+
+extern BOOLEAN nfa_sys_is_graceful_disable (void);
+extern void nfa_sys_sendmsg (void *p_msg);
+extern void nfa_sys_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout);
+extern void nfa_sys_stop_timer (TIMER_LIST_ENT *p_tle);
+
+extern void nfa_sys_cback_reg_enable_complete (tNFA_SYS_ENABLE_CBACK *p_cback);
+extern void nfa_sys_cback_notify_enable_complete (UINT8 id);
+
+extern void nfa_sys_notify_nfcc_power_mode (UINT8 nfcc_power_mode);
+extern void nfa_sys_cback_reg_nfcc_power_mode_proc_complete (tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL *p_cback);
+extern void nfa_sys_cback_notify_nfcc_power_mode_proc_complete (UINT8 id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_SYS_H */
diff --git a/src/nfa/int/nfa_sys_int.h b/src/nfa/int/nfa_sys_int.h
new file mode 100644
index 0000000..5be99df
--- /dev/null
+++ b/src/nfa/int/nfa_sys_int.h
@@ -0,0 +1,81 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the private interface file for the NFA system manager.
+ *
+ ******************************************************************************/
+#ifndef NFA_SYS_INT_H
+#define NFA_SYS_INT_H
+
+#include "nfa_sys_ptim.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+
+/* nfa_sys flags */
+#define NFA_SYS_FL_INITIALIZED  0x00000001          /* nfa_sys initialized */
+
+/*****************************************************************************
+**  state table
+*****************************************************************************/
+
+/* system manager control block */
+typedef struct
+{
+    UINT32                  flags;                  /* nfa_sys flags (must be first element of structure) */
+    tNFA_SYS_REG            *reg[NFA_ID_MAX];       /* registration structures */
+    BOOLEAN                 is_reg[NFA_ID_MAX];     /* registration structures */
+    tPTIM_CB                ptim_cb;                /* protocol timer list */
+    tNFA_SYS_ENABLE_CBACK   *p_enable_cback;
+    UINT16                  enable_cplt_flags;
+    UINT16                  enable_cplt_mask;
+
+    tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL  *p_proc_nfcc_pwr_mode_cmpl_cback;
+    UINT16                  proc_nfcc_pwr_mode_cplt_flags;
+    UINT16                  proc_nfcc_pwr_mode_cplt_mask;
+
+    BOOLEAN                 graceful_disable;       /* TRUE if NFA_Disable () is called with TRUE */
+    BOOLEAN                 timers_disabled;        /* TRUE if sys timers disabled */
+    UINT8                   trace_level;            /* Trace level */
+} tNFA_SYS_CB;
+
+
+
+/*****************************************************************************
+**  Global variables
+*****************************************************************************/
+
+/* system manager control block */
+#if NFA_DYNAMIC_MEMORY == FALSE
+extern tNFA_SYS_CB nfa_sys_cb;
+#else
+extern tNFA_SYS_CB *nfa_sys_cb_ptr;
+#define nfa_sys_cb (*nfa_sys_cb_ptr)
+#endif
+
+
+/* system manager configuration structure */
+extern tNFA_SYS_CFG *p_nfa_sys_cfg;
+
+BOOLEAN nfa_sys_sm_execute (BT_HDR *p_msg);
+
+#endif /* NFA_SYS_INT_H */
diff --git a/src/nfa/int/nfa_sys_ptim.h b/src/nfa/int/nfa_sys_ptim.h
new file mode 100644
index 0000000..8a81f65
--- /dev/null
+++ b/src/nfa/int/nfa_sys_ptim.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Protocol timer services.
+ *
+ ******************************************************************************/
+#ifndef NFA_SYS_PTIM_H
+#define NFA_SYS_PTIM_H
+
+#include "gki.h"
+
+/*****************************************************************************
+**  Constants and data types
+*****************************************************************************/
+
+typedef struct
+{
+    TIMER_LIST_Q        timer_queue;        /* GKI timer queue */
+    INT32               period;             /* Timer period in milliseconds */
+    UINT32              last_gki_ticks;     /* GKI ticks since last time update called */
+    UINT8               timer_id;           /* GKI timer id */
+} tPTIM_CB;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+**  Function Declarations
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_init
+**
+** Description      Initialize a protocol timer service control block.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_init (tPTIM_CB *p_cb, UINT16 period, UINT8 timer_id);
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_timer_update
+**
+** Description      Update the protocol timer list and handle expired timers.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_timer_update (tPTIM_CB *p_cb);
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_start_timer
+**
+** Description      Start a protocol timer for the specified amount
+**                  of time in milliseconds.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_start_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout);
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_stop_timer
+**
+** Description      Stop a protocol timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void nfa_sys_ptim_stop_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFA_SYS_PTIM_H */
diff --git a/src/nfa/p2p/nfa_p2p_act.c b/src/nfa/p2p/nfa_p2p_act.c
new file mode 100644
index 0000000..1901d8b
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_act.c
@@ -0,0 +1,1217 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the implementation file for the NFA P2P.
+ *
+ ******************************************************************************/
+
+#include "string.h"
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "llcp_defs.h"
+#include "llcp_api.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_allocate_conn_cb
+**
+** Description      Allocate data link connection control block
+**
+**
+** Returns          UINT8
+**
+*******************************************************************************/
+static UINT8 nfa_p2p_allocate_conn_cb (UINT8 local_sap)
+{
+    UINT8 xx;
+
+    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+    {
+        if (nfa_p2p_cb.conn_cb[xx].flags == 0)
+        {
+            nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_IN_USE;
+            nfa_p2p_cb.conn_cb[xx].local_sap = local_sap;
+
+            return (xx);
+        }
+    }
+
+    P2P_TRACE_ERROR0 ("nfa_p2p_allocate_conn_cb (): No resource");
+
+    return LLCP_MAX_DATA_LINK;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_deallocate_conn_cb
+**
+** Description      Deallocate data link connection control block
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfa_p2p_deallocate_conn_cb (UINT8 xx)
+{
+    if (xx < LLCP_MAX_DATA_LINK)
+    {
+        nfa_p2p_cb.conn_cb[xx].flags = 0;
+    }
+    else
+    {
+        P2P_TRACE_ERROR1 ("nfa_p2p_deallocate_conn_cb (): Invalid index (%d)", xx);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_find_conn_cb
+**
+** Description      Find data link connection control block by local/remote SAP
+**
+**
+** Returns          UINT8
+**
+*******************************************************************************/
+static UINT8 nfa_p2p_find_conn_cb (UINT8 local_sap, UINT8 remote_sap)
+{
+    UINT8 xx;
+
+    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+    {
+        if (  (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
+            &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)
+            &&(nfa_p2p_cb.conn_cb[xx].remote_sap == remote_sap)  )
+        {
+            return (xx);
+        }
+    }
+
+    return (LLCP_MAX_DATA_LINK);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_llcp_cback
+**
+** Description      Processing SAP callback events from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_p2p_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data)
+{
+    P2P_TRACE_DEBUG2 ("nfa_p2p_llcp_cback (): event:0x%02X, local_sap:0x%02X", p_data->hdr.event, p_data->hdr.local_sap);
+
+    switch (p_data->hdr.event)
+    {
+    case LLCP_SAP_EVT_DATA_IND:
+         nfa_p2p_proc_llcp_data_ind (p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONNECT_IND:
+        nfa_p2p_proc_llcp_connect_ind (p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONNECT_RESP:
+        nfa_p2p_proc_llcp_connect_resp (p_data);
+        break;
+
+    case LLCP_SAP_EVT_DISCONNECT_IND:
+        nfa_p2p_proc_llcp_disconnect_ind (p_data);
+        break;
+
+    case LLCP_SAP_EVT_DISCONNECT_RESP:
+        nfa_p2p_proc_llcp_disconnect_resp (p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONGEST:
+        nfa_p2p_proc_llcp_congestion (p_data);
+        break;
+
+    case LLCP_SAP_EVT_LINK_STATUS:
+        nfa_p2p_proc_llcp_link_status (p_data);
+        break;
+
+    default:
+        P2P_TRACE_ERROR1 ("nfa_p2p_llcp_cback (): Unknown event:0x%02X", p_data->hdr.event);
+        return;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_sdp_cback
+**
+** Description      Process SDP callback event from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_sdp_cback (UINT8 tid, UINT8 remote_sap)
+{
+    UINT8             local_sap;
+    UINT8             xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG2 ("nfa_p2p_sdp_cback (): tid:0x%02X, remote_sap:0x%02X", tid, remote_sap);
+
+    /* search for callback function to process */
+    for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
+    {
+        if (  (nfa_p2p_cb.sdp_cb[xx].local_sap != LLCP_INVALID_SAP)
+            &&(nfa_p2p_cb.sdp_cb[xx].tid == tid)  )
+        {
+            local_sap = nfa_p2p_cb.sdp_cb[xx].local_sap;
+
+            evt_data.sdp.handle     = (NFA_HANDLE_GROUP_P2P | local_sap);
+            evt_data.sdp.remote_sap = remote_sap;
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data);
+
+            nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
+            break;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_start_sdp
+**
+** Description      Initiate SDP
+**
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_start_sdp (char *p_service_name, UINT8 local_sap)
+{
+    int xx;
+
+    P2P_TRACE_DEBUG1 ("nfa_p2p_start_sdp (): SN:<%s>", p_service_name);
+
+    /* search for empty slot */
+    for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
+    {
+        if (nfa_p2p_cb.sdp_cb[xx].local_sap == LLCP_INVALID_SAP)
+        {
+            if (LLCP_DiscoverService (p_service_name,
+                                      nfa_p2p_sdp_cback,
+                                      &(nfa_p2p_cb.sdp_cb[xx].tid)) == LLCP_STATUS_SUCCESS)
+            {
+                nfa_p2p_cb.sdp_cb[xx].local_sap    = local_sap;
+                return TRUE;
+            }
+            else
+            {
+                /* failure of SDP */
+                return FALSE;
+            }
+        }
+    }
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_data_ind
+**
+** Description      Processing incoming data event from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             local_sap, xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_data_ind ()");
+
+    local_sap = p_data->data_ind.local_sap;
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        evt_data.data.handle    = 0;
+        /* if connectionless */
+        if (p_data->data_ind.link_type == NFA_P2P_LLINK_TYPE)
+        {
+            evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+        }
+        else
+        {
+            xx = nfa_p2p_find_conn_cb (p_data->data_ind.local_sap,
+                                       p_data->data_ind.remote_sap);
+
+            if (xx != LLCP_MAX_DATA_LINK)
+            {
+                evt_data.data.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+            }
+        }
+
+        evt_data.data.remote_sap = p_data->data_ind.remote_sap;
+        evt_data.data.link_type  = p_data->data_ind.link_type;
+
+        /* notify upper layer that there are data at LLCP */
+        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DATA_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_connect_ind
+**
+** Description      Processing connection request from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             server_sap, local_sap;
+    tNFA_P2P_EVT_DATA evt_data;
+    UINT8             xx;
+
+    P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_connect_ind () server_sap:0x%x",
+                       p_data->connect_ind.server_sap);
+
+    server_sap = p_data->connect_ind.server_sap;
+    local_sap  = p_data->connect_ind.local_sap;
+
+    if (nfa_p2p_cb.sap_cb[server_sap].p_cback)
+    {
+        xx = nfa_p2p_allocate_conn_cb (server_sap);
+
+        if (xx != LLCP_MAX_DATA_LINK)
+        {
+            nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_ind.remote_sap;
+            nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_ind.miu;
+
+            /* peer will not receive any data */
+            if (p_data->connect_ind.rw == 0)
+                nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
+
+            evt_data.conn_req.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+            evt_data.conn_req.conn_handle   = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+            evt_data.conn_req.remote_sap    = p_data->connect_ind.remote_sap;
+            evt_data.conn_req.remote_miu    = p_data->connect_ind.miu;
+            evt_data.conn_req.remote_rw     = p_data->connect_ind.rw;
+
+            nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_CONN_REQ_EVT, &evt_data);
+        }
+    }
+    else
+    {
+        P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_connect_ind (): Not registered");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_connect_resp
+**
+** Description      Processing connection response from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             local_sap, xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_connect_resp ()");
+
+    local_sap  = p_data->connect_resp.local_sap;
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        xx = nfa_p2p_allocate_conn_cb (local_sap);
+
+        if (xx != LLCP_MAX_DATA_LINK)
+        {
+            nfa_p2p_cb.conn_cb[xx].remote_sap = p_data->connect_resp.remote_sap;
+            nfa_p2p_cb.conn_cb[xx].remote_miu = p_data->connect_resp.miu;
+
+            /* peer will not receive any data */
+            if (p_data->connect_resp.rw == 0)
+                nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO;
+
+            evt_data.connected.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+            evt_data.connected.conn_handle   = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+            evt_data.connected.remote_sap    = p_data->connect_resp.remote_sap;
+            evt_data.connected.remote_miu    = p_data->connect_resp.miu;
+            evt_data.connected.remote_rw     = p_data->connect_resp.rw;
+
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONNECTED_EVT, &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_disconnect_ind
+**
+** Description      Processing disconnection request from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             local_sap, xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_ind ()");
+
+    local_sap  = p_data->disconnect_ind.local_sap;
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        xx = nfa_p2p_find_conn_cb (p_data->disconnect_ind.local_sap,
+                                   p_data->disconnect_ind.remote_sap);
+
+        if (xx != LLCP_MAX_DATA_LINK)
+        {
+            evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_INITIATE;
+
+            nfa_p2p_deallocate_conn_cb (xx);
+
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+        }
+        else
+        {
+            /*
+            ** LLCP link has been deactivated before receiving CC or DM.
+            ** Return NFA_P2P_DISC_EVT to indicate failure of creating connection
+            */
+
+            evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+
+            P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_ind (): Link deactivated");
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_disconnect_resp
+**
+** Description      Processing rejected connection from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             local_sap, xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_proc_llcp_disconnect_resp ()");
+
+    local_sap  = p_data->disconnect_resp.local_sap;
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC)
+        {
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
+        }
+        else if (  (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_APP_REJECTED)
+                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_THIS)
+                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_PERM_REJECT_ANY)
+                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_THIS)
+                 ||(p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_TEMP_REJECT_ANY)  )
+        {
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_REMOTE_REJECT;
+        }
+        else if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_NO_SERVICE)
+        {
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_SERVICE;
+        }
+        else if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION)
+        {
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+        }
+        else
+        {
+            evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
+        }
+
+        if (evt_data.disc.reason == NFA_P2P_DISC_REASON_LOCAL_INITITATE)
+        {
+            xx = nfa_p2p_find_conn_cb (p_data->disconnect_resp.local_sap,
+                                       p_data->disconnect_resp.remote_sap);
+
+            if (xx != LLCP_MAX_DATA_LINK)
+            {
+                evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+
+                nfa_p2p_deallocate_conn_cb (xx);
+
+                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+            }
+            else
+            {
+                P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_disconnect_resp (): No connection found");
+            }
+        }
+        else
+        {
+            evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_congest
+**
+** Description      Processing LLCP congestion event
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_congestion (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             local_sap, remote_sap, xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    local_sap  = p_data->congest.local_sap;
+    remote_sap = p_data->congest.remote_sap;
+
+    evt_data.congest.link_type    = p_data->congest.link_type;
+    evt_data.congest.is_congested = p_data->congest.is_congested;
+
+    if (p_data->congest.is_congested)
+    {
+        P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () START SAP=(0x%x,0x%x)",
+                          local_sap, remote_sap);
+
+    }
+    else
+    {
+        P2P_TRACE_DEBUG2 ("nfa_p2p_proc_llcp_congestion () END SAP=(0x%x,0x%x)",
+                          local_sap, remote_sap);
+    }
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        if (evt_data.congest.link_type == NFA_P2P_LLINK_TYPE)
+        {
+            evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+
+            if (  (evt_data.congest.is_congested == FALSE)
+                &&(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)  )
+            {
+                nfa_p2p_cb.sap_cb[local_sap].flags &= ~NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+            }
+            else if (  (evt_data.congest.is_congested == TRUE)
+                     &&(!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED))  )
+            {
+                /* this is overall congestion due to high usage of buffer pool */
+                nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+            }
+        }
+        else
+        {
+            xx = nfa_p2p_find_conn_cb (local_sap, remote_sap);
+
+            if (xx != LLCP_MAX_DATA_LINK)
+            {
+                evt_data.congest.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+
+                if (  (evt_data.congest.is_congested == FALSE)
+                    &&(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)  )
+                {
+                    nfa_p2p_cb.conn_cb[xx].flags &= ~NFA_P2P_CONN_FLAG_CONGESTED;
+                    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+                }
+                else if (  (evt_data.congest.is_congested == TRUE)
+                         &&(!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED))  )
+                {
+                    /* this is overall congestion due to high usage of buffer pool */
+                    nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+                    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+                }
+            }
+            else
+            {
+                P2P_TRACE_ERROR0 ("nfa_p2p_proc_llcp_congestion (): No connection found");
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_proc_llcp_link_status
+**
+** Description      Processing LLCP link status
+**
+**
+** Returns          next state after processing this event
+**
+*******************************************************************************/
+void nfa_p2p_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8             local_sap, xx;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG1 ("nfa_p2p_proc_llcp_link_status () is_activated:%d",
+                       p_data->link_status.is_activated);
+
+    local_sap  = p_data->link_status.local_sap;
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        if (p_data->link_status.is_activated)
+        {
+            /* only for server */
+            evt_data.activated.handle           = (NFA_HANDLE_GROUP_P2P | local_sap);
+            evt_data.activated.local_link_miu   = nfa_p2p_cb.local_link_miu;
+            evt_data.activated.remote_link_miu  = nfa_p2p_cb.remote_link_miu;
+
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
+        }
+        else /* if LLCP link is deactivated */
+        {
+            for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+            {
+                if (  (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
+                    &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap))
+                {
+                    evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+                    evt_data.disc.reason = NFA_P2P_DISC_REASON_LLCP_DEACTIVATED;
+
+                    nfa_p2p_deallocate_conn_cb (xx);
+                    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+                }
+            }
+
+            /* notify deactivation and clear flags */
+            if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_SERVER)
+            {
+                evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data);
+
+                nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_SERVER;
+            }
+            else if (nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_CLIENT)
+            {
+                evt_data.deactivated.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DEACTIVATED_EVT, &evt_data);
+
+                nfa_p2p_cb.sap_cb[local_sap].flags = NFA_P2P_SAP_FLAG_CLIENT;
+            }
+            else /* if this is not registered service */
+            {
+                nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_reg_server
+**
+** Description      Allocate a service as server and register to LLCP
+**
+**
+** Returns          FALSE if need to keep buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_reg_server (tNFA_P2P_MSG *p_msg)
+{
+    tNFA_P2P_EVT_DATA  evt_data;
+    UINT8              server_sap;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_reg_server ()");
+
+    server_sap = LLCP_RegisterServer (p_msg->api_reg_server.server_sap,
+                                      p_msg->api_reg_server.link_type,
+                                      p_msg->api_reg_server.service_name,
+                                      nfa_p2p_llcp_cback);
+
+    if (server_sap == LLCP_INVALID_SAP)
+    {
+        evt_data.reg_server.server_handle = NFA_HANDLE_INVALID;
+        evt_data.reg_server.server_sap    = NFA_P2P_INVALID_SAP;
+        BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
+                       p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+        evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
+
+        p_msg->api_reg_server.p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data);
+
+        return TRUE;
+    }
+
+    /* if need to update WKS in LLCP Gen bytes */
+    if (server_sap <= LLCP_UPPER_BOUND_WK_SAP)
+    {
+        nfa_p2p_enable_listening (NFA_ID_P2P, TRUE);
+    }
+    else if (!nfa_p2p_cb.is_p2p_listening)
+    {
+        nfa_p2p_enable_listening (NFA_ID_P2P, FALSE);
+    }
+
+    nfa_p2p_cb.sap_cb[server_sap].p_cback    = p_msg->api_reg_server.p_cback;
+    nfa_p2p_cb.sap_cb[server_sap].flags      = NFA_P2P_SAP_FLAG_SERVER;
+
+    evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+    evt_data.reg_server.server_sap    = server_sap;
+    BCM_STRNCPY_S (evt_data.reg_server.service_name, sizeof (evt_data.reg_server.service_name),
+                   p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+    evt_data.reg_server.service_name[LLCP_MAX_SN_LEN] = 0;
+
+    /* notify NFA_P2P_REG_SERVER_EVT to server */
+    nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_REG_SERVER_EVT, &evt_data);
+
+    /* if LLCP is already activated */
+    if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
+    {
+        evt_data.activated.handle          = (NFA_HANDLE_GROUP_P2P | server_sap);
+        evt_data.activated.local_link_miu  = nfa_p2p_cb.local_link_miu;
+        evt_data.activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+        /* notify NFA_P2P_ACTIVATED_EVT to server */
+        nfa_p2p_cb.sap_cb[server_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_reg_client
+**
+** Description      Allocate a service as client and register to LLCP
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_reg_client (tNFA_P2P_MSG *p_msg)
+{
+    tNFA_P2P_EVT_DATA  evt_data;
+    UINT8              local_sap;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_reg_client ()");
+
+    local_sap = LLCP_RegisterClient (p_msg->api_reg_client.link_type,
+                                     nfa_p2p_llcp_cback);
+
+    if (local_sap == LLCP_INVALID_SAP)
+    {
+        evt_data.reg_client.client_handle = NFA_HANDLE_INVALID;
+        p_msg->api_reg_client.p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data);
+        return TRUE;
+    }
+
+    nfa_p2p_cb.sap_cb[local_sap].p_cback = p_msg->api_reg_client.p_cback;
+    nfa_p2p_cb.sap_cb[local_sap].flags   = NFA_P2P_SAP_FLAG_CLIENT;
+
+    evt_data.reg_client.client_handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_REG_CLIENT_EVT, &evt_data);
+
+    /* if LLCP is already activated */
+    if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
+    {
+        evt_data.activated.handle           = (NFA_HANDLE_GROUP_P2P | local_sap);
+        evt_data.activated.local_link_miu   = nfa_p2p_cb.local_link_miu;
+        evt_data.activated.remote_link_miu  = nfa_p2p_cb.remote_link_miu;
+
+        /* notify NFA_P2P_ACTIVATED_EVT to client */
+        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_ACTIVATED_EVT, &evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_dereg
+**
+** Description      Deallocate a service as server or client and deregister to LLCP
+**                  LLCP will deallocate data link connection created by this server
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_dereg (tNFA_P2P_MSG *p_msg)
+{
+    UINT8 local_sap, xx;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_dereg ()");
+
+    local_sap = (UINT8) (p_msg->api_dereg.handle & NFA_HANDLE_MASK);
+
+    if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+    {
+        for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++)
+        {
+            if (  (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_IN_USE)
+                &&(nfa_p2p_cb.conn_cb[xx].local_sap == local_sap)  )
+            {
+                nfa_p2p_deallocate_conn_cb (xx);
+            }
+        }
+    }
+
+    LLCP_Deregister (local_sap);
+    nfa_p2p_cb.sap_cb[local_sap].p_cback = NULL;
+
+    if (nfa_p2p_cb.is_p2p_listening)
+    {
+        /* check if this is the last server on NFA P2P */
+        for (xx = 0; xx < NFA_P2P_NUM_SAP; xx++)
+        {
+            if (  (nfa_p2p_cb.sap_cb[xx].p_cback)
+                &&(nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_SERVER)  )
+            {
+                break;
+            }
+        }
+
+        if (xx >= NFA_P2P_NUM_SAP)
+        {
+            /* if need to update WKS in LLCP Gen bytes */
+            if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+                nfa_p2p_disable_listening (NFA_ID_P2P, TRUE);
+            else
+                nfa_p2p_disable_listening (NFA_ID_P2P, FALSE);
+        }
+        /* if need to update WKS in LLCP Gen bytes */
+        else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+        {
+            nfa_p2p_enable_listening (NFA_ID_P2P, TRUE);
+        }
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_accept_connection
+**
+** Description      Connection Confirm from local application
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_accept_connection (tNFA_P2P_MSG *p_msg)
+{
+    UINT8                   xx;
+    tLLCP_CONNECTION_PARAMS params;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_accept_connection ()");
+
+    xx  = (UINT8) (p_msg->api_accept.conn_handle & NFA_HANDLE_MASK);
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    params.miu   = p_msg->api_accept.miu;
+    params.rw    = p_msg->api_accept.rw;
+    params.sn[0] = 0;
+
+    LLCP_ConnectCfm (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap, &params);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_reject_connection
+**
+** Description      Reject connection by local application
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_reject_connection (tNFA_P2P_MSG *p_msg)
+{
+    UINT8 xx;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_reject_connection ()");
+
+    xx  = (UINT8) (p_msg->api_reject.conn_handle & NFA_HANDLE_MASK);
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    LLCP_ConnectReject (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap,
+                        LLCP_SAP_DM_REASON_APP_REJECTED);
+
+    /* no need to deregister service on LLCP */
+    nfa_p2p_deallocate_conn_cb (xx);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_disconnect
+**
+** Description      Disconnect data link connection by local application
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_disconnect (tNFA_P2P_MSG *p_msg)
+{
+    UINT8             local_sap, xx;
+    tLLCP_STATUS      status;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_disconnect ()");
+
+    xx = (UINT8) (p_msg->api_disconnect.conn_handle & NFA_HANDLE_MASK);
+
+    /* if this is for data link connection */
+    if (xx & NFA_P2P_HANDLE_FLAG_CONN)
+    {
+        xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+        status = LLCP_DisconnectReq (nfa_p2p_cb.conn_cb[xx].local_sap, nfa_p2p_cb.conn_cb[xx].remote_sap,
+                                     p_msg->api_disconnect.flush);
+
+        if (status == LLCP_STATUS_SUCCESS)
+        {
+            /* wait for disconnect response if successful */
+            return TRUE;
+        }
+        else
+        {
+            /*
+            ** while we are waiting for connect confirm,
+            ** we cannot sent DISC because we don't know DSAP yet
+            */
+            local_sap = nfa_p2p_cb.conn_cb[xx].local_sap;
+
+            if (nfa_p2p_cb.sap_cb[local_sap].p_cback)
+            {
+                evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+                evt_data.disc.reason = NFA_P2P_DISC_REASON_LOCAL_INITITATE;
+
+                nfa_p2p_deallocate_conn_cb (xx);
+                nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+            }
+        }
+    }
+    else
+    {
+        P2P_TRACE_ERROR0 ("Handle is not for Data link connection");
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_create_data_link_connection
+**
+** Description      Create data link connection
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_create_data_link_connection (tNFA_P2P_MSG *p_msg)
+{
+    UINT8                   local_sap;
+    tNFA_P2P_EVT_DATA       evt_data;
+    tLLCP_CONNECTION_PARAMS conn_params;
+    tLLCP_STATUS            status;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_create_data_link_connection ()");
+
+    local_sap = (UINT8) (p_msg->api_connect.client_handle & NFA_HANDLE_MASK);
+
+    conn_params.miu = p_msg->api_connect.miu;
+    conn_params.rw  = p_msg->api_connect.rw;
+
+    /* NFA_P2pConnectBySap () */
+    if (p_msg->api_connect.dsap != LLCP_INVALID_SAP)
+    {
+        conn_params.sn[0] = 0;
+        status = LLCP_ConnectReq (local_sap, p_msg->api_connect.dsap, &conn_params);
+    }
+    /* NFA_P2pConnectByName () */
+    else
+    {
+        BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn),
+                       p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
+        conn_params.sn[LLCP_MAX_SN_LEN] = 0;
+
+        status = LLCP_ConnectReq (local_sap, LLCP_SAP_SDP, &conn_params);
+    }
+
+    if (status != LLCP_STATUS_SUCCESS)
+    {
+        evt_data.disc.handle = (NFA_HANDLE_GROUP_P2P | local_sap);
+        evt_data.disc.reason = NFA_P2P_DISC_REASON_NO_INFORMATION;
+
+        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_DISC_EVT, &evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_send_ui
+**
+** Description      Send UI PDU
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_send_ui (tNFA_P2P_MSG *p_msg)
+{
+    UINT8             local_sap;
+    tLLCP_STATUS      status;
+    tNFA_P2P_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_send_ui ()");
+
+    local_sap = (UINT8) (p_msg->api_send_ui.handle & NFA_HANDLE_MASK);
+
+    /* decrease number of tx UI PDU which is not processed by NFA for congestion control */
+    if (nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu)
+        nfa_p2p_cb.sap_cb[local_sap].num_pending_ui_pdu--;
+
+    if (nfa_p2p_cb.total_pending_ui_pdu)
+        nfa_p2p_cb.total_pending_ui_pdu--;
+
+    status = LLCP_SendUI (local_sap,
+                          p_msg->api_send_ui.dsap,
+                          p_msg->api_send_ui.p_msg);
+
+    if (status == LLCP_STATUS_CONGESTED)
+    {
+        if (!(nfa_p2p_cb.sap_cb[local_sap].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED))
+        {
+            nfa_p2p_cb.sap_cb[local_sap].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+
+            /* notify that this logical link is congested */
+            evt_data.congest.link_type    = NFA_P2P_LLINK_TYPE;
+            evt_data.congest.handle       = (NFA_HANDLE_GROUP_P2P | local_sap);
+            evt_data.congest.is_congested = TRUE;
+
+            nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+        }
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_send_data
+**
+** Description      Send I PDU
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_send_data (tNFA_P2P_MSG *p_msg)
+{
+    tNFA_P2P_EVT_DATA evt_data;
+    tLLCP_STATUS      status;
+    UINT8             xx;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_send_data ()");
+
+    xx = (UINT8) (p_msg->api_send_data.conn_handle & NFA_HANDLE_MASK);
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    /* decrease number of tx I PDU which is not processed by NFA for congestion control */
+    if (nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu)
+        nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu--;
+
+    if (nfa_p2p_cb.total_pending_i_pdu)
+        nfa_p2p_cb.total_pending_i_pdu--;
+
+    status = LLCP_SendData (nfa_p2p_cb.conn_cb[xx].local_sap,
+                            nfa_p2p_cb.conn_cb[xx].remote_sap,
+                            p_msg->api_send_data.p_msg);
+
+    if (status == LLCP_STATUS_CONGESTED)
+    {
+        if (!(nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED))
+        {
+            nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+
+            /* notify that this data link is congested */
+            evt_data.congest.link_type    = NFA_P2P_DLINK_TYPE;
+            evt_data.congest.handle       = (NFA_HANDLE_GROUP_P2P | NFA_P2P_HANDLE_FLAG_CONN | xx);
+            evt_data.congest.is_congested = TRUE;
+
+            nfa_p2p_cb.sap_cb[nfa_p2p_cb.conn_cb[xx].local_sap].p_cback (NFA_P2P_CONGEST_EVT, &evt_data);
+        }
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_set_local_busy
+**
+** Description      Set or reset local busy
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_set_local_busy (tNFA_P2P_MSG *p_msg)
+{
+    UINT8 xx;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_set_local_busy ()");
+
+    xx = (UINT8) (p_msg->api_local_busy.conn_handle & NFA_HANDLE_MASK);
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    LLCP_SetLocalBusyStatus (nfa_p2p_cb.conn_cb[xx].local_sap,
+                             nfa_p2p_cb.conn_cb[xx].remote_sap,
+                             p_msg->api_local_busy.is_busy);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_get_link_info
+**
+** Description      Get WKS of remote and link MIU
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_get_link_info (tNFA_P2P_MSG *p_msg)
+{
+    tNFA_P2P_EVT_DATA evt_data;
+    UINT8             local_sap;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_get_link_info ()");
+
+    evt_data.link_info.handle          = p_msg->api_link_info.handle;
+    evt_data.link_info.wks             = LLCP_GetRemoteWKS ();
+    evt_data.link_info.local_link_miu  = nfa_p2p_cb.local_link_miu;
+    evt_data.link_info.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+
+    local_sap =  (UINT8) (p_msg->api_link_info.handle & NFA_HANDLE_MASK);
+    nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_LINK_INFO_EVT, &evt_data);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_get_remote_sap
+**
+** Description      Get remote SAP
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_get_remote_sap (tNFA_P2P_MSG *p_msg)
+{
+    tNFA_P2P_EVT_DATA evt_data;
+    UINT8             local_sap;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_get_remote_sap ()");
+
+    local_sap =  (UINT8) (p_msg->api_remote_sap.handle & NFA_HANDLE_MASK);
+
+    if (!nfa_p2p_start_sdp (p_msg->api_remote_sap.service_name,
+                            local_sap))
+    {
+        evt_data.sdp.handle     = p_msg->api_remote_sap.handle;
+        evt_data.sdp.remote_sap = 0x00;
+        nfa_p2p_cb.sap_cb[local_sap].p_cback (NFA_P2P_SDP_EVT, &evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_set_llcp_cfg
+**
+** Description      Set LLCP configuration
+**
+**
+** Returns          TRUE to deallocate buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_p2p_set_llcp_cfg (tNFA_P2P_MSG *p_msg)
+{
+    LLCP_SetConfig (p_msg->api_set_llcp_cfg.link_miu,
+                    p_msg->api_set_llcp_cfg.opt,
+                    p_msg->api_set_llcp_cfg.wt,
+                    p_msg->api_set_llcp_cfg.link_timeout,
+                    p_msg->api_set_llcp_cfg.inact_timeout_init,
+                    p_msg->api_set_llcp_cfg.inact_timeout_target,
+                    p_msg->api_set_llcp_cfg.symm_delay,
+                    p_msg->api_set_llcp_cfg.data_link_timeout,
+                    p_msg->api_set_llcp_cfg.delay_first_pdu_timeout);
+
+    return TRUE;
+}
diff --git a/src/nfa/p2p/nfa_p2p_api.c b/src/nfa/p2p/nfa_p2p_api.c
new file mode 100644
index 0000000..aa4d25a
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_api.c
@@ -0,0 +1,1155 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface to LLCP
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "llcp_defs.h"
+#include "llcp_api.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterServer
+**
+** Description      This function is called to listen to a SAP as server on LLCP.
+**
+**                  NFA_P2P_REG_SERVER_EVT will be returned with status and handle.
+**
+**                  If server_sap is set to NFA_P2P_ANY_SAP, then NFA will allocate
+**                  a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+**                  Otherwise, server_sap must be between (LLCP_SDP_SAP + 1) and
+**                  LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRegisterServer (UINT8              server_sap,
+                                   tNFA_P2P_LINK_TYPE link_type,
+                                   char               *p_service_name,
+                                   tNFA_P2P_CBACK     *p_cback)
+{
+    tNFA_P2P_API_REG_SERVER *p_msg;
+
+    P2P_TRACE_API3 ("NFA_P2pRegisterServer (): server_sap:0x%02x, link_type:0x%x, SN:<%s>",
+                     server_sap, link_type, p_service_name);
+
+    if (  (server_sap != NFA_P2P_ANY_SAP)
+        &&((server_sap <= LLCP_SAP_SDP) ||(server_sap > LLCP_UPPER_BOUND_SDP_SAP))  )
+    {
+        P2P_TRACE_ERROR2 ("NFA_P2pRegisterServer (): server_sap must be between %d and %d",
+                          LLCP_SAP_SDP + 1, LLCP_UPPER_BOUND_SDP_SAP);
+        return (NFA_STATUS_FAILED);
+    }
+    else if (  ((link_type & NFA_P2P_LLINK_TYPE) == 0x00)
+             &&((link_type & NFA_P2P_DLINK_TYPE) == 0x00)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pRegisterServer(): link type (0x%x) must be specified", link_type);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_REG_SERVER *) GKI_getbuf (sizeof (tNFA_P2P_API_REG_SERVER))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_REG_SERVER_EVT;
+
+        p_msg->server_sap = server_sap;
+        p_msg->link_type  = link_type;
+
+        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+        p_msg->p_cback = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRegisterClient
+**
+** Description      This function is called to register a client service on LLCP.
+**
+**                  NFA_P2P_REG_CLIENT_EVT will be returned with status and handle.
+**
+**                  link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRegisterClient (tNFA_P2P_LINK_TYPE link_type,
+                                   tNFA_P2P_CBACK     *p_cback)
+{
+    tNFA_P2P_API_REG_CLIENT *p_msg;
+
+    P2P_TRACE_API1 ("NFA_P2pRegisterClient (): link_type:0x%x", link_type);
+
+    if (  ((link_type & NFA_P2P_LLINK_TYPE) == 0x00)
+        &&((link_type & NFA_P2P_DLINK_TYPE) == 0x00)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pRegisterClient (): link type (0x%x) must be specified", link_type);
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_REG_CLIENT *) GKI_getbuf (sizeof (tNFA_P2P_API_REG_CLIENT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_REG_CLIENT_EVT;
+
+        p_msg->p_cback   = p_cback;
+        p_msg->link_type = link_type;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDeregister
+**
+** Description      This function is called to stop listening to a SAP as server
+**                  or stop client service on LLCP.
+**
+** Note:            If this function is called to de-register a server and RF discovery
+**                  is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pDeregister (tNFA_HANDLE handle)
+{
+    tNFA_P2P_API_DEREG *p_msg;
+    tNFA_HANDLE         xx;
+
+    P2P_TRACE_API1 ("NFA_P2pDeregister (): handle:0x%02X", handle);
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pDeregister (): Handle is invalid or not registered");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_DEREG *) GKI_getbuf (sizeof (tNFA_P2P_API_DEREG))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_DEREG_EVT;
+
+        p_msg->handle    = handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pAcceptConn
+**
+** Description      This function is called to accept a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pAcceptConn (tNFA_HANDLE handle,
+                               UINT16      miu,
+                               UINT8       rw)
+{
+    tNFA_P2P_API_ACCEPT_CONN *p_msg;
+    tNFA_HANDLE               xx;
+
+    P2P_TRACE_API3 ("NFA_P2pAcceptConn (): handle:0x%02X, MIU:%d, RW:%d", handle, miu, rw);
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (!(xx & NFA_P2P_HANDLE_FLAG_CONN))
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pAcceptConn (): Connection Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+    else
+    {
+        xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+    }
+
+    if (  (xx >= LLCP_MAX_DATA_LINK)
+        ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pAcceptConn (): Connection Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((miu < LLCP_DEFAULT_MIU) || (nfa_p2p_cb.local_link_miu < miu))
+    {
+        P2P_TRACE_ERROR3 ("NFA_P2pAcceptConn (): MIU(%d) must be between %d and %d",
+                            miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+    }
+    else if ((p_msg = (tNFA_P2P_API_ACCEPT_CONN *) GKI_getbuf (sizeof (tNFA_P2P_API_ACCEPT_CONN))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_ACCEPT_CONN_EVT;
+
+        p_msg->conn_handle  = handle;
+        p_msg->miu          = miu;
+        p_msg->rw           = rw;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pRejectConn
+**
+** Description      This function is called to reject a request of data link
+**                  connection to a listening SAP on LLCP after receiving
+**                  NFA_P2P_CONN_REQ_EVT.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pRejectConn (tNFA_HANDLE handle)
+{
+    tNFA_P2P_API_REJECT_CONN *p_msg;
+    tNFA_HANDLE               xx;
+
+    P2P_TRACE_API1 ("NFA_P2pRejectConn (): handle:0x%02X", handle);
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (!(xx & NFA_P2P_HANDLE_FLAG_CONN))
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pRejectConn (): Connection Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+    else
+    {
+        xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+    }
+
+    if (  (xx >= LLCP_MAX_DATA_LINK)
+        ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pRejectConn (): Connection Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_REJECT_CONN *) GKI_getbuf (sizeof (tNFA_P2P_API_REJECT_CONN))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_REJECT_CONN_EVT;
+
+        p_msg->conn_handle  = handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pDisconnect
+**
+** Description      This function is called to disconnect an existing or
+**                  connecting data link connection.
+**
+**                  discard any pending data on data link connection if flush is set to TRUE
+**
+**                  NFA_P2P_DISC_EVT will be returned after data link connection is disconnected
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pDisconnect (tNFA_HANDLE handle, BOOLEAN flush)
+{
+    tNFA_P2P_API_DISCONNECT *p_msg;
+    tNFA_HANDLE              xx;
+
+    P2P_TRACE_API2 ("NFA_P2pDisconnect (): handle:0x%02X, flush=%d", handle, flush);
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (xx & NFA_P2P_HANDLE_FLAG_CONN)
+    {
+        xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+        if (  (xx >= LLCP_MAX_DATA_LINK)
+            ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+        {
+            P2P_TRACE_ERROR0 ("NFA_P2pDisconnect (): Connection Handle is not valid");
+            return (NFA_STATUS_BAD_HANDLE);
+        }
+    }
+    else
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pDisconnect (): Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_DISCONNECT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_DISCONNECT_EVT;
+
+        p_msg->conn_handle  = handle;
+        p_msg->flush        = flush;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectByName
+**
+** Description      This function is called to create a connection-oriented transport
+**                  by a service name.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pConnectByName (tNFA_HANDLE client_handle,
+                                  char        *p_service_name,
+                                  UINT16      miu,
+                                  UINT8       rw)
+{
+    tNFA_P2P_API_CONNECT *p_msg;
+    tNFA_HANDLE           xx;
+
+    P2P_TRACE_API4 ("NFA_P2pConnectByName (): client_handle:0x%x, SN:<%s>, MIU:%d, RW:%d",
+                    client_handle, p_service_name, miu, rw);
+
+    xx = client_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pConnectByName (): Client Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if (  (miu < LLCP_DEFAULT_MIU)
+        ||(nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+        ||(nfa_p2p_cb.local_link_miu < miu)  )
+    {
+        P2P_TRACE_ERROR3 ("NFA_P2pConnectByName (): MIU(%d) must be between %d and %d or LLCP link is not activated",
+                            miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+    }
+    else if ((p_msg = (tNFA_P2P_API_CONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_CONNECT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
+
+        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+        p_msg->dsap    = LLCP_INVALID_SAP;
+        p_msg->miu     = miu;
+        p_msg->rw      = rw;
+        p_msg->client_handle = client_handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pConnectBySap
+**
+** Description      This function is called to create a connection-oriented transport
+**                  by a SAP.
+**                  NFA_P2P_CONNECTED_EVT if success
+**                  NFA_P2P_DISC_EVT if failed
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pConnectBySap (tNFA_HANDLE client_handle,
+                                 UINT8       dsap,
+                                 UINT16      miu,
+                                 UINT8       rw)
+{
+    tNFA_P2P_API_CONNECT *p_msg;
+    tNFA_HANDLE           xx;
+
+    P2P_TRACE_API4 ("NFA_P2pConnectBySap (): client_handle:0x%x, DSAP:0x%02X, MIU:%d, RW:%d",
+                    client_handle, dsap, miu, rw);
+
+    xx = client_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pConnectBySap (): Client Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if (  (miu < LLCP_DEFAULT_MIU)
+        ||(nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+        ||(nfa_p2p_cb.local_link_miu < miu)  )
+    {
+        P2P_TRACE_ERROR3 ("NFA_P2pConnectBySap (): MIU(%d) must be between %d and %d, or LLCP link is not activated",
+                            miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu);
+    }
+    else if ((p_msg = (tNFA_P2P_API_CONNECT *) GKI_getbuf (sizeof (tNFA_P2P_API_CONNECT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
+
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+        p_msg->dsap    = dsap;
+        p_msg->miu     = miu;
+        p_msg->rw      = rw;
+        p_msg->client_handle = client_handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendUI
+**
+** Description      This function is called to send data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote link MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSendUI (tNFA_HANDLE handle,
+                           UINT8       dsap,
+                           UINT16      length,
+                           UINT8      *p_data)
+{
+    tNFA_P2P_API_SEND_UI *p_msg;
+    tNFA_STATUS           ret_status = NFA_STATUS_FAILED;
+    tNFA_HANDLE           xx;
+
+    P2P_TRACE_API3 ("NFA_P2pSendUI (): handle:0x%X, DSAP:0x%02X, length:%d", handle, dsap, length);
+
+    GKI_sched_lock ();
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL))
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pSendUI (): Handle (0x%X) is not valid", handle);
+        ret_status = NFA_STATUS_BAD_HANDLE;
+    }
+    else if (length > nfa_p2p_cb.remote_link_miu)
+    {
+        P2P_TRACE_ERROR3 ("NFA_P2pSendUI (): handle:0x%X, length(%d) must be less than remote link MIU(%d)",
+                           handle, length, nfa_p2p_cb.remote_link_miu);
+        ret_status = NFA_STATUS_BAD_LENGTH;
+    }
+    else if (nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED)
+    {
+        P2P_TRACE_WARNING1 ("NFA_P2pSendUI (): handle:0x%X, logical data link is already congested",
+                             handle);
+        ret_status = NFA_STATUS_CONGESTED;
+    }
+    else if (LLCP_IsLogicalLinkCongested ((UINT8)xx,
+                                          nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu,
+                                          nfa_p2p_cb.total_pending_ui_pdu,
+                                          nfa_p2p_cb.total_pending_i_pdu))
+    {
+        nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+
+        P2P_TRACE_WARNING1 ("NFA_P2pSendUI(): handle:0x%X, logical data link is congested",
+                             handle);
+        ret_status = NFA_STATUS_CONGESTED;
+    }
+    else if ((p_msg = (tNFA_P2P_API_SEND_UI *) GKI_getbuf (sizeof(tNFA_P2P_API_SEND_UI))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_SEND_UI_EVT;
+
+        p_msg->handle  = handle;
+        p_msg->dsap    = dsap;
+
+        if ((p_msg->p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+        {
+            p_msg->p_msg->len    = length;
+            p_msg->p_msg->offset = LLCP_MIN_OFFSET;
+            memcpy (((UINT8*) (p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data, length);
+
+            /* increase number of tx UI PDU which is not processed by NFA for congestion control */
+            nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu++;
+            nfa_p2p_cb.total_pending_ui_pdu++;
+            nfa_sys_sendmsg (p_msg);
+
+            ret_status = NFA_STATUS_OK;
+        }
+        else
+        {
+            GKI_freebuf (p_msg);
+
+            nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED;
+            ret_status = NFA_STATUS_CONGESTED;
+        }
+    }
+
+    GKI_sched_unlock ();
+
+    return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadUI
+**
+** Description      This function is called to read data on connectionless
+**                  transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_LLINK_TYPE.
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into p_data.
+**                  - If more information of UI PDU or more UI PDU in queue then more
+**                    is returned to TRUE.
+**                  - Information of next UI PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pReadUI (tNFA_HANDLE handle,
+                           UINT32      max_data_len,
+                           UINT8       *p_remote_sap,
+                           UINT32      *p_data_len,
+                           UINT8       *p_data,
+                           BOOLEAN     *p_more)
+{
+    tNFA_STATUS ret_status;
+    tNFA_HANDLE xx;
+
+    P2P_TRACE_API1 ("NFA_P2pReadUI (): handle:0x%X", handle);
+
+    GKI_sched_lock ();
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pReadUI (): Handle (0x%X) is not valid", handle);
+        ret_status = NFA_STATUS_BAD_HANDLE;
+    }
+    else
+    {
+        *p_more = LLCP_ReadLogicalLinkData ((UINT8)xx,
+                                            max_data_len,
+                                            p_remote_sap,
+                                            p_data_len,
+                                            p_data);
+        ret_status = NFA_STATUS_OK;
+    }
+
+    GKI_sched_unlock ();
+
+    return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushUI
+**
+** Description      This function is called to flush data on connectionless
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pFlushUI (tNFA_HANDLE handle,
+                            UINT32      *p_length)
+{
+    tNFA_STATUS ret_status;
+    tNFA_HANDLE xx;
+
+    P2P_TRACE_API1 ("NFA_P2pReadUI (): handle:0x%X", handle);
+
+    GKI_sched_lock ();
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pFlushUI (): Handle (0x%X) is not valid", handle);
+        ret_status = NFA_STATUS_BAD_HANDLE;
+        *p_length  = 0;
+    }
+    else
+    {
+        *p_length  = LLCP_FlushLogicalLinkRxData ((UINT8)xx);
+        ret_status = NFA_STATUS_OK;
+    }
+
+    GKI_sched_unlock ();
+
+    return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSendData
+**
+** Description      This function is called to send data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_BAD_LENGTH if data length is more than remote MIU
+**                  NFA_STATUS_CONGESTED  if congested
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSendData (tNFA_HANDLE handle,
+                             UINT16      length,
+                             UINT8      *p_data)
+{
+    tNFA_P2P_API_SEND_DATA *p_msg;
+    tNFA_STATUS            ret_status = NFA_STATUS_FAILED;
+    tNFA_HANDLE            xx;
+
+    P2P_TRACE_API2 ("NFA_P2pSendData (): handle:0x%X, length:%d", handle, length);
+
+    GKI_sched_lock ();
+
+    xx = handle & NFA_HANDLE_MASK;
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    if (  (!(handle & NFA_P2P_HANDLE_FLAG_CONN))
+        ||(xx >= LLCP_MAX_DATA_LINK)
+        ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pSendData (): Handle(0x%X) is not valid", handle);
+        ret_status = NFA_STATUS_BAD_HANDLE;
+    }
+    else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO)
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pSendData (): handle:0x%X, Remote set RW to 0 (flow off)", handle);
+        ret_status = NFA_STATUS_FAILED;
+    }
+    else if (nfa_p2p_cb.conn_cb[xx].remote_miu < length)
+    {
+        P2P_TRACE_ERROR2 ("NFA_P2pSendData (): handle:0x%X, Data more than remote MIU(%d)",
+                           handle, nfa_p2p_cb.conn_cb[xx].remote_miu);
+        ret_status = NFA_STATUS_BAD_LENGTH;
+    }
+    else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED)
+    {
+        P2P_TRACE_WARNING1 ("NFA_P2pSendData (): handle:0x%X, data link connection is already congested",
+                            handle);
+        ret_status = NFA_STATUS_CONGESTED;
+    }
+    else if (LLCP_IsDataLinkCongested (nfa_p2p_cb.conn_cb[xx].local_sap,
+                                       nfa_p2p_cb.conn_cb[xx].remote_sap,
+                                       nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu,
+                                       nfa_p2p_cb.total_pending_ui_pdu,
+                                       nfa_p2p_cb.total_pending_i_pdu))
+    {
+        nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+
+        P2P_TRACE_WARNING1 ("NFA_P2pSendData (): handle:0x%X, data link connection is congested",
+                            handle);
+        ret_status = NFA_STATUS_CONGESTED;
+    }
+    else if ((p_msg = (tNFA_P2P_API_SEND_DATA *) GKI_getbuf (sizeof(tNFA_P2P_API_SEND_DATA))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_SEND_DATA_EVT;
+
+        p_msg->conn_handle  = handle;
+
+        if ((p_msg->p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+        {
+            p_msg->p_msg->len    = length;
+            p_msg->p_msg->offset = LLCP_MIN_OFFSET;
+            memcpy (((UINT8*) (p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data, length);
+
+            /* increase number of tx I PDU which is not processed by NFA for congestion control */
+            nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu++;
+            nfa_p2p_cb.total_pending_i_pdu++;
+            nfa_sys_sendmsg (p_msg);
+
+            ret_status = NFA_STATUS_OK;
+        }
+        else
+        {
+            GKI_freebuf (p_msg);
+            nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED;
+            ret_status = NFA_STATUS_CONGESTED;
+        }
+    }
+
+    GKI_sched_unlock ();
+
+    return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pReadData
+**
+** Description      This function is called to read data on connection-oriented
+**                  transport when receiving NFA_P2P_DATA_EVT with NFA_P2P_DLINK_TYPE.
+**
+**                  - Information of I PDU is copied into p_data up to max_data_len.
+**                  - If more information of I PDU or more I PDU in queue, then more
+**                    is returned to TRUE.
+**                  - Information of next I PDU is not concatenated.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pReadData (tNFA_HANDLE handle,
+                             UINT32      max_data_len,
+                             UINT32      *p_data_len,
+                             UINT8       *p_data,
+                             BOOLEAN     *p_more)
+{
+    tNFA_STATUS ret_status;
+    tNFA_HANDLE xx;
+
+    P2P_TRACE_API1 ("NFA_P2pReadData (): handle:0x%X", handle);
+
+    GKI_sched_lock ();
+
+    xx = handle & NFA_HANDLE_MASK;
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    if (  (!(handle & NFA_P2P_HANDLE_FLAG_CONN))
+        ||(xx >= LLCP_MAX_DATA_LINK)
+        ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pReadData (): Handle(0x%X) is not valid", handle);
+        ret_status = NFA_STATUS_BAD_HANDLE;
+    }
+    else
+    {
+        *p_more = LLCP_ReadDataLinkData (nfa_p2p_cb.conn_cb[xx].local_sap,
+                                         nfa_p2p_cb.conn_cb[xx].remote_sap,
+                                         max_data_len,
+                                         p_data_len,
+                                         p_data);
+        ret_status = NFA_STATUS_OK;
+    }
+
+    GKI_sched_unlock ();
+
+    return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pFlushData
+**
+** Description      This function is called to flush data on connection-oriented
+**                  transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pFlushData (tNFA_HANDLE handle,
+                              UINT32      *p_length)
+{
+    tNFA_STATUS ret_status;
+    tNFA_HANDLE xx;
+
+    P2P_TRACE_API1 ("NFA_P2pFlushData (): handle:0x%X", handle);
+
+    GKI_sched_lock ();
+
+    xx = handle & NFA_HANDLE_MASK;
+    xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+
+    if (  (!(handle & NFA_P2P_HANDLE_FLAG_CONN))
+        ||(xx >= LLCP_MAX_DATA_LINK)
+        ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+    {
+        P2P_TRACE_ERROR1 ("NFA_P2pFlushData (): Handle(0x%X) is not valid", handle);
+        ret_status = NFA_STATUS_BAD_HANDLE;
+    }
+    else
+    {
+        *p_length = LLCP_FlushDataLinkRxData (nfa_p2p_cb.conn_cb[xx].local_sap,
+                                              nfa_p2p_cb.conn_cb[xx].remote_sap);
+        ret_status = NFA_STATUS_OK;
+    }
+
+    GKI_sched_unlock ();
+
+    return (ret_status);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLocalBusy
+**
+** Description      This function is called to stop or resume incoming data on
+**                  connection-oriented transport.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSetLocalBusy (tNFA_HANDLE conn_handle,
+                                 BOOLEAN     is_busy)
+{
+    tNFA_P2P_API_SET_LOCAL_BUSY *p_msg;
+    tNFA_HANDLE                  xx;
+
+    P2P_TRACE_API2 ("NFA_P2pSetLocalBusy (): conn_handle:0x%02X, is_busy:%d", conn_handle, is_busy);
+
+    xx = conn_handle & NFA_HANDLE_MASK;
+
+    if (!(xx & NFA_P2P_HANDLE_FLAG_CONN))
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+    else
+    {
+        xx &= ~NFA_P2P_HANDLE_FLAG_CONN;
+    }
+
+    if (  (xx >= LLCP_MAX_DATA_LINK)
+        ||(nfa_p2p_cb.conn_cb[xx].flags == 0)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pSetLocalBusy (): Connection Handle is not valid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_SET_LOCAL_BUSY *) GKI_getbuf (sizeof (tNFA_P2P_API_SET_LOCAL_BUSY))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_SET_LOCAL_BUSY_EVT;
+
+        p_msg->conn_handle = conn_handle;
+        p_msg->is_busy     = is_busy;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLinkInfo
+**
+** Description      This function is called to get local/remote link MIU and
+**                  Well-Known Service list encoded as a 16-bit field of connected LLCP.
+**                  NFA_P2P_LINK_INFO_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pGetLinkInfo (tNFA_HANDLE handle)
+{
+    tNFA_P2P_API_GET_LINK_INFO *p_msg;
+    tNFA_HANDLE                 xx;
+
+    P2P_TRACE_API1 ("NFA_P2pGetLinkInfo (): handle:0x%x", handle);
+
+    if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pGetLinkInfo (): LLCP link is not activated");
+        return (NFA_STATUS_FAILED);
+    }
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pGetLinkInfo (): Handle is invalid or not registered");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_GET_LINK_INFO *) GKI_getbuf (sizeof (tNFA_P2P_API_GET_LINK_INFO))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_GET_LINK_INFO_EVT;
+
+        p_msg->handle = handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetRemoteSap
+**
+** Description      This function is called to get SAP associated by service name
+**                  on connected remote LLCP.
+**                  NFA_P2P_SDP_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if server or client is not registered
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pGetRemoteSap (tNFA_HANDLE handle,
+                                 char        *p_service_name)
+{
+    tNFA_P2P_API_GET_REMOTE_SAP *p_msg;
+    tNFA_HANDLE                  xx;
+
+    P2P_TRACE_API2 ("NFA_P2pGetRemoteSap(): handle:0x%x, SN:<%s>", handle, p_service_name);
+
+    if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED)
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pGetRemoteSap(): LLCP link is not activated");
+        return (NFA_STATUS_FAILED);
+    }
+
+    xx = handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_P2P_NUM_SAP)
+        ||(nfa_p2p_cb.sap_cb[xx].p_cback == NULL)  )
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pGetRemoteSap (): Handle is invalid or not registered");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_GET_REMOTE_SAP *) GKI_getbuf (sizeof (tNFA_P2P_API_GET_REMOTE_SAP))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_GET_REMOTE_SAP_EVT;
+
+        p_msg->handle = handle;
+
+        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name), p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetLLCPConfig
+**
+** Description      This function is called to change LLCP config parameters.
+**                  Application must call while LLCP is not activated.
+**
+**                  Parameters descriptions (default value)
+**                  - Local Link MIU (LLCP_MIU)
+**                  - Option parameter (LLCP_OPT_VALUE)
+**                  - Response Waiting Time Index (LLCP_WAITING_TIME)
+**                  - Local Link Timeout (LLCP_LTO_VALUE)
+**                  - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT)
+**                  - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT)
+**                  - Delay SYMM response (LLCP_DELAY_RESP_TIME)
+**                  - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT)
+**                  - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_P2pSetLLCPConfig (UINT16 link_miu,
+                                  UINT8  opt,
+                                  UINT8  wt,
+                                  UINT16 link_timeout,
+                                  UINT16 inact_timeout_init,
+                                  UINT16 inact_timeout_target,
+                                  UINT16 symm_delay,
+                                  UINT16 data_link_timeout,
+                                  UINT16 delay_first_pdu_timeout)
+{
+    tNFA_P2P_API_SET_LLCP_CFG *p_msg;
+
+    P2P_TRACE_API4 ("NFA_P2pSetLLCPConfig ():link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+                     link_miu, opt, wt, link_timeout);
+    P2P_TRACE_API4 ("                       inact_timeout(init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
+                     inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
+    P2P_TRACE_API1 ("                       delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
+
+    if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED)
+    {
+        P2P_TRACE_ERROR0 ("NFA_P2pSetLLCPConfig (): LLCP link is activated");
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_P2P_API_SET_LLCP_CFG *) GKI_getbuf (sizeof (tNFA_P2P_API_SET_LLCP_CFG))) != NULL)
+    {
+        p_msg->hdr.event = NFA_P2P_API_SET_LLCP_CFG_EVT;
+
+        p_msg->link_miu             = link_miu;
+        p_msg->opt                  = opt;
+        p_msg->wt                   = wt;
+        p_msg->link_timeout         = link_timeout;
+        p_msg->inact_timeout_init   = inact_timeout_init;
+        p_msg->inact_timeout_target = inact_timeout_target;
+        p_msg->symm_delay           = symm_delay;
+        p_msg->data_link_timeout    = data_link_timeout;
+        p_msg->delay_first_pdu_timeout = delay_first_pdu_timeout;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pGetLLCPConfig
+**
+** Description      This function is called to read LLCP config parameters.
+**
+**                  Parameters descriptions
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          None
+**
+*******************************************************************************/
+void NFA_P2pGetLLCPConfig (UINT16 *p_link_miu,
+                           UINT8  *p_opt,
+                           UINT8  *p_wt,
+                           UINT16 *p_link_timeout,
+                           UINT16 *p_inact_timeout_init,
+                           UINT16 *p_inact_timeout_target,
+                           UINT16 *p_symm_delay,
+                           UINT16 *p_data_link_timeout,
+                           UINT16 *p_delay_first_pdu_timeout)
+{
+    LLCP_GetConfig (p_link_miu,
+                    p_opt,
+                    p_wt,
+                    p_link_timeout,
+                    p_inact_timeout_init,
+                    p_inact_timeout_target,
+                    p_symm_delay,
+                    p_data_link_timeout,
+                    p_delay_first_pdu_timeout);
+
+    P2P_TRACE_API4 ("NFA_P2pGetLLCPConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+                     *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
+    P2P_TRACE_API4 ("                       inact_timeout(init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
+                     *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
+    P2P_TRACE_API1 ("                       delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
+
+}
+
+/*******************************************************************************
+**
+** Function         NFA_P2pSetTraceLevel
+**
+** Description      This function sets the trace level for P2P.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFA_P2pSetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        nfa_p2p_cb.trace_level = new_level;
+
+    return (nfa_p2p_cb.trace_level);
+}
+
diff --git a/src/nfa/p2p/nfa_p2p_main.c b/src/nfa/p2p/nfa_p2p_main.c
new file mode 100644
index 0000000..f8bca03
--- /dev/null
+++ b/src/nfa/p2p/nfa_p2p_main.c
@@ -0,0 +1,630 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA P2P.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_dm_int.h"
+#include "llcp_api.h"
+#include "llcp_defs.h"
+#include "nfa_p2p_api.h"
+#include "nfa_p2p_int.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_P2P_CB nfa_p2p_cb;
+#endif
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_msg);
+
+/* disable function type */
+static void nfa_p2p_sys_disable (void);
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_p2p_llcp_state_code (tNFA_P2P_LLCP_STATE state_code);
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_p2p_sys_reg =
+{
+    NULL,
+    nfa_p2p_evt_hdlr,
+    nfa_p2p_sys_disable,
+    NULL
+};
+
+#define NFA_P2P_NUM_ACTIONS  (NFA_P2P_LAST_EVT & 0x00ff)
+
+/* type for action functions */
+typedef BOOLEAN (*tNFA_P2P_ACTION) (tNFA_P2P_MSG *p_data);
+
+/* action function list */
+const tNFA_P2P_ACTION nfa_p2p_action[] =
+{
+    nfa_p2p_reg_server,                     /* NFA_P2P_API_REG_SERVER_EVT       */
+    nfa_p2p_reg_client,                     /* NFA_P2P_API_REG_CLIENT_EVT       */
+    nfa_p2p_dereg,                          /* NFA_P2P_API_DEREG_EVT            */
+    nfa_p2p_accept_connection,              /* NFA_P2P_API_ACCEPT_CONN_EVT      */
+    nfa_p2p_reject_connection,              /* NFA_P2P_API_REJECT_CONN_EVT      */
+    nfa_p2p_disconnect,                     /* NFA_P2P_API_DISCONNECT_EVT       */
+    nfa_p2p_create_data_link_connection,    /* NFA_P2P_API_CONNECT_EVT          */
+    nfa_p2p_send_ui,                        /* NFA_P2P_API_SEND_UI_EVT          */
+    nfa_p2p_send_data,                      /* NFA_P2P_API_SEND_DATA_EVT        */
+    nfa_p2p_set_local_busy,                 /* NFA_P2P_API_SET_LOCAL_BUSY_EVT   */
+    nfa_p2p_get_link_info,                  /* NFA_P2P_API_GET_LINK_INFO_EVT    */
+    nfa_p2p_get_remote_sap,                 /* NFA_P2P_API_GET_REMOTE_SAP_EVT   */
+    nfa_p2p_set_llcp_cfg                    /* NFA_P2P_API_SET_LLCP_CFG_EVT     */
+};
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_discovery_cback
+**
+** Description      Processing event from discovery callback for listening
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_discovery_cback (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data)
+{
+    tNFA_CONN_EVT_DATA evt_data;
+
+    P2P_TRACE_DEBUG1 ("nfa_p2p_discovery_cback (): event:0x%02X", event);
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISC_START_EVT:
+        if (p_data->status == NFC_STATUS_OK)
+        {
+            nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_LISTENING;
+        }
+        break;
+
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+
+        /* notify NFC link activation */
+        memcpy (&(evt_data.activated.activate_ntf),
+                &(p_data->activate),
+                sizeof (tNFC_ACTIVATE_DEVT));
+        nfa_dm_conn_cback_event_notify (NFA_ACTIVATED_EVT, &evt_data);
+
+        if ((p_data->activate.protocol        == NFC_PROTOCOL_NFC_DEP)
+          &&(p_data->activate.intf_param.type == NFC_INTERFACE_NFC_DEP))
+        {
+            nfa_p2p_activate_llcp (p_data);
+        }
+        break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+
+        /* notify deactivation */
+        if (  (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP)
+            ||(p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)  )
+        {
+            evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
+        }
+        else
+        {
+            evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        }
+        nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+        break;
+
+    case NFA_DM_RF_DISC_CMD_IDLE_CMPL_EVT:
+        /* DH initiated deactivation in NFA_DM_RFST_LISTEN_SLEEP */
+        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
+        nfa_dm_conn_cback_event_notify (NFA_DEACTIVATED_EVT, &evt_data);
+        break;
+
+    default:
+        P2P_TRACE_ERROR0 ("Unexpected event");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_llcp_link_cback
+**
+** Description      Processing event from LLCP link management callback
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_llcp_link_cback (UINT8 event, UINT8 reason)
+{
+    tNFA_LLCP_ACTIVATED     llcp_activated;
+    tNFA_LLCP_DEACTIVATED   llcp_deactivated;
+
+    P2P_TRACE_DEBUG1 ("nfa_p2p_llcp_link_cback () event:0x%x", event);
+
+    if (event == LLCP_LINK_ACTIVATION_COMPLETE_EVT)
+    {
+        LLCP_GetLinkMIU (&nfa_p2p_cb.local_link_miu, &nfa_p2p_cb.remote_link_miu);
+        nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_ACTIVATED;
+
+        if (nfa_p2p_cb.is_initiator)
+        {
+            /* notify NFA DM to send Activate Event to applicaiton with status  */
+            nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
+        }
+
+        llcp_activated.is_initiator    = nfa_p2p_cb.is_initiator;
+        llcp_activated.local_link_miu  = nfa_p2p_cb.local_link_miu;
+        llcp_activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
+        llcp_activated.remote_lsc      = LLCP_GetRemoteLSC ();
+        llcp_activated.remote_wks      = LLCP_GetRemoteWKS ();
+
+        nfa_dm_act_conn_cback_notify (NFA_LLCP_ACTIVATED_EVT, (tNFA_CONN_EVT_DATA *) &llcp_activated);
+
+    }
+    else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT)
+    {
+        nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+
+        if (nfa_p2p_cb.is_initiator)
+        {
+            /* notify NFA DM to send Activate Event to applicaiton with status  */
+            nfa_dm_notify_activation_status (NFA_STATUS_FAILED, NULL);
+        }
+
+        nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+    }
+    else /* LLCP_LINK_DEACTIVATED_EVT       */
+    {
+        nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+
+        llcp_deactivated.reason = reason;
+        nfa_dm_act_conn_cback_notify (NFA_LLCP_DEACTIVATED_EVT, (tNFA_CONN_EVT_DATA *)&llcp_deactivated);
+
+        if (  (nfa_p2p_cb.is_initiator)
+            &&(reason != LLCP_LINK_RF_LINK_LOSS_ERR)  ) /* if NFC link is still up */
+        {
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_activate_llcp
+**
+** Description      Activate LLCP link
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_activate_llcp (tNFC_DISCOVER *p_data)
+{
+    tLLCP_ACTIVATE_CONFIG config;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_activate_llcp ()");
+
+    if (  (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)
+        ||(p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F)
+        ||(p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE)
+        ||(p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)  )
+    {
+        config.is_initiator = TRUE;
+    }
+    else
+    {
+        config.is_initiator = FALSE;
+    }
+
+    nfa_p2p_cb.is_initiator = config.is_initiator;
+
+    config.max_payload_size = p_data->activate.intf_param.intf_param.pa_nfc.max_payload_size;
+    config.waiting_time     = p_data->activate.intf_param.intf_param.pa_nfc.waiting_time;
+    config.p_gen_bytes      = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes;
+    config.gen_bytes_len    = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes_len;
+
+    LLCP_ActivateLink (config, nfa_p2p_llcp_link_cback);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_deactivate_llcp
+**
+** Description      Deactivate LLCP link
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_deactivate_llcp (void)
+{
+    P2P_TRACE_DEBUG0 ("nfa_p2p_deactivate_llcp ()");
+
+    LLCP_DeactivateLink ();
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_init
+**
+** Description      Initialize NFA P2P
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_p2p_init (void)
+{
+    UINT8 xx;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_init ()");
+
+    /* initialize control block */
+    memset (&nfa_p2p_cb, 0, sizeof (tNFA_P2P_CB));
+    nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+    nfa_p2p_cb.trace_level    = APPL_INITIAL_TRACE_LEVEL;
+
+    for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++)
+    {
+        nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
+    }
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register (NFA_ID_P2P,  &nfa_p2p_sys_reg);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_sys_disable
+**
+** Description      Deregister NFA P2P from NFA SYS/DM
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_p2p_sys_disable (void)
+{
+    P2P_TRACE_DEBUG0 ("nfa_p2p_sys_disable()");
+
+    /* deregister message handler on NFA SYS */
+    nfa_sys_deregister (NFA_ID_P2P);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_set_config
+**
+** Description      Set General bytes and WT parameters for LLCP
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_set_config (tNFA_DM_DISC_TECH_PROTO_MASK disc_mask)
+{
+    UINT8 wt, gen_bytes_len = LLCP_MAX_GEN_BYTES;
+    UINT8 params[LLCP_MAX_GEN_BYTES + 5], *p, length;
+
+    P2P_TRACE_DEBUG0 ("nfa_p2p_set_config ()");
+
+    LLCP_GetDiscoveryConfig (&wt, params + 2, &gen_bytes_len);
+
+    if (disc_mask & ( NFA_DM_DISC_MASK_PA_NFC_DEP
+                     |NFA_DM_DISC_MASK_PF_NFC_DEP
+                     |NFA_DM_DISC_MASK_PAA_NFC_DEP
+                     |NFA_DM_DISC_MASK_PFA_NFC_DEP) )
+    {
+        p = params;
+
+        UINT8_TO_BE_STREAM (p, NFC_PMID_ATR_REQ_GEN_BYTES);
+        UINT8_TO_BE_STREAM (p, gen_bytes_len);
+
+        p += gen_bytes_len;
+        length = gen_bytes_len + 2;
+
+        nfa_dm_check_set_config (length, params, FALSE);
+    }
+
+    if (disc_mask & ( NFA_DM_DISC_MASK_LA_NFC_DEP
+                     |NFA_DM_DISC_MASK_LF_NFC_DEP
+                     |NFA_DM_DISC_MASK_LAA_NFC_DEP
+                     |NFA_DM_DISC_MASK_LFA_NFC_DEP) )
+    {
+        p = params;
+
+        UINT8_TO_BE_STREAM (p, NFC_PMID_ATR_RES_GEN_BYTES);
+        UINT8_TO_BE_STREAM (p, gen_bytes_len);
+
+        p += gen_bytes_len;
+        length = gen_bytes_len + 2;
+
+        UINT8_TO_BE_STREAM (p, NFC_PMID_WT);
+        UINT8_TO_BE_STREAM (p, NCI_PARAM_LEN_WT);
+        UINT8_TO_BE_STREAM (p, wt);
+
+        length += 3;
+
+        nfa_dm_check_set_config (length, params, FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_enable_listening
+**
+** Description      Configure listen technologies and protocols for LLCP
+**                  If LLCP WKS is changed then LLCP Gen bytes will be updated.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_enable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks)
+{
+    tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
+
+    P2P_TRACE_DEBUG2 ("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d",
+                       sys_id, update_wks);
+
+    if (sys_id == NFA_ID_P2P)
+        nfa_p2p_cb.is_p2p_listening = TRUE;
+    else if (sys_id == NFA_ID_CHO)
+        nfa_p2p_cb.is_cho_listening = TRUE;
+    else if (sys_id == NFA_ID_SNEP)
+        nfa_p2p_cb.is_snep_listening = TRUE;
+
+    if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
+    {
+        /* if need to update WKS in LLCP Gen bytes */
+        if (update_wks)
+        {
+            /* update LLCP Gen Bytes */
+            nfa_p2p_set_config (NFA_DM_DISC_MASK_PA_NFC_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP);
+        }
+        return;
+    }
+
+    /* collect listen technologies with NFC-DEP protocol */
+    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
+        p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
+
+    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
+        p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
+
+    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
+        p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
+
+    if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
+        p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
+
+    if (p2p_listen_mask)
+    {
+        /* Configure listen technologies and protocols and register callback to NFA DM discovery */
+        nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover (p2p_listen_mask,
+                                                            NFA_DM_DISC_HOST_ID_DH,
+                                                            nfa_p2p_discovery_cback);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_disable_listening
+**
+** Description      Remove listen technologies and protocols for LLCP and
+**                  deregister callback from NFA DM discovery if all of P2P/CHO/SNEP
+**                  doesn't listen LLCP any more.
+**                  If LLCP WKS is changed then ATR_RES will be updated.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_disable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks)
+{
+
+    P2P_TRACE_DEBUG2 ("nfa_p2p_disable_listening ()  sys_id = %d, update_wks = %d",
+                       sys_id, update_wks);
+
+    if (sys_id == NFA_ID_P2P)
+        nfa_p2p_cb.is_p2p_listening = FALSE;
+    else if (sys_id == NFA_ID_CHO)
+        nfa_p2p_cb.is_cho_listening = FALSE;
+    else if (sys_id == NFA_ID_SNEP)
+        nfa_p2p_cb.is_snep_listening = FALSE;
+
+    if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
+    {
+        if (  (nfa_p2p_cb.is_p2p_listening == FALSE)
+            &&(nfa_p2p_cb.is_cho_listening == FALSE)
+            &&(nfa_p2p_cb.is_snep_listening == FALSE)  )
+        {
+            nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
+
+            nfa_dm_delete_rf_discover (nfa_p2p_cb.dm_disc_handle);
+            nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+        }
+        else if (update_wks)
+        {
+            /* update LLCP Gen Bytes */
+            nfa_p2p_set_config (NFA_DM_DISC_MASK_PA_NFC_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_update_listen_tech
+**
+** Description      Update P2P listen technologies. If there is change then
+**                  restart or stop P2P listen.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_p2p_update_listen_tech (tNFA_TECHNOLOGY_MASK tech_mask)
+{
+    P2P_TRACE_DEBUG1 ("nfa_p2p_update_listen_tech ()  tech_mask = %d", tech_mask);
+
+    if (nfa_p2p_cb.listen_tech_mask != tech_mask)
+    {
+        nfa_p2p_cb.listen_tech_mask = tech_mask;
+
+        if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
+        {
+            nfa_dm_delete_rf_discover (nfa_p2p_cb.dm_disc_handle);
+            nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
+        }
+
+        /* restart discovery without updating sub-module status */
+        if (nfa_p2p_cb.is_p2p_listening)
+            nfa_p2p_enable_listening (NFA_ID_P2P, FALSE);
+        else if (nfa_p2p_cb.is_cho_listening)
+            nfa_p2p_enable_listening (NFA_ID_CHO, FALSE);
+        else if (nfa_p2p_cb.is_snep_listening)
+            nfa_p2p_enable_listening (NFA_ID_SNEP, FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_evt_hdlr
+**
+** Description      Processing event for NFA P2P
+**
+**
+** Returns          TRUE if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_hdr)
+{
+    BOOLEAN delete_msg = TRUE;
+    UINT16  event;
+
+    tNFA_P2P_MSG *p_msg = (tNFA_P2P_MSG *)p_hdr;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]",
+                       nfa_p2p_llcp_state_code (nfa_p2p_cb.llcp_state),
+                       nfa_p2p_evt_code (p_msg->hdr.event));
+#else
+    P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x",
+                       nfa_p2p_cb.llcp_state, p_msg->hdr.event);
+#endif
+
+    event = p_msg->hdr.event & 0x00ff;
+
+    /* execute action functions */
+    if (event < NFA_P2P_NUM_ACTIONS)
+    {
+        delete_msg = (*nfa_p2p_action[event]) (p_msg);
+    }
+    else
+    {
+        P2P_TRACE_ERROR0 ("Unhandled event");
+    }
+
+    return delete_msg;
+}
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_p2p_llcp_state_code
+**
+** Description
+**
+** Returns          string of state
+**
+*******************************************************************************/
+static char *nfa_p2p_llcp_state_code (tNFA_P2P_LLCP_STATE state_code)
+{
+    switch (state_code)
+    {
+    case NFA_P2P_LLCP_STATE_IDLE:
+        return "Link IDLE";
+    case NFA_P2P_LLCP_STATE_LISTENING:
+        return "Link LISTENING";
+    case NFA_P2P_LLCP_STATE_ACTIVATED:
+        return "Link ACTIVATED";
+    default:
+        return "Unknown state";
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_p2p_evt_code
+**
+** Description
+**
+** Returns          string of event
+**
+*******************************************************************************/
+char *nfa_p2p_evt_code (UINT16 evt_code)
+{
+    switch (evt_code)
+    {
+    case NFA_P2P_API_REG_SERVER_EVT:
+        return "API_REG_SERVER";
+    case NFA_P2P_API_REG_CLIENT_EVT:
+        return "API_REG_CLIENT";
+    case NFA_P2P_API_DEREG_EVT:
+        return "API_DEREG";
+    case NFA_P2P_API_ACCEPT_CONN_EVT:
+        return "API_ACCEPT_CONN";
+    case NFA_P2P_API_REJECT_CONN_EVT:
+        return "API_REJECT_CONN";
+    case NFA_P2P_API_DISCONNECT_EVT:
+        return "API_DISCONNECT";
+    case NFA_P2P_API_CONNECT_EVT:
+        return "API_CONNECT";
+    case NFA_P2P_API_SEND_UI_EVT:
+        return "API_SEND_UI";
+    case NFA_P2P_API_SEND_DATA_EVT:
+        return "API_SEND_DATA";
+    case NFA_P2P_API_SET_LOCAL_BUSY_EVT:
+        return "API_SET_LOCAL_BUSY";
+    case NFA_P2P_API_GET_LINK_INFO_EVT:
+        return "API_GET_LINK_INFO";
+    case NFA_P2P_API_GET_REMOTE_SAP_EVT:
+        return "API_GET_REMOTE_SAP";
+    case NFA_P2P_API_SET_LLCP_CFG_EVT:
+        return "API_SET_LLCP_CFG_EVT";
+    default:
+        return "Unknown event";
+    }
+}
+#endif  /* Debug Functions */
diff --git a/src/nfa/rw/nfa_rw_act.c b/src/nfa/rw/nfa_rw_act.c
new file mode 100644
index 0000000..e9f4eef
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_act.c
@@ -0,0 +1,2776 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the action functions the NFA_RW state machine.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_rw_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+#include "nfa_mem_co.h"
+#include "ndef_utils.h"
+#include "rw_api.h"
+
+/* Local static function prototypes */
+static tNFC_STATUS nfa_rw_start_ndef_read(void);
+static tNFC_STATUS nfa_rw_start_ndef_write(void);
+static tNFC_STATUS nfa_rw_start_ndef_detection(void);
+static tNFC_STATUS nfa_rw_config_tag_ro(BOOLEAN b_hard_lock);
+static BOOLEAN     nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data);
+static void        nfa_rw_error_cleanup (UINT8 event);
+
+/*******************************************************************************
+**
+** Function         nfa_rw_free_ndef_rx_buf
+**
+** Description      Free buffer allocated to hold incoming NDEF message
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_free_ndef_rx_buf(void)
+{
+    if (nfa_rw_cb.p_ndef_buf)
+    {
+        nfa_mem_co_free(nfa_rw_cb.p_ndef_buf);
+        nfa_rw_cb.p_ndef_buf = NULL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_store_ndef_rx_buf
+**
+** Description      Store data into NDEF buffer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_store_ndef_rx_buf (tRW_DATA *p_rw_data)
+{
+    UINT8      *p;
+
+    p = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
+
+    /* Save data into buffer */
+    memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p, p_rw_data->data.p_data->len);
+    nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len;
+
+    GKI_freebuf(p_rw_data->data.p_data);
+    p_rw_data->data.p_data = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_send_data_to_upper
+**
+** Description      Send data to upper layer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_send_data_to_upper (tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    if (  (p_rw_data->status == NFC_STATUS_TIMEOUT)
+        ||(p_rw_data->data.p_data == NULL) )
+        return;
+
+    /* Notify conn cback of NFA_DATA_EVT */
+    conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
+    conn_evt_data.data.len    = p_rw_data->data.p_data->len;
+
+    nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
+
+    GKI_freebuf(p_rw_data->data.p_data);
+    p_rw_data->data.p_data = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_error_cleanup
+**
+** Description      Handle failure - signal command complete and notify app
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_error_cleanup (UINT8 event)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    nfa_rw_command_complete();
+
+    conn_evt_data.status = NFA_STATUS_FAILED;
+
+    nfa_dm_act_conn_cback_notify (event, &conn_evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_check_start_presence_check_timer
+**
+** Description      Start timer for presence check
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_check_start_presence_check_timer (void)
+{
+#if (defined (NFA_DM_AUTO_PRESENCE_CHECK) && (NFA_DM_AUTO_PRESENCE_CHECK == TRUE))
+    if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE)
+    {
+        NFA_TRACE_DEBUG0("Starting presence check timer...");
+        nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT, NFA_RW_PRESENCE_CHECK_INTERVAL);
+    }
+#endif   /* NFA_DM_AUTO_PRESENCE_CHECK  */
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_stop_presence_check_timer
+**
+** Description      Stop timer for presence check
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_stop_presence_check_timer(void)
+{
+    nfa_sys_stop_timer(&nfa_rw_cb.tle);
+    NFA_TRACE_DEBUG0("Stopped presence check timer (if started)");
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_ndef_detect
+**
+** Description      Handler for NDEF detection reader/writer event
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_ndef_detect(tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    NFA_TRACE_DEBUG3("NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x",
+        p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size, p_rw_data->ndef.flags);
+
+    /* Check if NDEF detection succeeded */
+    if (p_rw_data->ndef.status == NFC_STATUS_OK)
+    {
+        /* Set NDEF detection state */
+        nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE;
+
+        /* Store ndef properties */
+        conn_evt_data.ndef_detect.status = NFA_STATUS_OK;
+        conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
+        conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
+        conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
+        conn_evt_data.ndef_detect.flags    = p_rw_data->ndef.flags;
+
+        if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY)
+            nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
+        else
+            nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY;
+
+        /* Determine what operation triggered the NDEF detection procedure */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            /* if ndef detection was done as part of ndef-read operation, then perform ndef read now */
+            if ((conn_evt_data.status = nfa_rw_start_ndef_read()) != NFA_STATUS_OK)
+            {
+                /* Failed to start NDEF Read */
+
+                /* Command complete - perform cleanup, notify app */
+                nfa_rw_command_complete();
+                nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+            }
+        }
+        else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* if ndef detection was done as part of ndef-write operation, then perform ndef write now */
+            if ((conn_evt_data.status = nfa_rw_start_ndef_write()) != NFA_STATUS_OK)
+            {
+                /* Failed to start NDEF Write.  */
+
+                /* Command complete - perform cleanup, notify app */
+                nfa_rw_command_complete();
+                nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+            }
+        }
+        else
+        {
+            /* current op was stand-alone NFA_DetectNDef. Command complete - perform cleanup and notify app */
+            nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+            nfa_rw_command_complete();
+
+            nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+        }
+    }
+    else
+    {
+        /* NDEF detection failed... */
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
+
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            /* if ndef detection was done as part of ndef-read operation, then notify NDEF handlers of failure */
+            nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+            /* Notify app of read status */
+            conn_evt_data.status = NFC_STATUS_FAILED;
+            nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        }
+        else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* if ndef detection was done as part of ndef-write operation, then notify app of failure */
+            conn_evt_data.status = NFA_STATUS_FAILED;
+            nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        }
+        else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF)
+        {
+            conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
+            /* current op was stand-alone NFA_DetectNDef. Notify app of failure */
+            conn_evt_data.ndef_detect.status = NFA_STATUS_FAILED;
+            if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT)
+            {
+                /* Tag could have moved away */
+                conn_evt_data.ndef_detect.cur_size = 0;
+                conn_evt_data.ndef_detect.max_size = 0;
+                conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
+            }
+            else
+            {
+                /* NDEF Detection failed for other reasons */
+                conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
+                conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
+                conn_evt_data.ndef_detect.flags    = p_rw_data->ndef.flags;
+            }
+            nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+        }
+
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_tlv_detect
+**
+** Description      Handler for TLV detection reader/writer event
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    /* Set TLV detection state */
+    if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
+    {
+        if(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
+        {
+            nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
+        }
+        else
+        {
+            nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+        }
+    }
+    else
+    {
+        if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV)
+        {
+            nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
+        }
+        else if(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV)
+        {
+            nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE;
+        }
+    }
+
+    /* Check if TLV detection succeeded */
+    if (p_rw_data->tlv.status == NFC_STATUS_OK)
+    {
+        NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",p_rw_data->tlv.num_bytes);
+
+        /* Store tlv properties */
+        conn_evt_data.tlv_detect.status     = NFA_STATUS_OK;
+        conn_evt_data.tlv_detect.protocol   = p_rw_data->tlv.protocol;
+        conn_evt_data.tlv_detect.num_bytes  = p_rw_data->tlv.num_bytes;
+
+
+        /* Determine what operation triggered the TLV detection procedure */
+        if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
+        {
+            if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK)
+            {
+                /* Failed to set tag read only */
+                conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+                nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+            }
+        }
+        else
+        {
+            /* current op was stand-alone NFA_DetectTlv. Command complete - perform cleanup and notify app */
+            nfa_rw_command_complete();
+            nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
+        }
+    }
+
+    /* Handle failures */
+    if (p_rw_data->tlv.status != NFC_STATUS_OK)
+    {
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+
+        conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+        if(  (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV)
+           ||(nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) )
+        {
+            nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
+        }
+        else if(nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO)
+        {
+            if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK)
+            {
+                /* Failed to set tag read only */
+                conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
+                nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+            }
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_presence_check_rsp
+**
+** Description      Handler RW_T#t_PRESENCE_CHECK_EVT
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_handle_presence_check_rsp (tNFC_STATUS status)
+{
+    BT_HDR *p_pending_msg;
+
+    if (status == NFA_STATUS_OK)
+    {
+        /* Clear the BUSY flag and restart the presence-check timer */
+        nfa_rw_command_complete();
+    }
+    else
+    {
+        /* If presence check failed just clear the BUSY flag */
+        nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
+    }
+
+    /* Handle presence check due to auto-presence-check  */
+    if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY)
+    {
+        nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
+
+        /* If an API was called during auto-presence-check, then handle it now */
+        if (nfa_rw_cb.p_pending_msg)
+        {
+            /* If NFA_RwPresenceCheck was called during auto-presence-check, notify app of result */
+            if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK)
+            {
+                /* Notify app of presence check status */
+                nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status);
+                GKI_freebuf(nfa_rw_cb.p_pending_msg);
+                nfa_rw_cb.p_pending_msg = NULL;
+            }
+            /* For all other APIs called during auto-presence check, perform the command now (if tag is still present) */
+            else if (status == NFC_STATUS_OK)
+            {
+                NFA_TRACE_DEBUG0("Performing deferred operation after presence check...");
+                p_pending_msg = (BT_HDR *)nfa_rw_cb.p_pending_msg;
+                nfa_rw_cb.p_pending_msg = NULL;
+                nfa_rw_handle_event(p_pending_msg);
+            }
+            else
+            {
+                /* Tag no longer present. Free command for pending API command */
+                GKI_freebuf(nfa_rw_cb.p_pending_msg);
+                nfa_rw_cb.p_pending_msg = NULL;
+            }
+        }
+
+        /* Auto-presence check failed. Deactivate */
+        if (status != NFC_STATUS_OK)
+        {
+            NFA_TRACE_DEBUG0("Auto presence check failed. Deactivating...");
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+        }
+    }
+    /* Handle presence check due to NFA_RwPresenceCheck API call */
+    else
+    {
+        /* Notify app of presence check status */
+        nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT, (tNFA_CONN_EVT_DATA *)&status);
+
+        /* If in normal mode (not-exclusive RF mode) then deactivate the link if presence check failed */
+        if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) && (status != NFC_STATUS_OK))
+        {
+            NFA_TRACE_DEBUG0("Presence check failed. Deactivating...");
+            nfa_dm_rf_deactivate (NFA_DEACTIVATE_TYPE_DISCOVERY);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t1t_evt
+**
+** Description      Handler for Type-1 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t1t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    conn_evt_data.status = p_rw_data->data.status;
+    switch (event)
+    {
+    case RW_T1T_RID_EVT:
+    case RW_T1T_RALL_CPLT_EVT:
+    case RW_T1T_READ_CPLT_EVT:
+    case RW_T1T_RSEG_CPLT_EVT:
+    case RW_T1T_READ8_CPLT_EVT:
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T1T_WRITE_E_CPLT_EVT:
+    case RW_T1T_WRITE_NE_CPLT_EVT:
+    case RW_T1T_WRITE_E8_CPLT_EVT:
+    case RW_T1T_WRITE_NE8_CPLT_EVT:
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T1T_TLV_DETECT_EVT:
+        nfa_rw_handle_tlv_detect(event, p_rw_data);
+        break;
+
+    case RW_T1T_NDEF_DETECT_EVT:
+        nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+        nfa_rw_handle_ndef_detect(event, p_rw_data);
+        break;
+
+    case RW_T1T_NDEF_READ_EVT:
+        nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+        if (p_rw_data->status == NFC_STATUS_OK)
+        {
+            /* Process the ndef record */
+            nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
+        }
+        else
+        {
+            /* Notify app of failure */
+            if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+            {
+                /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+                nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+            }
+        }
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+        break;
+
+    case RW_T1T_NDEF_WRITE_EVT:
+        if (p_rw_data->data.status != NFA_STATUS_OK)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+        nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
+
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+
+        /* Notify app */
+        conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* Update local cursize of ndef message */
+            nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+        }
+
+        /* Notify app of ndef write complete status */
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T1T_SET_TAG_RO_EVT:
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+        break;
+
+    case RW_T1T_RAW_FRAME_EVT:
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        break;
+
+    case RW_T1T_PRESENCE_CHECK_EVT:             /* Presence check completed */
+        nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+        break;
+
+    case RW_T1T_FORMAT_CPLT_EVT:
+        if (p_rw_data->data.status == NFA_STATUS_OK)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T1T_INTF_ERROR_EVT:
+        nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t2t_evt
+**
+** Description      Handler for Type-2 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t2t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    conn_evt_data.status = p_rw_data->data.status;
+    switch (event)
+    {
+    case RW_T2T_READ_CPLT_EVT:              /* Read completed          */
+        nfa_rw_send_data_to_upper (p_rw_data);
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T2T_WRITE_CPLT_EVT:             /* Write completed         */
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T2T_SELECT_CPLT_EVT:            /* Sector select completed */
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_SELECT_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T2T_NDEF_DETECT_EVT:            /* NDEF detection complete */
+        nfa_rw_handle_ndef_detect(event, p_rw_data);
+        break;
+
+    case RW_T2T_TLV_DETECT_EVT:             /* Lock control/Mem/Prop tlv detection complete */
+        nfa_rw_handle_tlv_detect(event, p_rw_data);
+        break;
+
+    case RW_T2T_NDEF_READ_EVT:              /* NDEF read completed     */
+        if (p_rw_data->status == NFC_STATUS_OK)
+        {
+            /* Process the ndef record */
+            nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
+        }
+        else
+        {
+            /* Notify app of failure */
+            if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+            {
+                /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+                nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+            }
+        }
+
+        /* Notify app of read status */
+        conn_evt_data.status = p_rw_data->status;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        break;
+
+    case RW_T2T_NDEF_WRITE_EVT:             /* NDEF write complete     */
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+
+        /* Notify app */
+        conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* Update local cursize of ndef message */
+            nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+        }
+
+        /* Notify app of ndef write complete status */
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+
+        break;
+
+    case RW_T2T_SET_TAG_RO_EVT:
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+        break;
+
+    case RW_T2T_RAW_FRAME_EVT:
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        break;
+
+    case RW_T2T_PRESENCE_CHECK_EVT:             /* Presence check completed */
+        nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+        break;
+
+    case RW_T2T_FORMAT_CPLT_EVT:
+        if (p_rw_data->data.status == NFA_STATUS_OK)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T2T_INTF_ERROR_EVT:
+        nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t3t_evt
+**
+** Description      Handler for Type-3 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t3t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+    tNFA_TAG_PARAMS tag_params;
+
+    switch (event)
+    {
+    case RW_T3T_NDEF_DETECT_EVT:            /* NDEF detection complete */
+        nfa_rw_handle_ndef_detect(event, p_rw_data);
+        break;
+
+    case RW_T3T_UPDATE_CPLT_EVT:        /* Write completed */
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+
+        /* Notify app */
+        conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* Update local cursize of ndef message */
+            nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+        }
+
+        /* Notify app of ndef write complete status */
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+
+        break;
+
+    case RW_T3T_CHECK_CPLT_EVT:         /* Read completed */
+        if (p_rw_data->status == NFC_STATUS_OK)
+        {
+            /* Process the ndef record */
+            nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
+        }
+        else
+        {
+            /* Notify app of failure */
+            if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+            {
+                /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+                nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+            }
+        }
+
+        /* Free ndef buffer */
+        nfa_rw_free_ndef_rx_buf();
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = p_rw_data->status;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T3T_CHECK_EVT:                  /* Segment of data received from type 3 tag */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            nfa_rw_store_ndef_rx_buf (p_rw_data);
+        }
+        else
+        {
+            nfa_rw_send_data_to_upper (p_rw_data);
+        }
+        break;
+
+    case RW_T3T_RAW_FRAME_EVT:              /* SendRawFrame response */
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        break;
+
+    case RW_T3T_PRESENCE_CHECK_EVT:             /* Presence check completed */
+        nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+        break;
+
+    case RW_T3T_GET_SYSTEM_CODES_EVT:           /* Presence check completed */
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+
+        /* System codes retrieved - notify app of ACTIVATION */
+        if (p_rw_data->status == NFC_STATUS_OK)
+        {
+            tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes;
+            tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes;
+        }
+        else
+        {
+            tag_params.t3t.num_system_codes = 0;
+            tag_params.t3t.p_system_codes = NULL;
+        }
+
+        nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
+        break;
+
+    case RW_T3T_FORMAT_CPLT_EVT:        /* Format completed */
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+
+        /* Notify app */
+        conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
+
+        /* Notify app of ndef write complete status */
+        nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+        break;
+
+
+    case RW_T3T_INTF_ERROR_EVT:
+        conn_evt_data.status = p_rw_data->status;
+        nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+        break;
+    }
+
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_t4t_evt
+**
+** Description      Handler for Type-4 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_t4t_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    switch (event)
+    {
+    case RW_T4T_NDEF_DETECT_EVT :           /* Result of NDEF detection procedure */
+        nfa_rw_handle_ndef_detect(event, p_rw_data);
+        break;
+
+    case RW_T4T_NDEF_READ_EVT:              /* Segment of data received from type 4 tag */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            nfa_rw_store_ndef_rx_buf (p_rw_data);
+        }
+        else
+        {
+            nfa_rw_send_data_to_upper (p_rw_data);
+        }
+        break;
+
+    case RW_T4T_NDEF_READ_CPLT_EVT:         /* Read operation completed           */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            nfa_rw_store_ndef_rx_buf (p_rw_data);
+
+            /* Process the ndef record */
+            nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
+
+            /* Free ndef buffer */
+            nfa_rw_free_ndef_rx_buf();
+        }
+        else
+        {
+            nfa_rw_send_data_to_upper (p_rw_data);
+        }
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+        conn_evt_data.status = NFC_STATUS_OK;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T4T_NDEF_READ_FAIL_EVT:         /* Read operation failed              */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+            nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+            /* Free ndef buffer */
+            nfa_rw_free_ndef_rx_buf();
+        }
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+        conn_evt_data.status = NFA_STATUS_FAILED;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T4T_NDEF_UPDATE_CPLT_EVT:       /* Update operation completed         */
+    case RW_T4T_NDEF_UPDATE_FAIL_EVT:       /* Update operation failed            */
+
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* Update local cursize of ndef message */
+            nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+        }
+
+        /* Notify app */
+        if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT)
+            conn_evt_data.status = NFA_STATUS_OK;
+        else
+            conn_evt_data.status = NFA_STATUS_FAILED;
+
+        /* Command complete - perform cleanup, notify the app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_T4T_RAW_FRAME_EVT:              /* Raw Frame data event         */
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+        break;
+
+    case RW_T4T_INTF_ERROR_EVT:             /* RF Interface error event         */
+        /* if NDEF operation */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+            nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+            /* Free ndef buffer */
+            nfa_rw_free_ndef_rx_buf();
+        }
+        else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* Update local cursize of ndef message */
+            nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+        }
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = p_rw_data->status;
+
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        }
+        else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        }
+        else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF)
+        {
+            conn_evt_data.ndef_detect.cur_size = 0;
+            conn_evt_data.ndef_detect.max_size = 0;
+            conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
+            nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+        }
+        else
+            nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
+        break;
+
+
+    case RW_T4T_PRESENCE_CHECK_EVT:             /* Presence check completed */
+        nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+        break;
+
+    default:
+        NFA_TRACE_DEBUG1("nfa_rw_handle_t4t_evt(); Unhandled RW event 0x%X", event);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_i93_evt
+**
+** Description      Handler for ISO 15693 tag reader/writer events
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_handle_i93_evt (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+    tNFA_TAG_PARAMS    i93_params;
+
+    switch (event)
+    {
+    case RW_I93_NDEF_DETECT_EVT :           /* Result of NDEF detection procedure */
+        nfa_rw_handle_ndef_detect(event, p_rw_data);
+        break;
+
+    case RW_I93_NDEF_READ_EVT:              /* Segment of data received from type 4 tag */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            nfa_rw_store_ndef_rx_buf (p_rw_data);
+        }
+        else
+        {
+            nfa_rw_send_data_to_upper (p_rw_data);
+        }
+        break;
+
+    case RW_I93_NDEF_READ_CPLT_EVT:         /* Read operation completed           */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            nfa_rw_store_ndef_rx_buf (p_rw_data);
+
+            /* Process the ndef record */
+            nfa_dm_ndef_handle_message (NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf, nfa_rw_cb.ndef_cur_size);
+
+            /* Free ndef buffer */
+            nfa_rw_free_ndef_rx_buf();
+        }
+        else
+        {
+            nfa_rw_send_data_to_upper (p_rw_data);
+        }
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        conn_evt_data.status = NFC_STATUS_OK;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_I93_NDEF_READ_FAIL_EVT:         /* Read operation failed              */
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+        {
+            /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+            nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+            /* Free ndef buffer */
+            nfa_rw_free_ndef_rx_buf();
+        }
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        conn_evt_data.status = NFA_STATUS_FAILED;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_I93_NDEF_UPDATE_CPLT_EVT:       /* Update operation completed         */
+    case RW_I93_NDEF_UPDATE_FAIL_EVT:       /* Update operation failed            */
+
+        if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+        {
+            /* Update local cursize of ndef message */
+            nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+        }
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+
+        if (event == RW_I93_NDEF_UPDATE_CPLT_EVT)
+            conn_evt_data.status = NFA_STATUS_OK;
+        else
+            conn_evt_data.status = NFA_STATUS_FAILED;
+
+        /* Notify app of ndef write complete status */
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_I93_RAW_FRAME_EVT:              /* Raw Frame data event         */
+        nfa_rw_send_data_to_upper (p_rw_data);
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        break;
+
+    case RW_I93_INTF_ERROR_EVT:             /* RF Interface error event         */
+        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
+        {
+            nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+            memset (&i93_params, 0x00, sizeof (tNFA_TAG_PARAMS));
+            memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+
+            /* Command complete - perform cleanup, notify app */
+            nfa_rw_command_complete();
+
+            nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
+        }
+        else
+        {
+            /* if NDEF operation */
+            if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+            {
+                /* If current operation is READ_NDEF, then notify ndef handlers of failure */
+                nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
+
+                /* Free ndef buffer */
+                nfa_rw_free_ndef_rx_buf();
+            }
+            else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+            {
+                /* Update local cursize of ndef message */
+                nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
+            }
+
+            /* Command complete - perform cleanup, notify app */
+            nfa_rw_command_complete();
+
+            conn_evt_data.status = p_rw_data->status;
+
+            if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF)
+            {
+                nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+            }
+            else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF)
+            {
+                nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+            }
+            else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF)
+            {
+                conn_evt_data.ndef_detect.cur_size = 0;
+                conn_evt_data.ndef_detect.max_size = 0;
+                conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
+                nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+            }
+            else
+            {
+                /* this event doesn't have command */
+                nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
+            }
+        }
+
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        break;
+
+
+    case RW_I93_PRESENCE_CHECK_EVT:             /* Presence check completed */
+        nfa_rw_handle_presence_check_rsp(p_rw_data->status);
+        break;
+
+    case RW_I93_FORMAT_CPLT_EVT:                /* Format procedure complete          */
+        if (p_rw_data->data.status == NFA_STATUS_OK)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        conn_evt_data.status = p_rw_data->status;
+        nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
+        break;
+
+    case RW_I93_SET_TAG_RO_EVT:                 /* Set read-only procedure complete   */
+        nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        conn_evt_data.status = p_rw_data->status;
+        nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
+        break;
+
+    case RW_I93_INVENTORY_EVT:                  /* Response of Inventory              */
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+
+        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
+        {
+            /* read AFI */
+            if (RW_I93ReadSingleBlock ((UINT8)(nfa_rw_cb.i93_afi_location / nfa_rw_cb.i93_block_size)) != NFC_STATUS_OK)
+            {
+                nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+                i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE);
+                i93_params.i93.dsfid      = p_rw_data->i93_inventory.dsfid;
+                i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
+                i93_params.i93.num_block  = nfa_rw_cb.i93_num_block;
+                memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+
+                nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
+            }
+            else
+            {
+                nfa_rw_cb.i93_dsfid = p_rw_data->i93_inventory.dsfid;
+                break;
+            }
+        }
+        else
+        {
+            conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_inventory.status;
+            conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY;
+
+            conn_evt_data.i93_cmd_cplt.params.inventory.dsfid = p_rw_data->i93_inventory.dsfid;
+            memcpy (conn_evt_data.i93_cmd_cplt.params.inventory.uid,
+                    p_rw_data->i93_inventory.uid,
+                    I93_UID_BYTE_LEN);
+
+            nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+        }
+
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        break;
+
+    case RW_I93_DATA_EVT:                       /* Response of Read, Get Multi Security */
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+
+        conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->i93_data.p_data + 1) + p_rw_data->i93_data.p_data->offset;
+
+        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
+        {
+            nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+            i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE|I93_INFO_FLAG_AFI);
+            i93_params.i93.afi        = *(conn_evt_data.data.p_data + nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size);
+            i93_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
+            i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
+            i93_params.i93.num_block  = nfa_rw_cb.i93_num_block;
+            memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
+
+            nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
+        }
+        else
+        {
+            conn_evt_data.data.len    = p_rw_data->i93_data.p_data->len;
+
+            nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
+        }
+
+        GKI_freebuf(p_rw_data->i93_data.p_data);
+        p_rw_data->i93_data.p_data = NULL;
+
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        break;
+
+    case RW_I93_SYS_INFO_EVT:                   /* Response of System Information     */
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+
+        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
+        {
+            nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
+
+            nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
+            nfa_rw_cb.i93_num_block  = p_rw_data->i93_sys_info.num_block;
+
+            i93_params.i93.info_flags   = p_rw_data->i93_sys_info.info_flags;
+            i93_params.i93.dsfid        = p_rw_data->i93_sys_info.dsfid;
+            i93_params.i93.afi          = p_rw_data->i93_sys_info.afi;
+            i93_params.i93.num_block    = p_rw_data->i93_sys_info.num_block;
+            i93_params.i93.block_size   = p_rw_data->i93_sys_info.block_size;
+            i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference;
+            memcpy (i93_params.i93.uid, p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN);
+
+            nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
+        }
+        else
+        {
+            conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_inventory.status;
+            conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO;
+
+            conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags = p_rw_data->i93_sys_info.info_flags;
+            memcpy (conn_evt_data.i93_cmd_cplt.params.sys_info.uid,
+                    p_rw_data->i93_sys_info.uid,
+                    I93_UID_BYTE_LEN);
+            conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid        = p_rw_data->i93_sys_info.dsfid;
+            conn_evt_data.i93_cmd_cplt.params.sys_info.afi          = p_rw_data->i93_sys_info.afi;
+            conn_evt_data.i93_cmd_cplt.params.sys_info.num_block    = p_rw_data->i93_sys_info.num_block;
+            conn_evt_data.i93_cmd_cplt.params.sys_info.block_size   = p_rw_data->i93_sys_info.block_size;
+            conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference = p_rw_data->i93_sys_info.IC_reference;
+
+            /* store tag memory information for writing blocks */
+            nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
+            nfa_rw_cb.i93_num_block  = p_rw_data->i93_sys_info.num_block;
+
+            nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+        }
+
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        break;
+
+    case RW_I93_CMD_CMPL_EVT:                   /* Command complete                   */
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+
+        conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_cmd_cmpl.status;
+        conn_evt_data.i93_cmd_cplt.sent_command = p_rw_data->i93_cmd_cmpl.command;
+
+        if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK)
+            conn_evt_data.i93_cmd_cplt.params.error_code = p_rw_data->i93_cmd_cmpl.error_code;
+
+        nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+
+        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
+        break;
+
+    default:
+        NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X", event);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_cback
+**
+** Description      Callback for reader/writer event notification
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data)
+{
+    NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event);
+
+    /* Call appropriate event handler for tag type */
+    if (event < RW_T1T_MAX_EVT)
+    {
+        /* Handle Type-1 tag events */
+        nfa_rw_handle_t1t_evt(event, p_rw_data);
+    }
+    else if (event < RW_T2T_MAX_EVT)
+    {
+        /* Handle Type-2 tag events */
+        nfa_rw_handle_t2t_evt(event, p_rw_data);
+    }
+    else if (event < RW_T3T_MAX_EVT)
+    {
+        /* Handle Type-3 tag events */
+        nfa_rw_handle_t3t_evt(event, p_rw_data);
+    }
+    else if (event < RW_T4T_MAX_EVT)
+    {
+        /* Handle Type-4 tag events */
+        nfa_rw_handle_t4t_evt(event, p_rw_data);
+    }
+    else if (event < RW_I93_MAX_EVT)
+    {
+        /* Handle ISO 15693 tag events */
+        nfa_rw_handle_i93_evt(event, p_rw_data);
+    }
+    else
+    {
+        NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_start_ndef_detection
+**
+** Description      Start NDEF detection on activated tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_detection(void)
+{
+    tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    switch (protocol)
+    {
+    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
+        status = RW_T1tDetectNDef();
+        break;
+
+    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
+        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+            status = RW_T2tDetectNDef();
+        break;
+
+    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
+        status = RW_T3tDetectNDef();
+        break;
+
+    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
+        status = RW_T4tDetectNDef();
+        break;
+
+    case NFC_PROTOCOL_15693:       /* ISO 15693 */
+        status = RW_I93DetectNDef();
+        break;
+
+    default:
+        break;
+    }
+
+    return(status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_start_ndef_read
+**
+** Description      Start NDEF read on activated tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_read(void)
+{
+    tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    /* Handle zero length NDEF message */
+    if (nfa_rw_cb.ndef_cur_size == 0)
+    {
+        NFA_TRACE_DEBUG0("NDEF message is zero-length");
+
+        /* Send zero-lengh NDEF message to ndef callback */
+        nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = NFA_STATUS_OK;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        return NFC_STATUS_OK;
+    }
+
+    /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if needed) */
+    nfa_rw_free_ndef_rx_buf ();
+    if ((nfa_rw_cb.p_ndef_buf = (UINT8 *)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size)) == NULL)
+    {
+        NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)", nfa_rw_cb.ndef_cur_size);
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = NFA_STATUS_FAILED;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+        return NFC_STATUS_FAILED;
+    }
+    nfa_rw_cb.ndef_rd_offset = 0;
+
+    switch (protocol)
+    {
+    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
+        status = RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
+        break;
+
+    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
+        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+            status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
+
+        break;
+
+    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
+        status = RW_T3tCheckNDef();
+        break;
+
+    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
+        status = RW_T4tReadNDef();
+        break;
+
+    case NFC_PROTOCOL_15693:       /* ISO 15693 */
+        status = RW_I93ReadNDef();
+        break;
+
+    default:
+        break;
+    }
+    return(status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_detect_ndef
+**
+** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+    NFA_TRACE_DEBUG0("nfa_rw_detect_ndef");
+
+    if ((conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection()) != NFC_STATUS_OK)
+    {
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.ndef_detect.cur_size = 0;
+        conn_evt_data.ndef_detect.max_size = 0;
+        conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
+        nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_start_ndef_write
+**
+** Description      Start NDEF write on activated tag
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_start_ndef_write(void)
+{
+    tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY)
+    {
+        /* error: ndef tag is read-only */
+        status = NFC_STATUS_FAILED;
+        NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only")
+    }
+    else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len)
+    {
+        /* error: ndef tag size is too small */
+        status = NFC_STATUS_BUFFER_FULL;
+        NFA_TRACE_ERROR2("Unable to write NDEF. Tag maxsize=%i, request write size=%i", nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len)
+    }
+    else
+    {
+        switch (protocol)
+        {
+        case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
+            status = RW_T1tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+            break;
+
+        case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
+
+            if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+                status = RW_T2tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+            break;
+
+        case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
+            status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+            break;
+
+        case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
+            status = RW_T4tUpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+            break;
+
+        case NFC_PROTOCOL_15693:       /* ISO 15693 */
+            status = RW_I93UpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    return(status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_read_ndef
+**
+** Description      Handler for NFA_RW_API_READ_NDEF_EVT
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_read_ndef(tNFA_RW_MSG *p_data)
+{
+    tNFA_STATUS status = NFA_STATUS_OK;
+    tNFA_CONN_EVT_DATA conn_evt_data;
+
+    NFA_TRACE_DEBUG0("nfa_rw_read_ndef");
+
+    /* Check if ndef detection has been performed yet */
+    if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
+    {
+        /* Perform ndef detection first */
+        status = nfa_rw_start_ndef_detection();
+    }
+    else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
+    {
+        /* Tag is not NDEF */
+        status = NFA_STATUS_FAILED;
+    }
+    else
+    {
+        /* Perform the NDEF read operation */
+        status = nfa_rw_start_ndef_read();
+    }
+
+    /* Handle failure */
+    if (status != NFA_STATUS_OK)
+    {
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = status;
+        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
+    }
+
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_write_ndef
+**
+** Description      Handler for NFA_RW_API_WRITE_NDEF_EVT
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_write_ndef(tNFA_RW_MSG *p_data)
+{
+    tNDEF_STATUS ndef_status;
+    tNFA_STATUS write_status = NFA_STATUS_OK;
+    tNFA_CONN_EVT_DATA conn_evt_data;
+    NFA_TRACE_DEBUG0("nfa_rw_write_ndef");
+
+    /* Validate NDEF message */
+    if ((ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data, p_data->op_req.params.write_ndef.len, FALSE)) != NDEF_OK)
+    {
+        NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status);
+
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = NFA_STATUS_FAILED;
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+        return TRUE;
+    }
+
+    /* Store pointer to source NDEF */
+    nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
+    nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
+
+    /* Check if ndef detection has been performed yet */
+    if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
+    {
+        /* Perform ndef detection first */
+        write_status = nfa_rw_start_ndef_detection();
+    }
+    else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
+    {
+        /* Tag is not NDEF */
+        write_status = NFA_STATUS_FAILED;
+    }
+    else
+    {
+        /* Perform the NDEF read operation */
+        write_status = nfa_rw_start_ndef_write();
+    }
+
+    /* Handle failure */
+    if (write_status != NFA_STATUS_OK)
+    {
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        conn_evt_data.status = write_status;
+        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_presence_check
+**
+** Description      Handler for NFA_RW_API_PRESENCE_CHECK
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void nfa_rw_presence_check (tNFA_RW_MSG *p_data)
+{
+    tNFC_PROTOCOL       protocol = nfa_rw_cb.protocol;
+    UINT8               sel_res  = nfa_rw_cb.pa_sel_res;
+    tNFC_STATUS         status   = NFC_STATUS_FAILED;
+
+    switch (protocol)
+    {
+    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
+        status = RW_T1tPresenceCheck();
+        break;
+
+    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
+        status = RW_T3tPresenceCheck();
+        break;
+
+    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
+        status = RW_T4tPresenceCheck();
+        break;
+
+    case NFC_PROTOCOL_15693:       /* ISO 15693 */
+        status = RW_I93PresenceCheck();
+        break;
+
+    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
+        /* If T2T NFC-Forum, then let RW handle presence check; otherwise fall through */
+        if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+        {
+            status = RW_T2tPresenceCheck();
+            break;
+        }
+
+    default:
+        /* Protocol unsupported by RW module... */
+        /* Let DM perform presence check (by putting tag to sleep and then waking it up) */
+        status = nfa_dm_disc_presence_check();
+        break;
+    }
+
+    /* Handle presence check failure */
+    if (status != NFC_STATUS_OK)
+        nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_rw_presence_check_tick
+**
+** Description      Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL
+**                  Initiate presence check
+**
+** Returns          TRUE (caller frees message buffer)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_presence_check_tick(tNFA_RW_MSG *p_data)
+{
+    /* Store the current operation */
+    nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
+    nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
+    NFA_TRACE_DEBUG0("Auto-presence check starting...");
+
+    /* Perform presence check */
+    nfa_rw_presence_check(NULL);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_format_tag
+**
+** Description      Handler for NFA_RW_API_FORMAT_TAG
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+static void nfa_rw_format_tag (tNFA_RW_MSG *p_data)
+{
+    tNFC_PROTOCOL   protocol = nfa_rw_cb.protocol;
+    tNFC_STATUS     status   = NFC_STATUS_FAILED;
+
+    if (protocol == NFC_PROTOCOL_T1T)
+    {
+        status = RW_T1tFormatNDef();
+    }
+    else if (  (protocol  == NFC_PROTOCOL_T2T)
+             &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) )
+    {
+        status = RW_T2tFormatNDef();
+    }
+    else if (protocol == NFC_PROTOCOL_T3T)
+    {
+        status = RW_T3tFormatNDef();
+    }
+    else if (protocol == NFC_PROTOCOL_15693)
+    {
+        status = RW_I93FormatNDef();
+    }
+
+    /* If unable to format NDEF, notify the app */
+    if (status != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_FORMAT_CPLT_EVT);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_detect_tlv
+**
+** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_detect_tlv (tNFA_RW_MSG *p_data, UINT8 tlv)
+{
+    NFA_TRACE_DEBUG0("nfa_rw_detect_tlv");
+
+    switch (nfa_rw_cb.protocol)
+    {
+    case NFC_PROTOCOL_T1T:
+        if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
+            nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
+        break;
+
+    case NFC_PROTOCOL_T2T:
+        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+        {
+            if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
+                nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_config_tag_ro
+**
+** Description      Handler for NFA_RW_OP_SET_TAG_RO
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static tNFC_STATUS nfa_rw_config_tag_ro (BOOLEAN b_hard_lock)
+{
+    tNFC_PROTOCOL                       protocol        = nfa_rw_cb.protocol;
+    tNFC_STATUS                         status          = NFC_STATUS_FAILED;
+
+    NFA_TRACE_DEBUG0("nfa_rw_config_tag_ro");
+
+    switch (protocol)
+    {
+    case NFC_PROTOCOL_T1T:
+        if(  (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
+           ||(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE) )
+        {
+            status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
+        }
+        else if ( (status = RW_T1tSetTagReadOnly(b_hard_lock)) != NFC_STATUS_OK)
+        {
+            nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
+        }
+        else
+        {
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+        }
+        break;
+
+    case NFC_PROTOCOL_T2T:
+        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+        {
+            if ( (status = RW_T2tSetTagReadOnly(b_hard_lock)) != NFC_STATUS_OK)
+            {
+                nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
+            }
+            else
+            {
+                nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+            }
+        }
+        break;
+
+    case NFC_PROTOCOL_15693:
+        if ( (status = RW_I93SetTagReadOnly()) != NFC_STATUS_OK)
+            nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
+        break;
+
+    default:
+        /* NOTE: type type-3 and type-4 protocol does not define transition to read-only */
+        break;
+
+    }
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_rid
+**
+** Description      Handler for T1T_RID API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_rid(tNFA_RW_MSG *p_data)
+{
+    if (RW_T1tRid () != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_rall
+**
+** Description      Handler for T1T_ReadAll API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_rall(tNFA_RW_MSG *p_data)
+{
+    if (RW_T1tReadAll() != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_read
+**
+** Description      Handler for T1T_Read API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_read (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
+
+    if (RW_T1tRead (p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_write
+**
+** Description      Handler for T1T_WriteErase/T1T_WriteNoErase API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_write (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
+    tNFC_STATUS                 status;
+
+    if (p_t1t_write->b_erase)
+    {
+        status = RW_T1tWriteErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
+    }
+    else
+    {
+        status = RW_T1tWriteNoErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
+    }
+
+    if (status != NFC_STATUS_OK)
+    {
+        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+    }
+    else
+    {
+        if (p_t1t_write->block_number == 0x01)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_rseg
+**
+** Description      Handler for T1t_ReadSeg API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_rseg (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
+
+    if (RW_T1tReadSeg (p_t1t_read->segment_number) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_read8
+**
+** Description      Handler for T1T_Read8 API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_read8 (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
+
+    if (RW_T1tRead8 (p_t1t_read->block_number) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t1t_write8
+**
+** Description      Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t1t_write8 (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
+    tNFC_STATUS                 status;
+
+    if (p_t1t_write->b_erase)
+    {
+        status = RW_T1tWriteErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
+    }
+    else
+    {
+        status = RW_T1tWriteNoErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
+    }
+
+    if (status != NFC_STATUS_OK)
+    {
+        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+    }
+    else
+    {
+        if (p_t1t_write->block_number == 0x01)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t2t_read
+**
+** Description      Handler for T2T_Read API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t2t_read (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T2T_READ *p_t2t_read = (tNFA_RW_OP_PARAMS_T2T_READ *)&(p_data->op_req.params.t2t_read);
+    tNFC_STATUS                status = NFC_STATUS_FAILED;
+
+    if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
+        status = RW_T2tRead (p_t2t_read->block_number);
+
+    if (status != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t2t_write
+**
+** Description      Handler for T2T_Write API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t2t_write (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T2T_WRITE *p_t2t_write = (tNFA_RW_OP_PARAMS_T2T_WRITE *)&(p_data->op_req.params.t2t_write);
+
+    if (RW_T2tWrite (p_t2t_write->block_number,p_t2t_write->p_block_data) != NFC_STATUS_OK)
+    {
+        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+    }
+    else
+    {
+        if (p_t2t_write->block_number == 0x03)
+            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t2t_sector_select
+**
+** Description      Handler for T2T_Sector_Select API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t2t_sector_select(tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *p_t2t_sector_select = (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT *)&(p_data->op_req.params.t2t_sector_select);
+
+    if (RW_T2tSectorSelect (p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_SELECT_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t3t_read
+**
+** Description      Handler for T3T_Read API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t3t_read (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T3T_READ *p_t3t_read = (tNFA_RW_OP_PARAMS_T3T_READ *)&(p_data->op_req.params.t3t_read);
+
+    if (RW_T3tCheck (p_t3t_read->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t3t_write
+**
+** Description      Handler for T3T_Write API
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t3t_write (tNFA_RW_MSG *p_data)
+{
+    tNFA_RW_OP_PARAMS_T3T_WRITE *p_t3t_write = (tNFA_RW_OP_PARAMS_T3T_WRITE *)&(p_data->op_req.params.t3t_write);
+
+    if (RW_T3tUpdate (p_t3t_write->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_write->p_block_desc, p_t3t_write->p_block_data) != NFC_STATUS_OK)
+        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_t3t_get_system_codes
+**
+** Description      Get system codes (initiated by NFA after activation)
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_t3t_get_system_codes (tNFA_RW_MSG *p_data)
+{
+    tNFC_STATUS     status;
+    tNFA_TAG_PARAMS tag_params;
+
+    status = RW_T3tGetSystemCodes();
+
+    if (status != NFC_STATUS_OK)
+    {
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+        tag_params.t3t.num_system_codes = 0;
+        tag_params.t3t.p_system_codes   = NULL;
+
+        nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_i93_command
+**
+** Description      Handler for ISO 15693 command
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_i93_command (tNFA_RW_MSG *p_data)
+{
+    tNFA_CONN_EVT_DATA conn_evt_data;
+    tNFC_STATUS        status = NFC_STATUS_OK;
+    UINT8              i93_command = I93_CMD_STAY_QUIET;
+
+    switch (p_data->op_req.op)
+    {
+    case NFA_RW_OP_I93_INVENTORY:
+        i93_command = I93_CMD_INVENTORY;
+        if (p_data->op_req.params.i93_cmd.uid_present)
+        {
+            status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi,
+                                      p_data->op_req.params.i93_cmd.uid);
+        }
+        else
+        {
+            status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi, NULL);
+        }
+        break;
+
+    case NFA_RW_OP_I93_STAY_QUIET:
+        i93_command = I93_CMD_STAY_QUIET;
+        status = RW_I93StayQuiet ();
+        break;
+
+    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+        i93_command = I93_CMD_READ_SINGLE_BLOCK;
+        status = RW_I93ReadSingleBlock (p_data->op_req.params.i93_cmd.first_block_number);
+        break;
+
+    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+        i93_command = I93_CMD_WRITE_SINGLE_BLOCK;
+        status = RW_I93WriteSingleBlock (p_data->op_req.params.i93_cmd.first_block_number,
+                                         p_data->op_req.params.i93_cmd.p_data);
+        break;
+
+    case NFA_RW_OP_I93_LOCK_BLOCK:
+        i93_command = I93_CMD_LOCK_BLOCK;
+        status = RW_I93LockBlock (p_data->op_req.params.i93_cmd.first_block_number);
+        break;
+
+    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+        i93_command = I93_CMD_READ_MULTI_BLOCK;
+        status = RW_I93ReadMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number,
+                                           p_data->op_req.params.i93_cmd.number_blocks);
+        break;
+
+    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+        i93_command = I93_CMD_WRITE_MULTI_BLOCK;
+        status = RW_I93WriteMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number,
+                                            p_data->op_req.params.i93_cmd.number_blocks,
+                                            p_data->op_req.params.i93_cmd.p_data);
+        break;
+
+    case NFA_RW_OP_I93_SELECT:
+        i93_command = I93_CMD_SELECT;
+        status = RW_I93Select (p_data->op_req.params.i93_cmd.p_data);
+        break;
+
+    case NFA_RW_OP_I93_RESET_TO_READY:
+        i93_command = I93_CMD_RESET_TO_READY;
+        status = RW_I93ResetToReady ();
+        break;
+
+    case NFA_RW_OP_I93_WRITE_AFI:
+        i93_command = I93_CMD_WRITE_AFI;
+        status = RW_I93WriteAFI (p_data->op_req.params.i93_cmd.afi);
+        break;
+
+    case NFA_RW_OP_I93_LOCK_AFI:
+        i93_command = I93_CMD_LOCK_AFI;
+        status = RW_I93LockAFI ();
+        break;
+
+    case NFA_RW_OP_I93_WRITE_DSFID:
+        i93_command = I93_CMD_WRITE_DSFID;
+        status = RW_I93WriteDSFID (p_data->op_req.params.i93_cmd.dsfid);
+        break;
+
+    case NFA_RW_OP_I93_LOCK_DSFID:
+        i93_command = I93_CMD_LOCK_DSFID;
+        status = RW_I93LockDSFID ();
+        break;
+
+    case NFA_RW_OP_I93_GET_SYS_INFO:
+        i93_command = I93_CMD_GET_SYS_INFO;
+        if (p_data->op_req.params.i93_cmd.uid_present)
+        {
+            status = RW_I93GetSysInfo (p_data->op_req.params.i93_cmd.uid);
+        }
+        else
+        {
+            status = RW_I93GetSysInfo (NULL);
+        }
+        break;
+
+    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+        i93_command = I93_CMD_GET_MULTI_BLK_SEC;
+        status = RW_I93GetMultiBlockSecurityStatus (p_data->op_req.params.i93_cmd.first_block_number,
+                                                    p_data->op_req.params.i93_cmd.number_blocks);
+        break;
+
+    default:
+        break;
+    }
+
+    if (status != NFC_STATUS_OK)
+    {
+        /* Command complete - perform cleanup, notify app */
+        nfa_rw_command_complete();
+
+        conn_evt_data.i93_cmd_cplt.status       = NFA_STATUS_FAILED;
+        conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
+
+        nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_raw_mode_data_cback
+**
+** Description      Handler for incoming tag data for unsupported tag protocols
+**                  (forward data to upper layer)
+**
+** Returns          nothing
+**
+*******************************************************************************/
+static void nfa_rw_raw_mode_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    BT_HDR             *p_msg = (BT_HDR *)p_data->data.p_data;
+    tNFA_CONN_EVT_DATA evt_data;
+
+    NFA_TRACE_DEBUG1 ("nfa_rw_raw_mode_data_cback(): event = 0x%X", event);
+
+    if ((event == NFC_DATA_CEVT) && (p_data->data.status == NFC_STATUS_OK))
+    {
+        if (p_msg)
+        {
+            evt_data.data.p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;
+            evt_data.data.len    = p_msg->len;
+
+            nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);
+
+            GKI_freebuf (p_msg);
+        }
+        else
+        {
+            NFA_TRACE_ERROR0 ("nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
+        }
+    }
+    else if (event == NFC_DEACTIVATE_CEVT)
+    {
+        NFC_SetStaticRfCback (NULL);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_rw_activate_ntf
+**
+** Description      Handler for NFA_RW_ACTIVATE_NTF
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_activate_ntf(tNFA_RW_MSG *p_data)
+{
+    tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params;
+    tNFA_TAG_PARAMS    tag_params;
+    tNFA_RW_OPERATION  msg;
+    BOOLEAN            activate_notify = TRUE;
+    UINT8              *p;
+
+    NFA_TRACE_DEBUG0("nfa_rw_activate_ntf");
+
+    /* Initialize control block */
+    nfa_rw_cb.protocol   = p_activate_params->protocol;
+    nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp;
+    nfa_rw_cb.flags      = NFA_RW_FL_ACTIVATED;
+    nfa_rw_cb.cur_op     = NFA_RW_OP_MAX;
+    nfa_rw_cb.ndef_st    = NFA_RW_NDEF_ST_UNKNOWN;
+    nfa_rw_cb.tlv_st     = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED;
+
+    memset (&tag_params, 0, sizeof(tNFA_TAG_PARAMS));
+
+    /* Check if we are in exclusive RF mode */
+    if (p_data->activate_ntf.excl_rf_not_active)
+    {
+        /* Not in exclusive RF mode */
+        nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE;
+    }
+
+    /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and start presence check if needed */
+    if (!nfa_dm_is_protocol_supported(p_activate_params->protocol, p_activate_params->rf_tech_param.param.pa.sel_rsp))
+    {
+        /* Set data callback (pass all incoming data to upper layer using NFA_DATA_EVT) */
+        NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
+
+        /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
+        nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
+        nfa_rw_check_start_presence_check_timer ();
+        return TRUE;
+    }
+
+    /* Initialize RW module */
+    if ((RW_SetActivatedTagType (p_activate_params, nfa_rw_cback)) != NFC_STATUS_OK)
+    {
+        /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
+        NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
+        return TRUE;
+    }
+
+    /* Perform protocol-specific actions */
+    switch (nfa_rw_cb.protocol)
+    {
+    case NFC_PROTOCOL_T1T:
+        /* Retrieve HR and UID fields from activation notification */
+        memcpy (tag_params.t1t.hr, p_activate_params->intf_param.intf_param.frame.param, NFA_T1T_HR_LEN);
+        memcpy (tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
+        break;
+
+    case NFC_PROTOCOL_T2T:
+        /* Retrieve UID fields from activation notification */
+        memcpy (tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
+        break;
+
+    case NFC_PROTOCOL_T3T:
+        /* Issue command to get Felica system codes */
+        activate_notify = FALSE;                    /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes are retrieved */
+        msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES;
+        nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg);
+        break;
+
+    case NFC_PROTOCOL_15693:
+        /* Issue INVENTORY command to retrieve additional tag infomation */
+        nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING;
+        activate_notify = FALSE;                    /* Delay notifying upper layer of NFA_ACTIVATED_EVT until INVENTORY response is received */
+
+        p = nfa_rw_cb.i93_uid;
+        ARRAY8_TO_STREAM (p, p_data->activate_ntf.p_activate_params->rf_tech_param.param.pi93.uid);
+
+        msg.params.i93_cmd.uid_present = TRUE;
+        p = msg.params.i93_cmd.uid;
+        ARRAY8_TO_STREAM (p, p_data->activate_ntf.p_activate_params->rf_tech_param.param.pi93.uid);
+
+        if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI)
+          &&(((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
+           ||((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)))
+        {
+            /* these don't support Get System Information Command */
+            nfa_rw_cb.i93_block_size    = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
+            nfa_rw_cb.i93_afi_location  = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
+
+            if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
+            {
+                nfa_rw_cb.i93_num_block     = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK;
+            }
+            else
+            {
+                nfa_rw_cb.i93_num_block     = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK;
+            }
+
+            msg.op = NFA_RW_OP_I93_INVENTORY; /* Let stack know UID of activated tag */
+            msg.params.i93_cmd.afi = 0x00;
+        }
+        else
+        {
+            /* All of ICODE supports Get System Information Command */
+            /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */
+            /* just try for others */
+
+            nfa_rw_cb.i93_block_size = 0;
+            nfa_rw_cb.i93_num_block  = 0;
+
+            msg.op = NFA_RW_OP_I93_GET_SYS_INFO;
+        }
+
+        /* Send the command */
+        nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg);
+        break;
+
+
+    default:
+        /* No action needed for other protocols */
+        break;
+    }
+
+    /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */
+    if (activate_notify)
+    {
+        nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
+        nfa_rw_check_start_presence_check_timer ();
+    }
+
+
+    return TRUE;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_rw_deactivate_ntf
+**
+** Description      Handler for NFA_RW_DEACTIVATE_NTF
+**
+** Returns          TRUE (message buffer to be freed by caller)
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_deactivate_ntf(tNFA_RW_MSG *p_data)
+{
+    /* Clear the activated flag */
+    nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
+
+    /* Free buffer for incoming NDEF message, in case we were in the middle of a read operation */
+    nfa_rw_free_ndef_rx_buf();
+
+    /* If there is a pending command message, then free it */
+    if (nfa_rw_cb.p_pending_msg)
+    {
+        GKI_freebuf(nfa_rw_cb.p_pending_msg);
+        nfa_rw_cb.p_pending_msg = NULL;
+    }
+
+    /* Stop presence check timer (if started) */
+    nfa_rw_stop_presence_check_timer();
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_op_req
+**
+** Description      Handler for NFA_RW_OP_REQUEST_EVT, operation request
+**
+** Returns          TRUE if caller should free p_data
+**                  FALSE if caller does not need to free p_data
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data)
+{
+    BOOLEAN freebuf = TRUE;
+
+    /* Check if activated */
+    if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED))
+    {
+        NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated");
+        return TRUE;
+    }
+    /* Check if currently busy with another API call */
+    else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY)
+    {
+        return (nfa_rw_op_req_while_busy(p_data));
+    }
+    /* Check if currently busy with auto-presence check */
+    else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY)
+    {
+        /* Cache the command (will be handled once auto-presence check is completed) */
+        NFA_TRACE_DEBUG1("Deferring operation %i until after auto-presence check is completed", p_data->op_req.op);
+        nfa_rw_cb.p_pending_msg = p_data;
+        nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
+        return (freebuf);
+    }
+
+    NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op);
+
+    nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
+
+    /* Stop the presence check timer */
+    nfa_rw_stop_presence_check_timer();
+
+    /* Store the current operation */
+    nfa_rw_cb.cur_op = p_data->op_req.op;
+
+    /* Call appropriate handler for requested operation */
+    switch (p_data->op_req.op)
+    {
+    case NFA_RW_OP_DETECT_NDEF:
+        nfa_rw_detect_ndef(p_data);
+        break;
+
+    case NFA_RW_OP_READ_NDEF:
+        nfa_rw_read_ndef(p_data);
+        break;
+
+    case NFA_RW_OP_WRITE_NDEF:
+        nfa_rw_write_ndef(p_data);
+        break;
+
+    case NFA_RW_OP_SEND_RAW_FRAME:
+        NFC_SendData (NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data);
+
+        /* Command complete - perform cleanup */
+        nfa_rw_command_complete();
+        break;
+
+    case NFA_RW_OP_PRESENCE_CHECK:
+        nfa_rw_presence_check(p_data);
+        break;
+
+    case NFA_RW_OP_FORMAT_TAG:
+        nfa_rw_format_tag(p_data);
+        break;
+
+    case NFA_RW_OP_DETECT_LOCK_TLV:
+        nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV);
+        break;
+
+    case NFA_RW_OP_DETECT_MEM_TLV:
+        nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV);
+        break;
+
+    case NFA_RW_OP_SET_TAG_RO:
+        nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock;
+        nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock);
+        break;
+
+    case NFA_RW_OP_T1T_RID:
+        nfa_rw_t1t_rid(p_data);
+        break;
+
+    case NFA_RW_OP_T1T_RALL:
+        nfa_rw_t1t_rall(p_data);
+        break;
+
+    case NFA_RW_OP_T1T_READ:
+        nfa_rw_t1t_read(p_data);
+        break;
+
+    case NFA_RW_OP_T1T_WRITE:
+        nfa_rw_t1t_write(p_data);
+        break;
+
+    case NFA_RW_OP_T1T_RSEG:
+        nfa_rw_t1t_rseg(p_data);
+        break;
+
+    case NFA_RW_OP_T1T_READ8:
+        nfa_rw_t1t_read8(p_data);
+        break;
+
+    case NFA_RW_OP_T1T_WRITE8:
+        nfa_rw_t1t_write8(p_data);
+        break;
+
+        /* Type-2 tag commands */
+    case NFA_RW_OP_T2T_READ:
+        nfa_rw_t2t_read(p_data);
+        break;
+
+    case NFA_RW_OP_T2T_WRITE:
+        nfa_rw_t2t_write(p_data);
+        break;
+
+    case NFA_RW_OP_T2T_SECTOR_SELECT:
+        nfa_rw_t2t_sector_select(p_data);
+        break;
+
+        /* Type-3 tag commands */
+    case NFA_RW_OP_T3T_READ:
+        nfa_rw_t3t_read(p_data);
+        break;
+
+    case NFA_RW_OP_T3T_WRITE:
+        nfa_rw_t3t_write(p_data);
+        break;
+
+    case NFA_RW_OP_T3T_GET_SYSTEM_CODES:
+        nfa_rw_t3t_get_system_codes(p_data);
+        break;
+
+        /* ISO 15693 tag commands */
+    case NFA_RW_OP_I93_INVENTORY:
+    case NFA_RW_OP_I93_STAY_QUIET:
+    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_LOCK_BLOCK:
+    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+    case NFA_RW_OP_I93_SELECT:
+    case NFA_RW_OP_I93_RESET_TO_READY:
+    case NFA_RW_OP_I93_WRITE_AFI:
+    case NFA_RW_OP_I93_LOCK_AFI:
+    case NFA_RW_OP_I93_WRITE_DSFID:
+    case NFA_RW_OP_I93_LOCK_DSFID:
+    case NFA_RW_OP_I93_GET_SYS_INFO:
+    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+        nfa_rw_i93_command (p_data);
+        break;
+
+    default:
+        NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i", p_data->op_req.op);
+        break;
+    }
+
+    return (freebuf);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_rw_op_req_while_busy
+**
+** Description      Handle operation request while busy
+**
+** Returns          TRUE if caller should free p_data
+**                  FALSE if caller does not need to free p_data
+**
+*******************************************************************************/
+static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data)
+{
+    BOOLEAN             freebuf = TRUE;
+    tNFA_CONN_EVT_DATA  conn_evt_data;
+    UINT8               event;
+
+    NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API");
+
+    /* Return appropriate event for requested API, with status=BUSY */
+    conn_evt_data.status = NFA_STATUS_BUSY;
+
+    switch (p_data->op_req.op)
+    {
+    case NFA_RW_OP_DETECT_NDEF:
+        conn_evt_data.ndef_detect.cur_size = 0;
+        conn_evt_data.ndef_detect.max_size = 0;
+        conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
+        event = NFA_NDEF_DETECT_EVT;
+        break;
+    case NFA_RW_OP_READ_NDEF:
+    case NFA_RW_OP_T1T_RID:
+    case NFA_RW_OP_T1T_RALL:
+    case NFA_RW_OP_T1T_READ:
+    case NFA_RW_OP_T1T_RSEG:
+    case NFA_RW_OP_T1T_READ8:
+    case NFA_RW_OP_T2T_READ:
+    case NFA_RW_OP_T3T_READ:
+        event = NFA_READ_CPLT_EVT;
+        break;
+    case NFA_RW_OP_WRITE_NDEF:
+    case NFA_RW_OP_T1T_WRITE:
+    case NFA_RW_OP_T1T_WRITE8:
+    case NFA_RW_OP_T2T_WRITE:
+    case NFA_RW_OP_T3T_WRITE:
+        event = NFA_WRITE_CPLT_EVT;
+        break;
+    case NFA_RW_OP_FORMAT_TAG:
+        event = NFA_FORMAT_CPLT_EVT;
+        break;
+        case NFA_RW_OP_DETECT_LOCK_TLV:
+    case NFA_RW_OP_DETECT_MEM_TLV:
+        event = NFA_TLV_DETECT_EVT;
+        break;
+    case NFA_RW_OP_SET_TAG_RO:
+        event = NFA_SET_TAG_RO_EVT;
+        break;
+    case NFA_RW_OP_T2T_SECTOR_SELECT:
+        event = NFA_SELECT_CPLT_EVT;
+        break;
+    case NFA_RW_OP_I93_INVENTORY:
+    case NFA_RW_OP_I93_STAY_QUIET:
+    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
+    case NFA_RW_OP_I93_LOCK_BLOCK:
+    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
+    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
+    case NFA_RW_OP_I93_SELECT:
+    case NFA_RW_OP_I93_RESET_TO_READY:
+    case NFA_RW_OP_I93_WRITE_AFI:
+    case NFA_RW_OP_I93_LOCK_AFI:
+    case NFA_RW_OP_I93_WRITE_DSFID:
+    case NFA_RW_OP_I93_LOCK_DSFID:
+    case NFA_RW_OP_I93_GET_SYS_INFO:
+    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
+        event = NFA_I93_CMD_CPLT_EVT;
+        break;
+    default:
+        return (freebuf);
+    }
+    nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
+
+    return (freebuf);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_command_complete
+**
+** Description      Handle command complete: clear the busy flag,
+**                  and start the presence check timer if applicable.
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_rw_command_complete(void)
+{
+    /* Clear the busy flag */
+    nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
+
+    /* Restart presence_check timer */
+    nfa_rw_check_start_presence_check_timer ();
+}
diff --git a/src/nfa/rw/nfa_rw_api.c b/src/nfa/rw/nfa_rw_api.c
new file mode 100644
index 0000000..4ac6dd4
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_api.c
@@ -0,0 +1,1497 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA interface for tag Reader/Writer
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_rw_int.h"
+#include "nfa_sys_int.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+
+/*****************************************************************************
+**  APIs
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RwDetectNDef
+**
+** Description      Perform the NDEF detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection, a
+**                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
+**                  of the NDEF attributes (NDEF total memory size, current
+**                  size, etc.).
+**
+**                  It is not mandatory to call this function -  NFA_RwReadNDef
+**                  and NFA_RwWriteNDef will perform NDEF detection internally if
+**                  not performed already. This API may be called to get a
+**                  tag's NDEF size before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwDetectNDef (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwDetectNDef");
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_DETECT_NDEF;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwReadNDef
+**
+** Description      Read NDEF message from tag. This function will internally
+**                  perform the NDEF detection procedure (if not performed
+**                  previously), and read the NDEF tag data using the
+**                  appropriate method for the currently activated tag.
+**
+**                  Upon successful completion of NDEF detection (if performed),
+**                  a NFA_NDEF_DETECT_EVT will be sent, to notify the application
+**                  of the NDEF attributes (NDEF total memory size, current size,
+**                  etc.).
+**
+**                  Upon receiving the NDEF message, the message will be sent to
+**                  the handler registered with NFA_RegisterNDefTypeHandler or
+**                  NFA_RequestExclusiveRfControl (if exclusive RF mode is active)
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF
+**                  NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the tag
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwReadNDef (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwReadNDef");
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_READ_NDEF;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+
+
+/*******************************************************************************
+**
+** Function         NFA_RwWriteNDef
+**
+** Description      Write NDEF data to the activated tag. This function will
+**                  internally perform NDEF detection if necessary, and write
+**                  the NDEF tag data using the appropriate method for the
+**                  currently activated tag.
+**
+**                  When the entire message has been written, or if an error
+**                  occurs, the app will be notified with NFA_WRITE_CPLT_EVT.
+**
+**                  p_data needs to be persistent until NFA_WRITE_CPLT_EVT
+**
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tag does not support NDEF/locked
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwWriteNDef (UINT8 *p_data, UINT32 len)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API2 ("NFA_RwWriteNDef (): ndef p_data=%08x, len: %i", p_data, len);
+
+    /* Validate parameters */
+    if (p_data == NULL)
+        return (NFA_STATUS_INVALID_PARAM);
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        p_msg->hdr.event                = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op                       = NFA_RW_OP_WRITE_NDEF;
+        p_msg->params.write_ndef.len    = len;
+        p_msg->params.write_ndef.p_data = p_data;
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*****************************************************************************
+**
+** Function         NFA_RwPresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
+**                  indicate presence or non-presence.
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+tNFA_STATUS NFA_RwPresenceCheck (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwPresenceCheck");
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_PRESENCE_CHECK;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*****************************************************************************
+**
+** Function         NFA_RwFormatTag
+**
+** Description      Check if the tag is NDEF Formatable. If yes Format the tag
+**
+**                  The NFA_RW_FORMAT_CPLT_EVT w/ status is used to
+**                  indicate if tag is successfully formated or not
+**
+** Returns
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*****************************************************************************/
+tNFA_STATUS NFA_RwFormatTag (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwFormatTag");
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16)(sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_FORMAT_TAG;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwSetTagReadOnly
+**
+** Description:
+**      Sets tag as read only.
+**
+**      When tag is set as read only, or if an error occurs, the app will be
+**      notified with NFA_SET_TAG_RO_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_REJECTED if protocol is not T1/T2/ISO15693
+**                 (or) if hard lock is not requested for protocol ISO15693
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwSetTagReadOnly (BOOLEAN b_hard_lock)
+{
+    tNFA_RW_OPERATION *p_msg;
+    tNFC_PROTOCOL      protocol = nfa_rw_cb.protocol;
+
+    if ((protocol != NFC_PROTOCOL_T1T) && (protocol != NFC_PROTOCOL_T2T) && (protocol != NFC_PROTOCOL_15693))
+    {
+        NFA_TRACE_API1 ("NFA_RwSetTagReadOnly (): Cannot Configure as read only for Protocol: %d", protocol);
+        return (NFA_STATUS_REJECTED);
+    }
+
+    if (!b_hard_lock && (protocol == NFC_PROTOCOL_15693))
+    {
+        NFA_TRACE_API1 ("NFA_RwSetTagReadOnly (): Can only hardlock for Protocol: %d", protocol);
+        return (NFA_STATUS_REJECTED);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                       = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op                              = NFA_RW_OP_SET_TAG_RO;
+        p_msg->params.set_readonly.b_hard_lock = b_hard_lock;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+** Tag specific APIs
+** (note: for Type-4 tags, use NFA_SendRawFrame to exchange APDUs)
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_RwLocateTlv
+**
+** Description:
+**      Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
+**
+**      Data is returned to the application using the NFA_TLV_DETECT_EVT. When
+**      search operation has completed, or if an error occurs, the app will be
+**      notified with NFA_TLV_DETECT_EVT.
+**
+** Description      Perform the TLV detection procedure  using the appropriate
+**                  method for the currently activated tag.
+**
+**                  Upon successful completion of TLV detection in T1/T2 tag, a
+**                  NFA_TLV_DETECT_EVT will be sent, to notify the application
+**                  of the TLV attributes (total lock/reserved bytes etc.).
+**                  However if the TLV type specified is NDEF then it is same as
+**                  calling NFA_RwDetectNDef and should expect to receive
+**                  NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
+**
+**                  It is not mandatory to call this function -  NFA_RwDetectNDef,
+**                  NFA_RwReadNDef and NFA_RwWriteNDef will perform TLV detection
+**                  internally if not performed already. An application may call
+**                  this API to check the a tag/card-emulator's total Reserved/
+**                  Lock bytes before issuing a write-request.
+**
+** Returns:
+**                  NFA_STATUS_OK if successfully initiated
+**                  NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support NDEF
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwLocateTlv (UINT8 tlv_type)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwLocateTlv");
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+
+        if (tlv_type == TAG_LOCK_CTRL_TLV)
+        {
+            p_msg->op = NFA_RW_OP_DETECT_LOCK_TLV;
+        }
+        else if (tlv_type == TAG_MEM_CTRL_TLV)
+        {
+            p_msg->op = NFA_RW_OP_DETECT_MEM_TLV;
+        }
+        else if (tlv_type == TAG_NDEF_TLV)
+        {
+            p_msg->op = NFA_RW_OP_DETECT_NDEF;
+        }
+        else
+            return (NFA_STATUS_FAILED);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRid
+**
+** Description:
+**      Send a RID command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRid (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_T1T_RID;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadAll
+**
+** Description:
+**      Send a RALL command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tReadAll (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_T1T_RALL;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead
+**
+** Description:
+**      Send a READ command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRead (UINT8 block_number, UINT8 index)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                    = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op                           = NFA_RW_OP_T1T_READ;
+        p_msg->params.t1t_read.block_number = block_number;
+        p_msg->params.t1t_read.index        = index;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite
+**
+** Description:
+**      Send a WRITE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the write
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tWrite (UINT8 block_number, UINT8 index, UINT8 data, BOOLEAN b_erase)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                     = NFA_RW_OP_REQUEST_EVT;
+        p_msg->params.t1t_write.b_erase      = b_erase;
+        p_msg->op                            = NFA_RW_OP_T1T_WRITE;
+        p_msg->params.t1t_write.block_number = block_number;
+        p_msg->params.t1t_write.index        = index;
+        p_msg->params.t1t_write.p_block_data[0] = data;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tReadSeg
+**
+** Description:
+**      Send a RSEG command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tReadSeg (UINT8 segment_number)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                      = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op                             = NFA_RW_OP_T1T_RSEG;
+        p_msg->params.t1t_read.segment_number = segment_number;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tRead8
+**
+** Description:
+**      Send a READ8 command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tRead8 (UINT8 block_number)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                     = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op                            = NFA_RW_OP_T1T_READ8;
+        p_msg->params.t1t_write.block_number = block_number;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT1tWrite8
+**
+** Description:
+**      Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT1tWrite8 (UINT8 block_number, UINT8 *p_data, BOOLEAN b_erase)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                     = NFA_RW_OP_REQUEST_EVT;
+        p_msg->params.t1t_write.b_erase      = b_erase;
+        p_msg->op                            = NFA_RW_OP_T1T_WRITE8;
+        p_msg->params.t1t_write.block_number = block_number;
+
+        memcpy (p_msg->params.t1t_write.p_block_data,p_data,8);
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tRead
+**
+** Description:
+**      Send a READ command to the activated Type 2 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tRead (UINT8 block_number)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwT2tRead (): Block to read: %d", block_number);
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event                    = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op                           = NFA_RW_OP_T2T_READ;
+        p_msg->params.t2t_read.block_number = block_number;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tWrite
+**
+** Description:
+**      Send an WRITE command to the activated Type 2 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tWrite (UINT8 block_number,	UINT8 *p_data)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwT2tRead (): Block to write: %d", block_number);
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_T2T_WRITE;
+
+        p_msg->params.t2t_write.block_number = block_number;
+
+        memcpy (p_msg->params.t2t_write.p_block_data,p_data,4);
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT2tSectorSelect
+**
+** Description:
+**      Send SECTOR SELECT command to the activated Type 2 tag.
+**
+**      When the sector select operation has completed (or if an error occurs), the
+**      app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT2tSectorSelect (UINT8 sector_number)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwT2tRead (): sector to select: %d", sector_number);
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_T2T_SECTOR_SELECT;
+
+        p_msg->params.t2t_sector_select.sector_number = sector_number;
+
+        nfa_sys_sendmsg (p_msg);
+        return (NFA_STATUS_OK);
+    }
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tRead
+**
+** Description:
+**      Send a CHECK (read) command to the activated Type 3 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_READ_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT3tRead (UINT8 num_blocks, tNFA_T3T_BLOCK_DESC *t3t_blocks)
+{
+    tNFA_RW_OPERATION *p_msg;
+    UINT8 *p_block_desc;
+
+    NFA_TRACE_API1 ("NFA_RwT3tRead (): num_blocks to read: %i", num_blocks);
+
+    /* Validate parameters */
+    if ((num_blocks == 0) || (t3t_blocks == NULL))
+        return (NFA_STATUS_INVALID_PARAM);
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + (num_blocks * sizeof (tNFA_T3T_BLOCK_DESC))))) != NULL)
+    {
+        /* point to area after tNFA_RW_OPERATION */
+        p_block_desc = (UINT8 *) (p_msg+1);
+
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_T3T_READ;
+
+        p_msg->params.t3t_read.num_blocks   = num_blocks;
+        p_msg->params.t3t_read.p_block_desc = (tNFA_T3T_BLOCK_DESC *) p_block_desc;
+
+        /* Copy block descriptor list */
+        memcpy (p_block_desc, t3t_blocks, (num_blocks * sizeof (tNFA_T3T_BLOCK_DESC)));
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwT3tWrite
+**
+** Description:
+**      Send an UPDATE (write) command to the activated Type 3 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_WRITE_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwT3tWrite (UINT8 num_blocks, tNFA_T3T_BLOCK_DESC *t3t_blocks,	UINT8 *p_data)
+{
+    tNFA_RW_OPERATION *p_msg;
+    UINT8 *p_block_desc, *p_data_area;
+
+    NFA_TRACE_API1 ("NFA_RwT3tWrite (): num_blocks to write: %i", num_blocks);
+
+    /* Validate parameters */
+    if ((num_blocks == 0) || (t3t_blocks == NULL) | (p_data == NULL))
+        return (NFA_STATUS_INVALID_PARAM);
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + (num_blocks * (sizeof (tNFA_T3T_BLOCK_DESC) + 16))))) != NULL)
+    {
+        /* point to block descriptor and data areas after tNFA_RW_OPERATION */
+        p_block_desc = (UINT8 *) (p_msg+1);
+        p_data_area  = p_block_desc + (num_blocks * (sizeof (tNFA_T3T_BLOCK_DESC)));
+
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_T3T_WRITE;
+
+        p_msg->params.t3t_write.num_blocks   = num_blocks;
+        p_msg->params.t3t_write.p_block_desc = (tNFA_T3T_BLOCK_DESC *) p_block_desc;
+        p_msg->params.t3t_write.p_block_data = p_data_area;
+
+        /* Copy block descriptor list */
+        memcpy (p_block_desc, t3t_blocks, (num_blocks * sizeof (tNFA_T3T_BLOCK_DESC)));
+
+        /* Copy data */
+        memcpy (p_data_area, p_data, (num_blocks * 16));
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Inventory
+**
+** Description:
+**      Send Inventory command to the activated ISO 15693 tag.
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93Inventory (UINT8 afi, UINT8 *p_uid)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwI93Inventory (): AFI: 0x%02X", afi);
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_INVENTORY;
+
+        p_msg->params.i93_cmd.afi = afi;
+
+        if (p_uid)
+        {
+            p_msg->params.i93_cmd.uid_present = TRUE;
+            memcpy (p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
+        }
+        else
+        {
+            p_msg->params.i93_cmd.uid_present = FALSE;
+        }
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93StayQuiet
+**
+** Description:
+**      Send Stay Quiet command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93StayQuiet (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwI93StayQuiet ()");
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_STAY_QUIET;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadSingleBlock
+**
+** Description:
+**      Send Read Single Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ReadSingleBlock (UINT8 block_number)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwI93ReadSingleBlock (): block_number: 0x%02X", block_number);
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_READ_SINGLE_BLOCK;
+
+        p_msg->params.i93_cmd.first_block_number = block_number;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteSingleBlock
+**
+** Description:
+**      Send Write Single Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteSingleBlock (UINT8 block_number,
+                                       UINT8 *p_data)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwI93WriteSingleBlock (): block_number: 0x%02X", block_number);
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    /* we don't know block size of tag */
+    if (  (nfa_rw_cb.i93_block_size == 0)
+        ||(nfa_rw_cb.i93_num_block == 0)  )
+    {
+        return (NFA_STATUS_FAILED);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + nfa_rw_cb.i93_block_size))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_WRITE_SINGLE_BLOCK;
+
+        p_msg->params.i93_cmd.first_block_number = block_number;
+        p_msg->params.i93_cmd.p_data             = (UINT8*) (p_msg + 1);
+
+        memcpy (p_msg->params.i93_cmd.p_data, p_data, nfa_rw_cb.i93_block_size);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockBlock
+**
+** Description:
+**      Send Lock block command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockBlock (UINT8 block_number)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwI93LockBlock (): block_number: 0x%02X", block_number);
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_LOCK_BLOCK;
+
+        p_msg->params.i93_cmd.first_block_number = block_number;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ReadMultipleBlocks
+**
+** Description:
+**      Send Read Multiple Block command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ReadMultipleBlocks (UINT8  first_block_number,
+                                         UINT16 number_blocks)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API2 ("NFA_RwI93ReadMultipleBlocks(): %d, %d", first_block_number, number_blocks);
+
+    if ( nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_READ_MULTI_BLOCK;
+
+        p_msg->params.i93_cmd.first_block_number = first_block_number;
+        p_msg->params.i93_cmd.number_blocks      = number_blocks;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteMultipleBlocks
+**
+** Description:
+**      Send Write Multiple Block command to the activated ISO 15693 tag.
+**
+**      When the write operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteMultipleBlocks (UINT8  first_block_number,
+                                          UINT16 number_blocks,
+                                          UINT8 *p_data)
+{
+    tNFA_RW_OPERATION *p_msg;
+    UINT16      data_length;
+
+    NFA_TRACE_API2 ("NFA_RwI93WriteMultipleBlocks (): %d, %d", first_block_number, number_blocks);
+
+    if ( nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    /* we don't know block size of tag */
+    if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0))
+    {
+        return (NFA_STATUS_FAILED);
+    }
+
+    data_length = nfa_rw_cb.i93_block_size * number_blocks;
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + data_length))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_WRITE_MULTI_BLOCK;
+
+        p_msg->params.i93_cmd.first_block_number = first_block_number;
+        p_msg->params.i93_cmd.number_blocks      = number_blocks;
+        p_msg->params.i93_cmd.p_data             = (UINT8*) (p_msg + 1);
+
+        memcpy (p_msg->params.i93_cmd.p_data, p_data, data_length);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93Select
+**
+** Description:
+**      Send Select command to the activated ISO 15693 tag.
+**
+**      UID[0]: 0xE0, MSB
+**      UID[1]: IC Mfg Code
+**      ...
+**      UID[7]: LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93Select (UINT8 *p_uid)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API3 ("NFA_RwI93Select (): UID: [%02X%02X%02X...]", *(p_uid), *(p_uid+1), *(p_uid+2));
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION) + I93_UID_BYTE_LEN))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_SELECT;
+
+        p_msg->params.i93_cmd.p_data = (UINT8 *) (p_msg + 1);
+        memcpy (p_msg->params.i93_cmd.p_data, p_uid, I93_UID_BYTE_LEN);
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93ResetToReady
+**
+** Description:
+**      Send Reset to ready command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93ResetToReady (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwI93ResetToReady ()");
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_RESET_TO_READY;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteAFI
+**
+** Description:
+**      Send Write AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteAFI (UINT8 afi)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwI93WriteAFI (): AFI: 0x%02X", afi);
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_WRITE_AFI;
+
+        p_msg->params.i93_cmd.afi = afi;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockAFI
+**
+** Description:
+**      Send Lock AFI command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockAFI (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwI93LockAFI ()");
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_LOCK_AFI;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93WriteDSFID
+**
+** Description:
+**      Send Write DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93WriteDSFID (UINT8 dsfid)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API1 ("NFA_RwI93WriteDSFID (): DSFID: 0x%02X", dsfid);
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_WRITE_DSFID;
+
+        p_msg->params.i93_cmd.dsfid = dsfid;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93LockDSFID
+**
+** Description:
+**      Send Lock DSFID command to the activated ISO 15693 tag.
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93LockDSFID (void)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwI93LockDSFID ()");
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_LOCK_DSFID;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetSysInfo
+**
+** Description:
+**      Send Get system information command to the activated ISO 15693 tag.
+**      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**      When the operation has completed (or if an error occurs), the
+**      app will be notified with NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93GetSysInfo (UINT8 *p_uid)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API0 ("NFA_RwI93GetSysInfo ()");
+
+    if (nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_GET_SYS_INFO;
+
+        if (p_uid)
+        {
+            p_msg->params.i93_cmd.uid_present = TRUE;
+            memcpy (p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
+        }
+        else
+        {
+            p_msg->params.i93_cmd.uid_present = FALSE;
+        }
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_RwI93GetMultiBlockSecurityStatus
+**
+** Description:
+**      Send Get Multiple block security status command to the activated ISO 15693 tag.
+**
+**      Data is returned to the application using the NFA_DATA_EVT. When the read
+**      operation has completed, or if an error occurs, the app will be notified with
+**      NFA_I93_CMD_CPLT_EVT.
+**
+** Returns:
+**      NFA_STATUS_OK if successfully initiated
+**      NFA_STATUS_WRONG_PROTOCOL: ISO 15693 tag not activated
+**      NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus (UINT8  first_block_number,
+                                                  UINT16 number_blocks)
+{
+    tNFA_RW_OPERATION *p_msg;
+
+    NFA_TRACE_API2 ("NFA_RwI93GetMultiBlockSecurityStatus(): %d, %d", first_block_number, number_blocks);
+
+    if ( nfa_rw_cb.protocol != NFC_PROTOCOL_15693)
+    {
+        return (NFA_STATUS_WRONG_PROTOCOL);
+    }
+
+    if ((p_msg = (tNFA_RW_OPERATION *) GKI_getbuf ((UINT16) (sizeof (tNFA_RW_OPERATION)))) != NULL)
+    {
+        /* Fill in tNFA_RW_OPERATION struct */
+        p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
+        p_msg->op        = NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS;
+
+        p_msg->params.i93_cmd.first_block_number = first_block_number;
+        p_msg->params.i93_cmd.number_blocks      = number_blocks;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
diff --git a/src/nfa/rw/nfa_rw_main.c b/src/nfa/rw/nfa_rw_main.c
new file mode 100644
index 0000000..0304328
--- /dev/null
+++ b/src/nfa/rw/nfa_rw_main.c
@@ -0,0 +1,229 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA_RW
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_rw_api.h"
+#include "nfa_sys.h"
+#include "nfa_rw_int.h"
+#include "nfa_dm_int.h"
+#include "nfa_sys_int.h"
+
+/* NFA_RW control block */
+tNFA_RW_CB nfa_rw_cb;
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_rw_sys_reg =
+{
+    NULL,
+    nfa_rw_handle_event,
+    nfa_rw_sys_disable,
+    NULL
+};
+
+/* NFA_RW actions */
+const tNFA_RW_ACTION nfa_rw_action_tbl[] =
+{
+    nfa_rw_handle_op_req,           /* NFA_RW_OP_REQUEST_EVT            */
+    nfa_rw_activate_ntf,            /* NFA_RW_ACTIVATE_NTF_EVT          */
+    nfa_rw_deactivate_ntf,          /* NFA_RW_DEACTIVATE_NTF_EVT        */
+    nfa_rw_presence_check_tick,     /* NFA_RW_PRESENCE_CHECK_TICK_EVT   */
+};
+
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_rw_evt_2_str (UINT16 event);
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_rw_init
+**
+** Description      Initialize NFA RW
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_rw_init (void)
+{
+    NFA_TRACE_DEBUG0 ("nfa_rw_init ()");
+
+    /* initialize control block */
+    memset (&nfa_rw_cb, 0, sizeof (tNFA_RW_CB));
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register (NFA_ID_RW,  &nfa_rw_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_sys_disable
+**
+** Description      Clean up rw sub-system
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_rw_sys_disable (void)
+{
+    /* Return to idle */
+    NFC_SetStaticRfCback (NULL);
+
+    /* Stop presence check timer (if started) */
+    nfa_rw_stop_presence_check_timer ();
+
+    /* Free scratch buffer if any */
+    nfa_rw_free_ndef_rx_buf ();
+
+    /* Free pending command if any */
+    if (nfa_rw_cb.p_pending_msg)
+    {
+        GKI_freebuf (nfa_rw_cb.p_pending_msg);
+        nfa_rw_cb.p_pending_msg = NULL;
+    }
+
+    nfa_sys_deregister (NFA_ID_RW);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_proc_disc_evt
+**
+** Description      Called by nfa_dm to handle ACTIVATED/DEACTIVATED  events
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_rw_proc_disc_evt (tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER *p_data, BOOLEAN excl_rf_not_active)
+{
+    tNFA_RW_MSG msg;
+
+    switch (event)
+    {
+    case NFA_DM_RF_DISC_ACTIVATED_EVT:
+        msg.hdr.event                       = NFA_RW_ACTIVATE_NTF_EVT;
+        msg.activate_ntf.p_activate_params  = &p_data->activate;
+        msg.activate_ntf.excl_rf_not_active = excl_rf_not_active;
+
+        nfa_rw_handle_event ((BT_HDR *) &msg);
+        break;
+
+    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
+        msg.hdr.event = NFA_RW_DEACTIVATE_NTF_EVT;
+
+        nfa_rw_handle_event ((BT_HDR *) &msg);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_send_raw_frame
+**
+** Description      Called by nfa_dm to send raw frame
+**
+** Returns          tNFA_STATUS
+**
+*******************************************************************************/
+tNFA_STATUS nfa_rw_send_raw_frame (BT_HDR *p_data)
+{
+    tNFA_RW_MSG msg;
+
+    msg.hdr.event       = NFA_RW_OP_REQUEST_EVT;
+    msg.op_req.op = NFA_RW_OP_SEND_RAW_FRAME;
+
+    msg.op_req.params.send_raw_frame.p_data = p_data;
+
+    nfa_rw_handle_event ((BT_HDR *) &msg);
+    return (NFA_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_rw_handle_event
+**
+** Description      nfa rw main event handling function.
+**
+** Returns          TRUE if caller should free p_msg buffer
+**
+*******************************************************************************/
+BOOLEAN nfa_rw_handle_event(BT_HDR *p_msg)
+{
+    UINT16 act_idx;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFA_TRACE_EVENT3 ("nfa_rw_handle_event event: %s (0x%02x), flags: %08x", nfa_rw_evt_2_str (p_msg->event), p_msg->event, nfa_rw_cb.flags);
+#else
+    NFA_TRACE_EVENT2 ("nfa_rw_handle_event event: 0x%x, flags: %08x",p_msg->event, nfa_rw_cb.flags);
+#endif
+
+    /* Get NFA_RW sub-event */
+    if ((act_idx = (p_msg->event & 0x00FF)) < (NFA_RW_MAX_EVT & 0xFF))
+    {
+        return (*nfa_rw_action_tbl[act_idx]) ( (tNFA_RW_MSG*) p_msg);
+    }
+    else
+    {
+        NFA_TRACE_ERROR1 ("nfa_rw_handle_event: unhandled event 0x%02X", p_msg->event);
+        return TRUE;
+    }
+}
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_rw_evt_2_str
+**
+** Description      convert nfa_rw evt to string
+**
+*******************************************************************************/
+static char *nfa_rw_evt_2_str (UINT16 event)
+{
+    switch (event)
+    {
+    case NFA_RW_OP_REQUEST_EVT:
+        return "NFA_RW_OP_REQUEST_EVT";
+
+    case NFA_RW_ACTIVATE_NTF_EVT:
+        return "NFA_RW_ACTIVATE_NTF_EVT";
+
+    case NFA_RW_DEACTIVATE_NTF_EVT:
+        return "NFA_RW_DEACTIVATE_NTF_EVT";
+
+    case NFA_RW_PRESENCE_CHECK_TICK_EVT:
+        return "NFA_RW_PRESENCE_CHECK_TICK_EVT";
+
+    default:
+        return "Unknown";
+    }
+}
+#endif /* BT_TRACE_VERBOSE */
diff --git a/src/nfa/snep/nfa_snep_act.c b/src/nfa/snep/nfa_snep_act.c
new file mode 100644
index 0000000..68810c7
--- /dev/null
+++ b/src/nfa/snep/nfa_snep_act.c
@@ -0,0 +1,1975 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the generic SNEP implementation file for the NFA SNEP.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "llcp_defs.h"
+#include "nfa_p2p_int.h"
+#include "nfa_snep_int.h"
+#include "nfa_mem_co.h"
+#include "trace_api.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_snep_opcode (UINT8 opcode);
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_snep_sap_to_index
+**
+** Description      find a connection control block with SAP
+**
+**
+** Returns          index of connection control block if success
+**                  NFA_SNEP_MAX_CONN, otherwise
+**
+*******************************************************************************/
+UINT8 nfa_snep_sap_to_index (UINT8 local_sap, UINT8 remote_sap, UINT8 flags)
+{
+    UINT8 xx;
+
+    for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
+    {
+        if (  (nfa_snep_cb.conn[xx].p_cback)
+            &&(nfa_snep_cb.conn[xx].local_sap == local_sap)
+            &&((remote_sap == NFA_SNEP_ANY_SAP) || (nfa_snep_cb.conn[xx].remote_sap == remote_sap))
+            &&((nfa_snep_cb.conn[xx].flags & flags) == flags)  )
+        {
+            return xx;
+        }
+    }
+    return NFA_SNEP_MAX_CONN;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_allocate_cb
+**
+** Description      Allocate a connection control block
+**
+**
+** Returns          index of connection control block if success
+**                  NFA_SNEP_MAX_CONN, otherwise
+**
+*******************************************************************************/
+UINT8 nfa_snep_allocate_cb (void)
+{
+    UINT8 xx;
+
+    for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
+    {
+        if (nfa_snep_cb.conn[xx].p_cback == NULL)
+        {
+            memset (&nfa_snep_cb.conn[xx], 0x00, sizeof (tNFA_SNEP_CONN));
+            return xx;
+        }
+    }
+    return NFA_SNEP_MAX_CONN;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_deallocate_cb
+**
+** Description      Deallocate a connection control block
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_snep_deallocate_cb (UINT8 xx)
+{
+    nfa_snep_cb.conn[xx].p_cback = NULL;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_timer_cback
+**
+** Description      Process timeout event when timer expires
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_snep_timer_cback (void *p_tle)
+{
+    UINT8 dlink = (UINT8) ((TIMER_LIST_ENT*)p_tle)->event;
+
+    SNEP_TRACE_DEBUG1 ("nfa_snep_timer_cback () dlink = %d", dlink);
+
+    /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+    nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+    LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                        nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_get_efficent_miu
+**
+** Description      Calculate best MIU to send data for throughput
+**
+**
+** Returns          most efficent MIU for throughput
+**
+*******************************************************************************/
+static UINT16 nfa_snep_get_efficent_miu (UINT16 remote_miu, UINT8 remote_rw)
+{
+    UINT16 local_link_miu, remote_link_miu;
+    UINT16 max_num_pdu_in_agf;
+    UINT16 efficent_miu;
+
+    SNEP_TRACE_DEBUG2 ("nfa_snep_get_efficent_miu () remote_miu = %d, remote_rw = %d",
+                        remote_miu, remote_rw);
+
+    LLCP_GetLinkMIU (&local_link_miu, &remote_link_miu);
+
+    /* local buffer size is small than max receiving size of peer */
+    if (local_link_miu < remote_link_miu)
+    {
+        remote_link_miu = local_link_miu;
+    }
+
+    /*
+    ** 9 bytes overhead if AGF is used
+    **  - 2 byts AGF header
+    **  - at least two of 2 bytes length field for I-PDU
+    **  - 3 bytes header for I-PDU
+    */
+    if (remote_link_miu - remote_miu > 9)
+    {
+        /*
+        ** 5 bytes overhead for each I-PDU in AGF
+        **  - 2 bytes length field
+        **  - 3 bytes header for I-PDU
+        */
+        max_num_pdu_in_agf = remote_link_miu / (remote_miu + 5);
+
+        if (remote_link_miu % (remote_miu + 5))
+        {
+            max_num_pdu_in_agf += 1;
+        }
+
+        /* if local devie can put all I-PDU in one AGF */
+        if (max_num_pdu_in_agf <= remote_rw)
+        {
+            efficent_miu = (remote_link_miu - max_num_pdu_in_agf*5)/max_num_pdu_in_agf;
+        }
+        else
+        {
+            efficent_miu = remote_miu;
+        }
+    }
+    else
+    {
+        efficent_miu = remote_miu;
+    }
+
+    SNEP_TRACE_DEBUG2 ("nfa_snep_get_efficent_miu () remote_link_miu = %d, efficent_miu = %d",
+                        remote_link_miu, efficent_miu);
+
+    return efficent_miu;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_check_version
+**
+** Description      Check version of SNEP
+**
+**
+** Returns          TRUE if supported
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_check_version (UINT8 version)
+{
+    /* if major version is matched */
+    if ((version & 0xF0) == (NFA_SNEP_VERSION & 0xF0))
+        return TRUE;
+    else
+        return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_send_msg
+**
+** Description      Send complete or the first fragment of SNEP message with or
+**                  without information.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_snep_send_msg (UINT8 opcode, UINT8 dlink)
+{
+    BT_HDR *p_msg;
+    UINT32 length;
+    UINT8  *p;
+    tLLCP_STATUS status = LLCP_STATUS_FAIL;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    SNEP_TRACE_DEBUG4 ("nfa_snep_send_msg () [0x%x, 0x%x]: %s (0x%02x)",
+                       nfa_snep_cb.conn[dlink].local_sap,
+                       nfa_snep_cb.conn[dlink].remote_sap,
+                       nfa_snep_opcode (opcode), opcode);
+#else
+    SNEP_TRACE_DEBUG3 ("nfa_snep_send_msg () [0x%x, 0x%x]: opcode 0x%02x",
+                       nfa_snep_cb.conn[dlink].local_sap,
+                       nfa_snep_cb.conn[dlink].remote_sap,
+                       opcode);
+#endif
+
+    /* if there is pending SNEP message and opcode can have information */
+    if (  (nfa_snep_cb.conn[dlink].p_ndef_buff)
+        &&((opcode == NFA_SNEP_REQ_CODE_GET) || (opcode == NFA_SNEP_REQ_CODE_PUT) || (opcode == NFA_SNEP_RESP_CODE_SUCCESS))  )
+    {
+        length = NFA_SNEP_HEADER_SIZE + nfa_snep_cb.conn[dlink].ndef_length;
+
+        if (opcode == NFA_SNEP_REQ_CODE_GET)
+        {
+            length += NFA_SNEP_ACCEPT_LEN_SIZE; /* add acceptable length field */
+        }
+
+        /* if message is bigger than peer's MIU, send the first fragment */
+        if (length > nfa_snep_cb.conn[dlink].tx_miu)
+        {
+            length = nfa_snep_cb.conn[dlink].tx_miu;
+        }
+
+        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+        {
+            p_msg->len    = (UINT16) length;
+            p_msg->offset = LLCP_MIN_OFFSET;
+
+            p = (UINT8*) (p_msg + 1) + p_msg->offset;
+
+            /* add SNEP header */
+            UINT8_TO_BE_STREAM (p, NFA_SNEP_VERSION);
+            UINT8_TO_BE_STREAM (p, opcode);
+
+            if (opcode == NFA_SNEP_REQ_CODE_GET)
+            {
+                /* add acceptable length field in information field*/
+                UINT32_TO_BE_STREAM (p, nfa_snep_cb.conn[dlink].ndef_length + NFA_SNEP_ACCEPT_LEN_SIZE);
+                UINT32_TO_BE_STREAM (p, nfa_snep_cb.conn[dlink].acceptable_length);
+                length -= NFA_SNEP_ACCEPT_LEN_SIZE;
+            }
+            else
+            {
+                UINT32_TO_BE_STREAM (p, nfa_snep_cb.conn[dlink].ndef_length);
+            }
+
+            length -= NFA_SNEP_HEADER_SIZE;
+
+
+            /* add the first fragment or complete of NDEF message */
+            memcpy (p, nfa_snep_cb.conn[dlink].p_ndef_buff, length);
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+            DispSNEP (nfa_snep_cb.conn[dlink].local_sap,
+                      nfa_snep_cb.conn[dlink].remote_sap,
+                     (UINT8*)(p_msg + 1) + p_msg->offset,
+                      NFA_SNEP_HEADER_SIZE,
+                      FALSE);
+#endif
+            status = LLCP_SendData (nfa_snep_cb.conn[dlink].local_sap,
+                                    nfa_snep_cb.conn[dlink].remote_sap, p_msg);
+
+            if (status != LLCP_STATUS_FAIL)
+            {
+                SNEP_TRACE_DEBUG2 ("nfa_snep_send_msg (): sending %d out of %d",
+                                   length, nfa_snep_cb.conn[dlink].ndef_length);
+
+                /* if sent complete SNEP message */
+                if (length == nfa_snep_cb.conn[dlink].ndef_length)
+                {
+                    nfa_snep_cb.conn[dlink].cur_length = 0;
+
+                    if (  (opcode == NFA_SNEP_RESP_CODE_SUCCESS)
+                        &&(nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_GET)  )
+                    {
+                        /* Set LLCP to send LLCP_SAP_EVT_TX_COMPLETE */
+                        LLCP_SetTxCompleteNtf (nfa_snep_cb.conn[dlink].local_sap,
+                                               nfa_snep_cb.conn[dlink].remote_sap);
+                    }
+                }
+                else
+                {
+                    /* update sent length */
+                    nfa_snep_cb.conn[dlink].cur_length = length;
+
+                    if ((opcode == NFA_SNEP_REQ_CODE_GET) || (opcode == NFA_SNEP_REQ_CODE_PUT))
+                    {
+                        nfa_snep_cb.conn[dlink].flags |= NFA_SNEP_FLAG_W4_RESP_CONTINUE;
+                    }
+                    else /* (opcode == NFA_SNEP_RESP_CODE_SUCCESS) */
+                    {
+                        nfa_snep_cb.conn[dlink].flags |= NFA_SNEP_FLAG_W4_REQ_CONTINUE;
+                    }
+                }
+            }
+        }
+    }
+    else /* opcode without information */
+    {
+        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+        {
+            p_msg->len    = NFA_SNEP_HEADER_SIZE;
+            p_msg->offset = LLCP_MIN_OFFSET;
+
+            p = (UINT8*) (p_msg + 1) + p_msg->offset;
+
+            /* add SNEP header without information */
+            UINT8_TO_BE_STREAM (p, NFA_SNEP_VERSION);
+            UINT8_TO_BE_STREAM (p, opcode);
+            UINT32_TO_BE_STREAM (p, 0);
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+            DispSNEP(nfa_snep_cb.conn[dlink].local_sap,
+                     nfa_snep_cb.conn[dlink].remote_sap,
+                     (UINT8*)(p_msg + 1) + p_msg->offset,
+                     NFA_SNEP_HEADER_SIZE,
+                     FALSE);
+#endif
+            status = LLCP_SendData (nfa_snep_cb.conn[dlink].local_sap,
+                                    nfa_snep_cb.conn[dlink].remote_sap, p_msg);
+        }
+    }
+
+    if (status == LLCP_STATUS_FAIL)
+    {
+        SNEP_TRACE_ERROR0 ("Cannot allocate buffer or failed to send data");
+
+        /* upper layer will free buffer when NFA_SNEP_DISC_EVT is received */
+        nfa_snep_cb.conn[dlink].p_ndef_buff = 0;
+
+        LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                            nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+    }
+    else if (status == LLCP_STATUS_CONGESTED)
+    {
+        nfa_snep_cb.conn[dlink].congest = TRUE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_send_remaining
+**
+** Description      Send remaining fragments of SNEP message
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_snep_send_remaining (UINT8 dlink)
+{
+    BT_HDR *p_msg;
+    UINT8  *p_src, *p_dst;
+    UINT32 length;
+    tLLCP_STATUS status;
+
+    SNEP_TRACE_DEBUG1 ("nfa_snep_send_remaining (): dlink:0x%02X", dlink);
+
+    /* while data link connection is not congested */
+    while (  (nfa_snep_cb.conn[dlink].congest == FALSE)
+           &&(nfa_snep_cb.conn[dlink].cur_length > 0)   /* if any fragment was sent */
+           &&(nfa_snep_cb.conn[dlink].cur_length < nfa_snep_cb.conn[dlink].ndef_length)  )
+    {
+        /* start of remaining fragments */
+        p_src = nfa_snep_cb.conn[dlink].p_ndef_buff + nfa_snep_cb.conn[dlink].cur_length;
+
+        length = nfa_snep_cb.conn[dlink].ndef_length - nfa_snep_cb.conn[dlink].cur_length;
+
+        /* sending up to peer's MIU */
+        if (length > nfa_snep_cb.conn[dlink].tx_miu)
+        {
+            length = nfa_snep_cb.conn[dlink].tx_miu;
+        }
+
+        status = LLCP_STATUS_FAIL;
+
+        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL)
+        {
+            p_msg->len    = (UINT16) length;
+            p_msg->offset = LLCP_MIN_OFFSET;
+
+            p_dst = (UINT8*) (p_msg + 1) + p_msg->offset;
+
+            memcpy (p_dst, p_src, length);
+
+            status = LLCP_SendData (nfa_snep_cb.conn[dlink].local_sap,
+                                    nfa_snep_cb.conn[dlink].remote_sap, p_msg);
+
+            if (status != LLCP_STATUS_FAIL)
+            {
+                /* update sent length */
+                nfa_snep_cb.conn[dlink].cur_length += length;
+
+                SNEP_TRACE_DEBUG2 ("nfa_snep_send_remaining (): sending %d out of %d",
+                                   nfa_snep_cb.conn[dlink].cur_length,
+                                   nfa_snep_cb.conn[dlink].ndef_length);
+
+                /* if sent the last fragment */
+                if (nfa_snep_cb.conn[dlink].cur_length == nfa_snep_cb.conn[dlink].ndef_length)
+                {
+                    nfa_snep_cb.conn[dlink].cur_length = 0;
+
+                    if (  (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_RESP_CODE_SUCCESS)
+                        &&(nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_CONTINUE)  )
+                    {
+                        /* Set LLCP to send LLCP_SAP_EVT_TX_COMPLETE */
+                        LLCP_SetTxCompleteNtf (nfa_snep_cb.conn[dlink].local_sap,
+                                               nfa_snep_cb.conn[dlink].remote_sap);
+                    }
+                }
+            }
+        }
+
+        if (status == LLCP_STATUS_CONGESTED)
+        {
+            nfa_snep_cb.conn[dlink].congest = TRUE;
+
+            /* wait for uncongested event from LLCP */
+            break;
+        }
+        else if (status == LLCP_STATUS_FAIL)
+        {
+            SNEP_TRACE_ERROR0 ("Cannot allocate buffer or failed to send data");
+
+            /* upper layer will free buffer when NFA_SNEP_DISC_EVT is received */
+            nfa_snep_cb.conn[dlink].p_ndef_buff = 0;
+
+            LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+            return;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_llcp_cback
+**
+** Description      Processing event from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_llcp_cback (tLLCP_SAP_CBACK_DATA *p_data)
+{
+    SNEP_TRACE_DEBUG2 ("nfa_snep_llcp_cback (): event:0x%02X, local_sap:0x%02X", p_data->hdr.event, p_data->hdr.local_sap);
+
+    switch (p_data->hdr.event)
+    {
+    case LLCP_SAP_EVT_DATA_IND:
+        nfa_snep_proc_llcp_data_ind (p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONNECT_IND:
+        nfa_snep_proc_llcp_connect_ind (p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONNECT_RESP:
+        nfa_snep_proc_llcp_connect_resp (p_data);
+        break;
+
+    case LLCP_SAP_EVT_DISCONNECT_IND:
+        nfa_snep_proc_llcp_disconnect_ind (p_data);
+        break;
+
+    case LLCP_SAP_EVT_DISCONNECT_RESP:
+        nfa_snep_proc_llcp_disconnect_resp (p_data);
+        break;
+
+    case LLCP_SAP_EVT_CONGEST:
+        /* congestion start/end */
+        nfa_snep_proc_llcp_congest (p_data);
+        break;
+
+    case LLCP_SAP_EVT_LINK_STATUS:
+        nfa_snep_proc_llcp_link_status (p_data);
+        break;
+
+    case LLCP_SAP_EVT_TX_COMPLETE:
+        nfa_snep_proc_llcp_tx_complete (p_data);
+        break;
+
+    default:
+        SNEP_TRACE_ERROR1 ("Unknown event:0x%02X", p_data->hdr.event);
+        return;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_validate_rx_msg
+**
+** Description      Validate version, opcode, length in received message
+**
+**
+** Returns          TRUE if message is valid
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_validate_rx_msg (UINT8 dlink)
+{
+    UINT32  length;
+    UINT8   buffer[NFA_SNEP_HEADER_SIZE], *p;
+    BOOLEAN more;
+    UINT8   version, opcode;
+    UINT32  info_len;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_validate_rx_msg ()");
+
+    more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
+                                  nfa_snep_cb.conn[dlink].remote_sap,
+                                  NFA_SNEP_HEADER_SIZE,
+                                  &length, buffer);
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispSNEP(nfa_snep_cb.conn[dlink].local_sap,
+             nfa_snep_cb.conn[dlink].remote_sap,
+             buffer,
+             (UINT16)length,
+             TRUE);
+#endif
+
+    /* check if it has minimum header,
+    ** the first fragment shall include at least the entier SNEP header
+    */
+    if (length < NFA_SNEP_HEADER_SIZE)
+    {
+        SNEP_TRACE_ERROR0 ("The first fragment shall include at least the entire SNEP header");
+
+        /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+        nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+        LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                            nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+        return FALSE;
+    }
+
+    p = buffer;
+
+    /* parse SNEP header */
+    BE_STREAM_TO_UINT8 (version, p);
+    BE_STREAM_TO_UINT8 (opcode,  p);
+    BE_STREAM_TO_UINT32 (info_len, p);
+
+    /* check version of SNEP */
+    if (!nfa_snep_check_version (version))
+    {
+        nfa_snep_send_msg (NFA_SNEP_RESP_CODE_UNSUPP_VER, dlink);
+        return FALSE;
+    }
+
+    /* check valid opcode for server */
+    if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_SERVER)
+    {
+        /* if this is response message */
+        if (opcode & NFA_SNEP_RESP_CODE_CONTINUE)
+        {
+            SNEP_TRACE_ERROR0 ("Invalid opcode for server");
+
+            /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+            return FALSE;
+        }
+        else if (  (opcode != NFA_SNEP_REQ_CODE_CONTINUE)
+                 &&(opcode != NFA_SNEP_REQ_CODE_GET)
+                 &&(opcode != NFA_SNEP_REQ_CODE_PUT)
+                 &&(opcode != NFA_SNEP_REQ_CODE_REJECT)  )
+        {
+            SNEP_TRACE_ERROR0 ("Not supported opcode for server");
+            nfa_snep_send_msg (NFA_SNEP_RESP_CODE_NOT_IMPLM, dlink);
+            return FALSE;
+        }
+    }
+    /* check valid opcode for client */
+    else
+    {
+        if (  (opcode != NFA_SNEP_RESP_CODE_CONTINUE)
+            &&(opcode != NFA_SNEP_RESP_CODE_SUCCESS)
+            &&(opcode != NFA_SNEP_RESP_CODE_NOT_FOUND)
+            &&(opcode != NFA_SNEP_RESP_CODE_EXCESS_DATA)
+            &&(opcode != NFA_SNEP_RESP_CODE_BAD_REQ)
+            &&(opcode != NFA_SNEP_RESP_CODE_NOT_IMPLM)
+            &&(opcode != NFA_SNEP_RESP_CODE_UNSUPP_VER)
+            &&(opcode != NFA_SNEP_RESP_CODE_REJECT)  )
+        {
+            SNEP_TRACE_ERROR0 ("Invalid opcode for client");
+            /* client cannot send error code so disconnect */
+            /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+            return FALSE;
+        }
+    }
+
+    if (opcode == NFA_SNEP_REQ_CODE_GET)
+    {
+        more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
+                                      nfa_snep_cb.conn[dlink].remote_sap,
+                                      NFA_SNEP_ACCEPT_LEN_SIZE,
+                                      &length, buffer);
+
+        if (length < NFA_SNEP_ACCEPT_LEN_SIZE)
+        {
+            /*
+            ** Including acceptable length in the first segment is not mandated in spec
+            ** but MIU is always big enough to include acceptable length field.
+            */
+            nfa_snep_send_msg (NFA_SNEP_RESP_CODE_BAD_REQ, dlink);
+            return FALSE;
+        }
+
+        p = buffer;
+        BE_STREAM_TO_UINT32 (nfa_snep_cb.conn[dlink].acceptable_length, p);
+
+        /* store expected NDEF message length */
+        nfa_snep_cb.conn[dlink].ndef_length = info_len - NFA_SNEP_ACCEPT_LEN_SIZE;
+    }
+    else if (  (opcode == NFA_SNEP_REQ_CODE_PUT)
+             ||((opcode == NFA_SNEP_RESP_CODE_SUCCESS) && (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)))
+    {
+        /* store expected NDEF message length */
+        nfa_snep_cb.conn[dlink].ndef_length = info_len;
+    }
+    else
+    {
+        if (more)
+        {
+            SNEP_TRACE_ERROR0 ("The information field shall not be transmitted with this request or response");
+
+            if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_SERVER)
+            {
+                nfa_snep_send_msg (NFA_SNEP_RESP_CODE_BAD_REQ, dlink);
+            }
+            /* client cannot send error code so disconnect */
+            /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+            return FALSE;
+        }
+    }
+
+    /* store received opcode */
+    nfa_snep_cb.conn[dlink].rx_code = opcode;
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_store_first_rx_msg
+**
+** Description      Allocate buffer and store the first fragment
+**
+**
+** Returns          TRUE if the received fragment is successfully stored
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_store_first_rx_msg (UINT8 dlink)
+{
+    tNFA_SNEP_EVT_DATA evt_data;
+    BOOLEAN            more;
+    UINT32             length;
+
+    /* send event to upper layer of this data link connection to allocate buffer */
+    evt_data.alloc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+    evt_data.alloc.req_code    = nfa_snep_cb.conn[dlink].rx_code;
+    evt_data.alloc.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
+    evt_data.alloc.p_buff      = NULL;
+
+    nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_ALLOC_BUFF_EVT, &evt_data);
+    nfa_snep_cb.conn[dlink].p_ndef_buff = evt_data.alloc.p_buff;
+
+    /* store information into application buffer */
+    if (nfa_snep_cb.conn[dlink].p_ndef_buff)
+    {
+        /* store buffer size */
+        nfa_snep_cb.conn[dlink].buff_length = evt_data.alloc.ndef_length;
+
+        more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
+                                      nfa_snep_cb.conn[dlink].remote_sap,
+                                      nfa_snep_cb.conn[dlink].buff_length,
+                                      &length,
+                                      nfa_snep_cb.conn[dlink].p_ndef_buff);
+
+        /* store received message length */
+        nfa_snep_cb.conn[dlink].cur_length  = (UINT32) length;
+
+        SNEP_TRACE_DEBUG2 ("Received NDEF on SNEP, %d ouf of %d",
+                           nfa_snep_cb.conn[dlink].cur_length,
+                           nfa_snep_cb.conn[dlink].ndef_length);
+
+        /* if fragmented */
+        if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].cur_length)
+        {
+            nfa_snep_cb.conn[dlink].rx_fragments = TRUE;
+        }
+        else if (more)
+        {
+            /* ignore extra bytes in the message */
+            length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
+                                               nfa_snep_cb.conn[dlink].remote_sap);
+
+            SNEP_TRACE_WARNING1 ("Received extra %d bytes on SNEP", length);
+        }
+
+        return TRUE;
+    }
+    else
+    {
+        SNEP_TRACE_ERROR1 ("Upper layer cannot allocate buffer for %d bytes",
+                           nfa_snep_cb.conn[dlink].ndef_length);
+
+        /* clear data in data link connection */
+        length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
+                                           nfa_snep_cb.conn[dlink].remote_sap);
+
+        /* if fragmented */
+        if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].cur_length)
+        {
+            /* notify peer not to send any more fragment */
+            if (evt_data.alloc.resp_code != NFA_SNEP_RESP_CODE_NOT_IMPLM)
+            {
+                /* Set proper code */
+                evt_data.alloc.resp_code = NFA_SNEP_REQ_CODE_REJECT;
+            }
+        }
+        else
+        {
+            if (evt_data.alloc.resp_code != NFA_SNEP_RESP_CODE_NOT_IMPLM)
+            {
+                /* Set proper code */
+                evt_data.alloc.resp_code = NFA_SNEP_RESP_CODE_NOT_FOUND;
+            }
+        }
+
+        nfa_snep_send_msg (evt_data.alloc.resp_code, dlink);
+
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_first_rx_msg
+**
+** Description      Process the first part of received message
+**
+**
+** Returns          TRUE if it is not fragmented message
+**                  FALSE if it is fragmented or found error
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_proc_first_rx_msg (UINT8 dlink)
+{
+    UINT32             length;
+    tNFA_SNEP_EVT_DATA evt_data;
+    BOOLEAN            more;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_first_rx_msg ()");
+
+    /* if version, opcode or length is not valid in received message */
+    if (!nfa_snep_validate_rx_msg (dlink))
+    {
+        /* clear data in data link connection */
+        LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
+                                  nfa_snep_cb.conn[dlink].remote_sap);
+        return FALSE;
+    }
+
+    if (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_GET)
+    {
+        /* if failed to allocate buffer */
+        if (!nfa_snep_store_first_rx_msg (dlink))
+        {
+            return FALSE;
+        }
+        else
+        {
+            if (nfa_snep_cb.conn[dlink].rx_fragments == TRUE)
+            {
+                /* let peer send remaining fragments */
+                nfa_snep_send_msg (NFA_SNEP_RESP_CODE_CONTINUE, dlink);
+
+                return FALSE;
+            }
+        }
+    }
+    else if (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_PUT)
+    {
+        /* if failed to allocate buffer */
+        if (!nfa_snep_store_first_rx_msg (dlink))
+        {
+            return FALSE;
+        }
+        else
+        {
+            if (nfa_snep_cb.conn[dlink].rx_fragments == TRUE)
+            {
+                /* let peer send remaining fragments */
+                nfa_snep_send_msg (NFA_SNEP_RESP_CODE_CONTINUE, dlink);
+                return FALSE;
+            }
+        }
+    }
+    /* if we got response of GET request from server */
+    else if (  (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_RESP_CODE_SUCCESS)
+             &&(nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)  )
+    {
+        /* if server is sending more than acceptable length */
+        if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].acceptable_length)
+        {
+            SNEP_TRACE_ERROR0 ("Server is sending more than acceptable length");
+
+            length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
+                                               nfa_snep_cb.conn[dlink].remote_sap);
+
+            /* if fragmented */
+            if (nfa_snep_cb.conn[dlink].ndef_length > length)
+            {
+                nfa_snep_send_msg (NFA_SNEP_REQ_CODE_REJECT, dlink);
+                nfa_snep_cb.conn[dlink].rx_fragments = FALSE;
+            }
+
+            /* return error to client so buffer can be freed */
+            evt_data.get_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+            evt_data.get_resp.resp_code   = NFA_SNEP_RESP_CODE_EXCESS_DATA;
+            evt_data.get_resp.ndef_length = 0;
+            evt_data.get_resp.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
+
+            nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_EVT, &evt_data);
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            return FALSE;
+        }
+
+        more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
+                                      nfa_snep_cb.conn[dlink].remote_sap,
+                                      nfa_snep_cb.conn[dlink].buff_length,
+                                      &length,
+                                      nfa_snep_cb.conn[dlink].p_ndef_buff);
+
+        /* store received message length */
+        nfa_snep_cb.conn[dlink].cur_length = length;
+
+        SNEP_TRACE_DEBUG2 ("Received NDEF on SNEP, %d ouf of %d",
+                           nfa_snep_cb.conn[dlink].cur_length,
+                           nfa_snep_cb.conn[dlink].ndef_length);
+
+        if (nfa_snep_cb.conn[dlink].ndef_length > nfa_snep_cb.conn[dlink].cur_length)
+        {
+            nfa_snep_cb.conn[dlink].rx_fragments = TRUE;
+        }
+        else if (more)
+        {
+            /* ignore extra bytes in the message */
+            length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
+                                               nfa_snep_cb.conn[dlink].remote_sap);
+
+            SNEP_TRACE_WARNING1 ("Received extra %d bytes on SNEP", length);
+        }
+
+        if (nfa_snep_cb.conn[dlink].rx_fragments == TRUE)
+        {
+            /* let peer send remaining fragments */
+            nfa_snep_send_msg (NFA_SNEP_REQ_CODE_CONTINUE, dlink);
+
+            /* start timer for next fragment */
+            nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
+
+            return FALSE;
+        }
+    }
+
+    /* other than above cases, there is no inforamtion field */
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_assemble_fragments
+**
+** Description      Assemble fragments of SNEP message
+**
+**
+** Returns          TRUE if it is not fragmented message
+**                  FALSE if it is fragmented or found error
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_assemble_fragments (UINT8 dlink)
+{
+    BOOLEAN more;
+    UINT32  length;
+
+    more = LLCP_ReadDataLinkData (nfa_snep_cb.conn[dlink].local_sap,
+                                  nfa_snep_cb.conn[dlink].remote_sap,
+                                  nfa_snep_cb.conn[dlink].buff_length - nfa_snep_cb.conn[dlink].cur_length,
+                                  &length,
+                                  nfa_snep_cb.conn[dlink].p_ndef_buff + nfa_snep_cb.conn[dlink].cur_length);
+
+    nfa_snep_cb.conn[dlink].cur_length += length;
+
+    SNEP_TRACE_DEBUG2 ("Received NDEF on SNEP, %d ouf of %d",
+                       nfa_snep_cb.conn[dlink].cur_length,
+                       nfa_snep_cb.conn[dlink].ndef_length);
+
+    /* if received the last fragment */
+    if (nfa_snep_cb.conn[dlink].ndef_length == nfa_snep_cb.conn[dlink].cur_length)
+    {
+        nfa_snep_cb.conn[dlink].rx_fragments = FALSE;
+
+        if (more)
+        {
+            length = LLCP_FlushDataLinkRxData (nfa_snep_cb.conn[dlink].local_sap,
+                                               nfa_snep_cb.conn[dlink].remote_sap);
+
+            SNEP_TRACE_ERROR2 ("Received extra %d bytes more than NDEF length (%d)",
+                               length,
+                               nfa_snep_cb.conn[dlink].ndef_length);
+
+            /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+
+            return FALSE;
+        }
+    }
+    else
+    {
+        if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CLIENT)
+        {
+            /* wait for more fragments */
+            nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
+        }
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_data_ind
+**
+** Description      Processing incoming data from LLCP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_data_ind (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8              dlink;
+    tNFA_SNEP_EVT_DATA evt_data;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_data_ind ()");
+
+    /* find connection control block with SAP */
+    dlink = nfa_snep_sap_to_index (p_data->data_ind.local_sap,
+                                   p_data->data_ind.remote_sap,
+                                   NFA_SNEP_FLAG_ANY);
+
+    /* if found */
+    if (  (dlink < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+    {
+        if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CLIENT)
+        {
+            /* stop timer for response from server */
+            nfa_sys_stop_timer (&nfa_snep_cb.conn[dlink].timer);
+        }
+
+        /* if received the first fragment or complete SNEP message */
+        if (nfa_snep_cb.conn[dlink].rx_fragments == FALSE)
+        {
+            if (!nfa_snep_proc_first_rx_msg (dlink))
+            {
+                /* need more data or found error */
+                return;
+            }
+        }
+        /* if received other than the first fragment */
+        else
+        {
+            if (!nfa_snep_assemble_fragments (dlink))
+            {
+                /* need more data or found error */
+                return;
+            }
+        }
+
+        /* processing complete SNEP message */
+        switch (nfa_snep_cb.conn[dlink].rx_code)
+        {
+        case NFA_SNEP_REQ_CODE_CONTINUE:
+            if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_W4_REQ_CONTINUE)
+            {
+                nfa_snep_cb.conn[dlink].flags &= ~NFA_SNEP_FLAG_W4_REQ_CONTINUE;
+
+                /* send remaining fragments of GET response */
+                nfa_snep_send_remaining (dlink);
+            }
+            else
+            {
+                SNEP_TRACE_ERROR0 ("Received invalid NFA_SNEP_REQ_CODE_CONTINUE");
+
+                /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+                nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+                LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                    nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+            }
+            break;
+
+        case NFA_SNEP_REQ_CODE_GET:
+            evt_data.get_req.conn_handle       = (NFA_HANDLE_GROUP_SNEP | dlink);
+            evt_data.get_req.acceptable_length = nfa_snep_cb.conn[dlink].acceptable_length;
+
+            /* NDEF message */
+            evt_data.get_req.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
+            evt_data.get_req.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
+
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            /* send event to server of this data link connection */
+            nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_REQ_EVT, &evt_data);
+            break;
+
+        case NFA_SNEP_REQ_CODE_PUT:
+            evt_data.put_req.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+
+            /* NDEF message */
+            evt_data.put_req.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
+            evt_data.put_req.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
+
+            nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+            /* send event to server of this data link connection */
+            nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_PUT_REQ_EVT, &evt_data);
+            break;
+
+        case NFA_SNEP_RESP_CODE_CONTINUE:
+            if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_W4_RESP_CONTINUE)
+            {
+                nfa_snep_cb.conn[dlink].flags &= ~NFA_SNEP_FLAG_W4_RESP_CONTINUE;
+                /* send remaining fragments GET/PUT request */
+                nfa_snep_send_remaining (dlink);
+            }
+            else
+            {
+                SNEP_TRACE_ERROR0 ("Received invalid NFA_SNEP_RESP_CODE_CONTINUE");
+
+                /* application will free buffer when receiving NFA_SNEP_DISC_EVT */
+                nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+                LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                                    nfa_snep_cb.conn[dlink].remote_sap, TRUE);
+            }
+            break;
+
+        case NFA_SNEP_RESP_CODE_SUCCESS:
+            if (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)
+            {
+                evt_data.get_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+                evt_data.get_resp.resp_code   = NFA_SNEP_RESP_CODE_SUCCESS;
+                evt_data.get_resp.ndef_length = nfa_snep_cb.conn[dlink].ndef_length;
+                evt_data.get_resp.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
+
+                nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+
+                /* send event to client of this data link connection */
+                nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_EVT, &evt_data);
+            }
+            else
+            {
+                evt_data.put_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+                evt_data.put_resp.resp_code   = NFA_SNEP_RESP_CODE_SUCCESS;
+
+                /* send event to client of this data link connection */
+                nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_PUT_RESP_EVT, &evt_data);
+            }
+            break;
+
+        case NFA_SNEP_RESP_CODE_NOT_FOUND:
+        case NFA_SNEP_RESP_CODE_EXCESS_DATA:
+        case NFA_SNEP_RESP_CODE_BAD_REQ:
+        case NFA_SNEP_RESP_CODE_NOT_IMPLM:
+        case NFA_SNEP_RESP_CODE_UNSUPP_VER:
+        case NFA_SNEP_RESP_CODE_REJECT:
+            /* if client sent GET request */
+            if (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_GET)
+            {
+                evt_data.get_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+                evt_data.get_resp.resp_code   = nfa_snep_cb.conn[dlink].rx_code;
+                evt_data.get_resp.ndef_length = 0;
+                evt_data.get_resp.p_ndef      = nfa_snep_cb.conn[dlink].p_ndef_buff;
+
+                /* send event to client of this data link connection */
+                nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_EVT, &evt_data);
+            }
+            /* if client sent PUT request */
+            else if (nfa_snep_cb.conn[dlink].tx_code == NFA_SNEP_REQ_CODE_PUT)
+            {
+                evt_data.put_resp.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+                evt_data.put_resp.resp_code   = nfa_snep_cb.conn[dlink].rx_code;
+
+                /* send event to client of this data link connection */
+                nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_PUT_RESP_EVT, &evt_data);
+            }
+
+            /* if there is remaining SNEP message */
+            if (nfa_snep_cb.conn[dlink].p_ndef_buff)
+            {
+                nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+            }
+            break;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_connect_ind
+**
+** Description      Processing connection request from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_connect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8 server, dlink;
+    tLLCP_CONNECTION_PARAMS params;
+    tNFA_SNEP_EVT_DATA      evt_data;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_connect_ind ()");
+
+    server = nfa_snep_sap_to_index (p_data->connect_ind.server_sap,
+                                    NFA_SNEP_ANY_SAP,
+                                    NFA_SNEP_FLAG_SERVER);
+
+    /* if found valid server */
+    if (server < NFA_SNEP_MAX_CONN)
+    {
+        /* allocate connection control block for data link connection */
+        dlink = nfa_snep_allocate_cb ();
+
+        if (dlink < NFA_SNEP_MAX_CONN)
+        {
+            /* set data link connection's callback to server's callback */
+            /* request will be sent to this server */
+            nfa_snep_cb.conn[dlink].local_sap  = p_data->connect_ind.local_sap;
+            nfa_snep_cb.conn[dlink].remote_sap = p_data->connect_ind.remote_sap;
+            nfa_snep_cb.conn[dlink].p_cback    = nfa_snep_cb.conn[server].p_cback;
+            nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CONNECTED;
+
+            nfa_snep_cb.conn[dlink].tx_miu = nfa_snep_get_efficent_miu (p_data->connect_ind.miu,
+                                                                        p_data->connect_ind.rw);
+
+            /* accept connection request */
+            params.miu = NFA_SNEP_MIU;
+            params.rw  = NFA_SNEP_RW;
+            params.sn[0] = 0;
+
+            LLCP_ConnectCfm (p_data->connect_ind.local_sap,
+                             p_data->connect_ind.remote_sap, &params);
+
+            evt_data.connect.reg_handle  = (NFA_HANDLE_GROUP_SNEP | server);
+            evt_data.connect.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+            nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_CONNECTED_EVT, &evt_data);
+        }
+        else
+        {
+            SNEP_TRACE_ERROR0 ("Cannot allocate connection control block");
+            LLCP_ConnectReject (p_data->connect_ind.local_sap,
+                                p_data->connect_ind.remote_sap,
+                                LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
+        }
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Cannot find SNEP server");
+        LLCP_ConnectReject (p_data->connect_ind.local_sap,
+                            p_data->connect_ind.remote_sap,
+                            LLCP_SAP_DM_REASON_NO_SERVICE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_connect_resp
+**
+** Description      Processing connection response from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_connect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8 dlink;
+    tNFA_SNEP_EVT_DATA evt_data;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_connect_resp ()");
+
+    /* find client by SAP */
+    dlink = nfa_snep_sap_to_index (p_data->connect_resp.local_sap,
+                                   NFA_SNEP_ANY_SAP,
+                                   NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTING);
+
+    /* if found client */
+    if (dlink < NFA_SNEP_MAX_CONN)
+    {
+        nfa_snep_cb.conn[dlink].remote_sap = p_data->connect_resp.remote_sap;
+        nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTED;
+
+        nfa_snep_cb.conn[dlink].tx_miu = nfa_snep_get_efficent_miu (p_data->connect_resp.miu,
+                                                                    p_data->connect_resp.rw);
+
+        evt_data.connect.reg_handle  = (NFA_HANDLE_GROUP_SNEP | dlink);
+        evt_data.connect.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+        nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_CONNECTED_EVT, &evt_data);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Cannot find SNEP client");
+        LLCP_DisconnectReq (p_data->connect_resp.local_sap,
+                            p_data->connect_resp.remote_sap, TRUE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_disconnect_ind
+**
+** Description      Processing disconnection request from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_disconnect_ind (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8              dlink;
+    tNFA_SNEP_EVT_DATA evt_data;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_disconnect_ind ()");
+
+    /* find connection control block by SAP */
+    dlink = nfa_snep_sap_to_index (p_data->disconnect_ind.local_sap,
+                                   p_data->disconnect_ind.remote_sap,
+                                   NFA_SNEP_FLAG_ANY);
+
+    /* if found */
+    if (dlink < NFA_SNEP_MAX_CONN)
+    {
+        evt_data.disc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+
+        nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_DISC_EVT, &evt_data);
+
+        if (nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CLIENT)
+        {
+            /* clear other flags */
+            nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_CLIENT;
+            nfa_snep_cb.conn[dlink].remote_sap = LLCP_INVALID_SAP;
+        }
+        else
+        {
+            nfa_snep_deallocate_cb (dlink);
+        }
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Cannot find SNEP connection");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_disconnect_resp
+**
+** Description      Processing rejected connection from peer
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_disconnect_resp (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8              dlink, flags;
+    UINT8              remote_sap;
+    tNFA_SNEP_EVT_DATA evt_data;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_disconnect_resp ()");
+
+    /* if remote sent response to disconnection requested by local */
+    if (p_data->disconnect_resp.reason == LLCP_SAP_DM_REASON_RESP_DISC)
+    {
+        remote_sap = p_data->disconnect_resp.remote_sap;
+        flags      = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTED;
+    }
+    else /* connection failed so we don't have remote SAP */
+    {
+        remote_sap = NFA_SNEP_ANY_SAP;
+        flags      = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTING;
+    }
+
+    /* find connection control block by SAP */
+    dlink = nfa_snep_sap_to_index (p_data->disconnect_resp.local_sap,
+                                   remote_sap,
+                                   flags);
+
+    /* if found client */
+    if (dlink < NFA_SNEP_MAX_CONN)
+    {
+        evt_data.disc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+
+        nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_DISC_EVT, &evt_data);
+
+        /* clear other flags */
+        nfa_snep_cb.conn[dlink].flags      = NFA_SNEP_FLAG_CLIENT;
+        nfa_snep_cb.conn[dlink].remote_sap = LLCP_INVALID_SAP;
+    }
+    else
+    {
+        /* find server connection control block by SAP */
+        dlink = nfa_snep_sap_to_index (p_data->disconnect_resp.local_sap,
+                                       remote_sap,
+                                       NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CONNECTED);
+
+        /* if found server connection */
+        if (dlink < NFA_SNEP_MAX_CONN)
+        {
+            evt_data.disc.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+
+            nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_DISC_EVT, &evt_data);
+
+            nfa_snep_deallocate_cb (dlink);
+        }
+        else
+        {
+            SNEP_TRACE_ERROR0 ("Cannot find SNEP connection");
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_congest
+**
+** Description      Processing LLCP congestion event
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_congest (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8 dlink;
+
+    SNEP_TRACE_DEBUG3 ("nfa_snep_proc_llcp_congest () local_sap=0x%x, remote_sap=0x%x, is_congested=%d",
+                       p_data->congest.local_sap,
+                       p_data->congest.remote_sap,
+                       p_data->congest.is_congested);
+
+    /* if data link connection is congested */
+    if (p_data->congest.link_type == LLCP_LINK_TYPE_DATA_LINK_CONNECTION)
+    {
+        dlink = nfa_snep_sap_to_index (p_data->congest.local_sap,
+                                       p_data->congest.remote_sap,
+                                       NFA_SNEP_FLAG_ANY);
+
+        if (  (dlink < NFA_SNEP_MAX_CONN)
+            &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+        {
+            nfa_snep_cb.conn[dlink].congest = p_data->congest.is_congested;
+
+            if (!nfa_snep_cb.conn[dlink].congest)
+            {
+                /* if received CONTINUE then continue to send remaining fragments */
+                if (  (nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_REQ_CODE_CONTINUE)
+                    ||(nfa_snep_cb.conn[dlink].rx_code == NFA_SNEP_RESP_CODE_CONTINUE)  )
+                {
+                    nfa_snep_send_remaining (dlink);
+                }
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_link_status
+**
+** Description      Processing LLCP link status
+**
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_link_status (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8              xx;
+    tNFA_SNEP_EVT_DATA evt_data;
+
+    SNEP_TRACE_DEBUG1 ("nfa_snep_proc_llcp_link_status () is_activated:%d",
+                       p_data->link_status.is_activated);
+
+    xx = nfa_snep_sap_to_index (p_data->link_status.local_sap,
+                                NFA_SNEP_ANY_SAP,
+                                NFA_SNEP_FLAG_CLIENT);
+
+    if (xx < NFA_SNEP_MAX_CONN)
+    {
+        evt_data.activated.client_handle = (NFA_HANDLE_GROUP_SNEP | xx);
+
+        /* if LLCP link is activated */
+        if (p_data->link_status.is_activated == TRUE)
+        {
+            /* notify only client which may want to connect */
+            nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_ACTIVATED_EVT, &evt_data);
+        }
+        else
+        {
+            /* LLCP link is deactivated */
+            nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_DEACTIVATED_EVT, &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_proc_llcp_tx_complete
+**
+** Description      Processing LLCP tx complete event
+**
+**
+** Returns          none
+**
+*******************************************************************************/
+void nfa_snep_proc_llcp_tx_complete (tLLCP_SAP_CBACK_DATA  *p_data)
+{
+    UINT8              dlink;
+    tNFA_SNEP_EVT_DATA evt_data;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_proc_llcp_tx_complete ()");
+
+    dlink = nfa_snep_sap_to_index (p_data->tx_complete.local_sap,
+                                   p_data->tx_complete.remote_sap,
+                                   NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CONNECTED);
+
+    if (dlink < NFA_SNEP_MAX_CONN)
+    {
+        /* notify upper layer that transmission is complete */
+        evt_data.get_resp_cmpl.conn_handle = (NFA_HANDLE_GROUP_SNEP | dlink);
+        evt_data.get_resp_cmpl.p_buff      = nfa_snep_cb.conn[dlink].p_ndef_buff;
+
+        nfa_snep_cb.conn[dlink].p_cback (NFA_SNEP_GET_RESP_CMPL_EVT, &evt_data);
+        nfa_snep_cb.conn[dlink].p_ndef_buff = NULL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_reg_server
+**
+** Description      Allocate a connection control block as server and register to LLCP
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_reg_server (tNFA_SNEP_MSG *p_msg)
+{
+    tNFA_SNEP_EVT_DATA  evt_data;
+    UINT8               xx, local_sap = LLCP_INVALID_SAP;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_reg_server ()");
+
+    xx = nfa_snep_allocate_cb ();
+
+    if (xx < NFA_SNEP_MAX_CONN)
+    {
+        local_sap = LLCP_RegisterServer (p_msg->api_reg_server.server_sap,
+                                         LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
+                                         p_msg->api_reg_server.service_name,
+                                         nfa_snep_llcp_cback);
+    }
+
+    BCM_STRNCPY_S (evt_data.reg.service_name, sizeof (evt_data.reg.service_name),
+                   p_msg->api_reg_server.service_name, LLCP_MAX_SN_LEN);
+    evt_data.reg.service_name[LLCP_MAX_SN_LEN] = 0x00;
+
+    if ((xx == NFA_SNEP_MAX_CONN) || (local_sap == LLCP_INVALID_SAP))
+    {
+        SNEP_TRACE_ERROR0 ("Cannot allocate or register SNEP server");
+
+        evt_data.reg.status = NFA_STATUS_FAILED;
+        p_msg->api_reg_server.p_cback (NFA_SNEP_REG_EVT, &evt_data);
+        return TRUE;
+    }
+
+    if (!nfa_snep_cb.is_dta_mode)
+    {
+        /* if need to update WKS in LLCP Gen bytes */
+        if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+        {
+            nfa_p2p_enable_listening (NFA_ID_SNEP, TRUE);
+            nfa_snep_cb.listen_enabled = TRUE;
+        }
+        else if (!nfa_snep_cb.listen_enabled)
+        {
+            nfa_p2p_enable_listening (NFA_ID_SNEP, FALSE);
+            nfa_snep_cb.listen_enabled = TRUE;
+        }
+    }
+
+    nfa_snep_cb.conn[xx].local_sap  = local_sap;
+    nfa_snep_cb.conn[xx].remote_sap = LLCP_INVALID_SAP;
+    nfa_snep_cb.conn[xx].p_cback    = p_msg->api_reg_server.p_cback;
+    nfa_snep_cb.conn[xx].flags      = NFA_SNEP_FLAG_SERVER;
+
+    evt_data.reg.status     = NFA_STATUS_OK;
+    evt_data.reg.reg_handle = (NFA_HANDLE_GROUP_SNEP | xx);
+
+    /* notify NFA_SNEP_REG_EVT to application */
+    nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_REG_EVT, &evt_data);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_reg_client
+**
+** Description      Allocate a connection control block as client and register to LLCP
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_reg_client (tNFA_SNEP_MSG *p_msg)
+{
+    tNFA_SNEP_EVT_DATA  evt_data;
+    UINT8               xx, local_sap = LLCP_INVALID_SAP;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_reg_client ()");
+
+    xx = nfa_snep_allocate_cb ();
+
+    if (xx < NFA_SNEP_MAX_CONN)
+    {
+        local_sap = LLCP_RegisterClient (LLCP_LINK_TYPE_DATA_LINK_CONNECTION,
+                                         nfa_snep_llcp_cback);
+    }
+
+    evt_data.reg.service_name[0] = 0x00;
+
+    if ((xx == NFA_SNEP_MAX_CONN) || (local_sap == LLCP_INVALID_SAP))
+    {
+        SNEP_TRACE_ERROR0 ("Cannot allocate or register SNEP client");
+
+        evt_data.reg.status = NFA_STATUS_FAILED;
+        p_msg->api_reg_client.p_cback (NFA_SNEP_REG_EVT, &evt_data);
+        return TRUE;
+    }
+
+    nfa_snep_cb.conn[xx].local_sap  = local_sap;
+    nfa_snep_cb.conn[xx].remote_sap = LLCP_INVALID_SAP;
+    nfa_snep_cb.conn[xx].p_cback    = p_msg->api_reg_client.p_cback;
+    nfa_snep_cb.conn[xx].flags      = NFA_SNEP_FLAG_CLIENT;
+
+    /* initialize timer callback */
+    nfa_snep_cb.conn[xx].timer.p_cback = nfa_snep_timer_cback;
+
+    evt_data.reg.status     = NFA_STATUS_OK;
+    evt_data.reg.reg_handle = (NFA_HANDLE_GROUP_SNEP | xx);
+
+    /* notify NFA_SNEP_REG_EVT to application */
+    nfa_snep_cb.conn[xx].p_cback (NFA_SNEP_REG_EVT, &evt_data);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_dereg
+**
+** Description      Deallocate a connection control block and deregister to LLCP
+**                  LLCP will deallocate any data link connection created for this
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_dereg (tNFA_SNEP_MSG *p_msg)
+{
+    UINT8 xx;
+    UINT8 local_sap;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_dereg ()");
+
+    xx = (UINT8) (p_msg->api_dereg.reg_handle & NFA_HANDLE_MASK);
+
+    if (  (xx < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[xx].p_cback)
+        &&(nfa_snep_cb.conn[xx].flags & (NFA_SNEP_FLAG_SERVER|NFA_SNEP_FLAG_CLIENT))  )
+    {
+        local_sap = nfa_snep_cb.conn[xx].local_sap;
+        LLCP_Deregister (local_sap);
+        nfa_snep_deallocate_cb (xx);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Cannot find SNEP server/client");
+        return TRUE;
+    }
+
+    if (!nfa_snep_cb.is_dta_mode)
+    {
+        if (nfa_snep_cb.listen_enabled)
+        {
+            for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
+            {
+                if (  (nfa_snep_cb.conn[xx].p_cback)
+                    &&(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_SERVER)  )
+                {
+                    break;
+                }
+            }
+
+            if (xx >= NFA_SNEP_MAX_CONN)
+            {
+                /* if need to update WKS in LLCP Gen bytes */
+                if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+                    nfa_p2p_disable_listening (NFA_ID_SNEP, TRUE);
+                else
+                    nfa_p2p_disable_listening (NFA_ID_SNEP, FALSE);
+
+                nfa_snep_cb.listen_enabled = FALSE;
+            }
+            /* if need to update WKS in LLCP Gen bytes */
+            else if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+            {
+                nfa_p2p_enable_listening (NFA_ID_SNEP, TRUE);
+            }
+        }
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_connect
+**
+** Description      Create data link connection for client
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_connect (tNFA_SNEP_MSG *p_msg)
+{
+    tLLCP_CONNECTION_PARAMS conn_params;
+    UINT8 xx;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_connect ()");
+
+    xx = (UINT8) (p_msg->api_connect.client_handle & NFA_HANDLE_MASK);
+
+    if (xx < NFA_SNEP_MAX_CONN)
+    {
+        nfa_snep_cb.conn[xx].congest = FALSE;
+
+        /* Set remote_sap to SDP to find callback in case that link is deactivted before connected */
+        nfa_snep_cb.conn[xx].remote_sap = LLCP_SAP_SDP;
+
+        /* in order to send NFA_SNEP_DISC_EVT in case of connection failure */
+        nfa_snep_cb.conn[xx].flags = NFA_SNEP_FLAG_CLIENT|NFA_SNEP_FLAG_CONNECTING;
+
+        /* create data link connection with server name */
+        conn_params.miu = NFA_SNEP_MIU;
+        conn_params.rw  = NFA_SNEP_RW;
+        BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn),
+                       p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
+        conn_params.sn[LLCP_MAX_SN_LEN] = 0;
+
+        LLCP_ConnectReq (nfa_snep_cb.conn[xx].local_sap, LLCP_SAP_SDP, &conn_params);
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_get_req
+**
+** Description      Send SNEP GET request on data link connection
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_get_req (tNFA_SNEP_MSG *p_msg)
+{
+    UINT8 dlink;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_get_req ()");
+
+    dlink = (UINT8) (p_msg->api_get_req.conn_handle & NFA_HANDLE_MASK);
+
+    if (  (dlink < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+    {
+        nfa_snep_cb.conn[dlink].tx_code           = NFA_SNEP_REQ_CODE_GET;
+        nfa_snep_cb.conn[dlink].buff_length       = p_msg->api_get_req.buff_length;
+        nfa_snep_cb.conn[dlink].ndef_length       = p_msg->api_get_req.ndef_length;
+        nfa_snep_cb.conn[dlink].p_ndef_buff       = p_msg->api_get_req.p_ndef_buff;
+        nfa_snep_cb.conn[dlink].acceptable_length = p_msg->api_get_req.buff_length;
+
+        nfa_snep_send_msg (NFA_SNEP_REQ_CODE_GET, dlink);
+
+        /* start timer for response from server */
+        nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Data link connection is not established");
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_put_req
+**
+** Description      Send SNEP PUT request on data link connection
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_put_req (tNFA_SNEP_MSG *p_msg)
+{
+    UINT8 dlink;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_put_req ()");
+
+    dlink = (UINT8) (p_msg->api_put_req.conn_handle & NFA_HANDLE_MASK);
+
+    if (  (dlink < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+    {
+        nfa_snep_cb.conn[dlink].tx_code     = NFA_SNEP_REQ_CODE_PUT;
+        nfa_snep_cb.conn[dlink].buff_length = p_msg->api_put_req.ndef_length;
+        nfa_snep_cb.conn[dlink].ndef_length = p_msg->api_put_req.ndef_length;
+        nfa_snep_cb.conn[dlink].p_ndef_buff = p_msg->api_put_req.p_ndef_buff;
+
+        nfa_snep_send_msg (NFA_SNEP_REQ_CODE_PUT, dlink);
+
+        /* start timer for response from server */
+        nfa_sys_start_timer (&nfa_snep_cb.conn[dlink].timer, dlink, NFA_SNEP_CLIENT_TIMEOUT);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Data link connection is not established");
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_get_resp
+**
+** Description      Server responds to GET request
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_get_resp (tNFA_SNEP_MSG *p_msg)
+{
+    UINT8 dlink;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_get_resp ()");
+
+    dlink = (UINT8) (p_msg->api_get_resp.conn_handle & NFA_HANDLE_MASK);
+
+    if (  (dlink < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+    {
+        nfa_snep_cb.conn[dlink].buff_length = p_msg->api_get_resp.ndef_length;
+        nfa_snep_cb.conn[dlink].ndef_length = p_msg->api_get_resp.ndef_length;
+        nfa_snep_cb.conn[dlink].p_ndef_buff = p_msg->api_get_resp.p_ndef_buff;
+
+        nfa_snep_cb.conn[dlink].tx_code     = p_msg->api_get_resp.resp_code;
+
+        nfa_snep_send_msg (p_msg->api_get_resp.resp_code, dlink);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Data link connection is not established");
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_put_resp
+**
+** Description      Server responds to PUT request
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_put_resp (tNFA_SNEP_MSG *p_msg)
+{
+    UINT8 dlink;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_put_resp ()");
+
+    dlink = (UINT8) (p_msg->api_put_resp.conn_handle & NFA_HANDLE_MASK);
+
+    if (  (dlink < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+    {
+        nfa_snep_cb.conn[dlink].tx_code = p_msg->api_put_resp.resp_code;
+
+        nfa_snep_send_msg (p_msg->api_put_resp.resp_code, dlink);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Data link connection is not established");
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_disconnect
+**
+** Description      Disconnect data link connection
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_disconnect (tNFA_SNEP_MSG *p_msg)
+{
+    UINT8 dlink;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_disconnect ()");
+
+    dlink = (UINT8) (p_msg->api_disc.conn_handle & NFA_HANDLE_MASK);
+
+    if (  (dlink < NFA_SNEP_MAX_CONN)
+        &&(nfa_snep_cb.conn[dlink].flags & NFA_SNEP_FLAG_CONNECTED)  )
+    {
+        LLCP_DisconnectReq (nfa_snep_cb.conn[dlink].local_sap,
+                            nfa_snep_cb.conn[dlink].remote_sap,
+                            p_msg->api_disc.flush);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Data link connection is not established");
+    }
+    return TRUE;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_snep_opcode
+**
+** Description
+**
+** Returns          string of event
+**
+*******************************************************************************/
+static char *nfa_snep_opcode (UINT8 opcode)
+{
+    switch (opcode)
+    {
+    case NFA_SNEP_REQ_CODE_CONTINUE:
+        return "REQ_CONTINUE";
+    case NFA_SNEP_REQ_CODE_GET:
+        return "REQ_GET";
+    case NFA_SNEP_REQ_CODE_PUT:
+        return "REQ_PUT";
+    case NFA_SNEP_REQ_CODE_REJECT:
+        return "REQ_REJECT";
+
+    case NFA_SNEP_RESP_CODE_CONTINUE:
+        return "RESP_CONTINUE";
+    case NFA_SNEP_RESP_CODE_SUCCESS:
+        return "RESP_SUCCESS";
+    case NFA_SNEP_RESP_CODE_NOT_FOUND:
+        return "RESP_NOT_FOUND";
+    case NFA_SNEP_RESP_CODE_EXCESS_DATA:
+        return "RESP_EXCESS_DATA";
+    case NFA_SNEP_RESP_CODE_BAD_REQ:
+        return "RESP_BAD_REQ";
+    case NFA_SNEP_RESP_CODE_NOT_IMPLM:
+        return "RESP_NOT_IMPLM";
+    case NFA_SNEP_RESP_CODE_UNSUPP_VER:
+        return "RESP_UNSUPP_VER";
+    case NFA_SNEP_RESP_CODE_REJECT:
+        return "RESP_REJECT";
+
+    default:
+        return "Reserved opcode";
+    }
+}
+
+#endif  /* Debug Functions */
+
diff --git a/src/nfa/snep/nfa_snep_api.c b/src/nfa/snep/nfa_snep_api.c
new file mode 100644
index 0000000..d02a7a5
--- /dev/null
+++ b/src/nfa/snep/nfa_snep_api.c
@@ -0,0 +1,620 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  NFA SNEP interface to LLCP
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_snep_int.h"
+#include "nfa_mem_co.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFA_SnepStartDefaultServer
+**
+** Description      This function is called to listen to SAP, 0x04 as SNEP default
+**                  server ("urn:nfc:sn:snep") on LLCP.
+**
+**                  NFA_SNEP_DEFAULT_SERVER_STARTED_EVT without data will be returned.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepStartDefaultServer (tNFA_SNEP_CBACK *p_cback)
+{
+    tNFA_SNEP_API_START_DEFAULT_SERVER *p_msg;
+
+    SNEP_TRACE_API0 ("NFA_SnepStartDefaultServer ()");
+
+    if (p_cback == NULL)
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepStartDefaultServer (): p_cback is NULL");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_START_DEFAULT_SERVER *) GKI_getbuf (sizeof (tNFA_SNEP_API_START_DEFAULT_SERVER))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_START_DEFAULT_SERVER_EVT;
+        p_msg->p_cback   = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepStopDefaultServer
+**
+** Description      This function is called to stop SNEP default server on LLCP.
+**
+**                  NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT without data will be returned.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepStopDefaultServer (tNFA_SNEP_CBACK *p_cback)
+{
+    tNFA_SNEP_API_STOP_DEFAULT_SERVER *p_msg;
+
+    SNEP_TRACE_API0 ("NFA_SnepStopDefaultServer ()");
+
+    if (p_cback == NULL)
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepStopDefaultServer (): p_cback is NULL");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_STOP_DEFAULT_SERVER *) GKI_getbuf (sizeof (tNFA_SNEP_API_STOP_DEFAULT_SERVER))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT;
+        p_msg->p_cback   = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepRegisterServer
+**
+** Description      This function is called to listen to a SAP as SNEP server.
+**
+**                  If server_sap is set to NFA_SNEP_ANY_SAP, then NFA will allocate
+**                  a SAP between LLCP_LOWER_BOUND_SDP_SAP and LLCP_UPPER_BOUND_SDP_SAP
+**
+**                  NFC Forum default SNEP server ("urn:nfc:sn:snep") may be launched
+**                  by NFA_SnepStartDefaultServer().
+**
+**                  NFA_SNEP_REG_EVT will be returned with status, handle and service name.
+**
+** Note:            If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepRegisterServer (UINT8           server_sap,
+                                    char            *p_service_name,
+                                    tNFA_SNEP_CBACK *p_cback)
+{
+    tNFA_SNEP_API_REG_SERVER *p_msg;
+
+    SNEP_TRACE_API2 ("NFA_SnepRegisterServer (): SAP:0x%X, SN:<%s>", server_sap, p_service_name);
+
+    if ((p_service_name == NULL) || (p_cback == NULL))
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepRegisterServer (): p_service_name or p_cback is NULL");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_REG_SERVER *) GKI_getbuf (sizeof (tNFA_SNEP_API_REG_SERVER))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_REG_SERVER_EVT;
+
+        p_msg->server_sap = server_sap;
+
+        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name),
+                       p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+        p_msg->p_cback = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepRegisterClient
+**
+** Description      This function is called to register SNEP client.
+**                  NFA_SNEP_REG_EVT will be returned with status, handle
+**                  and zero-length service name.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_INVALID_PARAM if p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepRegisterClient (tNFA_SNEP_CBACK *p_cback)
+{
+    tNFA_SNEP_API_REG_CLIENT *p_msg;
+
+    SNEP_TRACE_API0 ("NFA_SnepRegisterClient ()");
+
+    if (p_cback == NULL)
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepRegisterClient (): p_cback is NULL");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_REG_CLIENT *) GKI_getbuf (sizeof (tNFA_SNEP_API_REG_CLIENT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_REG_CLIENT_EVT;
+
+        p_msg->p_cback = p_cback;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepDeregister
+**
+** Description      This function is called to stop listening as SNEP server
+**                  or SNEP client. Application shall use reg_handle returned in
+**                  NFA_SNEP_REG_EVT.
+**
+** Note:            If this function is called to de-register a SNEP server and RF
+**                  discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT
+**                  should happen before calling this function
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepDeregister (tNFA_HANDLE reg_handle)
+{
+    tNFA_SNEP_API_DEREG *p_msg;
+    tNFA_HANDLE          xx;
+
+    SNEP_TRACE_API1 ("NFA_SnepDeregister (): reg_handle:0x%X", reg_handle);
+
+    xx = reg_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL)  )
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepDeregister (): Handle is invalid or not registered");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_DEREG *) GKI_getbuf (sizeof (tNFA_SNEP_API_DEREG))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_DEREG_EVT;
+
+        p_msg->reg_handle = reg_handle;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepConnect
+**
+** Description      This function is called by client to create data link connection
+**                  to SNEP server on peer device.
+**
+**                  Client handle and service name of server to connect shall be provided.
+**                  A conn_handle will be returned in NFA_SNEP_CONNECTED_EVT, if
+**                  successfully connected. Otherwise NFA_SNEP_DISC_EVT will be returned.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_INVALID_PARAM if p_service_name or p_cback is NULL
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepConnect (tNFA_HANDLE     client_handle,
+                             char            *p_service_name)
+{
+    tNFA_SNEP_API_CONNECT *p_msg;
+    tNFA_HANDLE            xx;
+
+    SNEP_TRACE_API1 ("NFA_SnepConnect(): client_handle:0x%X", client_handle);
+
+    xx = client_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
+        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_CLIENT))  )
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepConnect (): Client handle is invalid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if (p_service_name == NULL)
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepConnect (): p_service_name is NULL");
+        return (NFA_STATUS_INVALID_PARAM);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_CONNECT*) GKI_getbuf (sizeof (tNFA_SNEP_API_CONNECT))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_CONNECT_EVT;
+
+        p_msg->client_handle = client_handle;
+        BCM_STRNCPY_S (p_msg->service_name, sizeof (p_msg->service_name),
+                       p_service_name, LLCP_MAX_SN_LEN);
+        p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepGet
+**
+** Description      This function is called by client to send GET request.
+**
+**                  Application shall allocate a buffer and put NDEF message with
+**                  desired record type to get from server. NDEF message from server
+**                  will be returned in the same buffer with NFA_SNEP_GET_RESP_EVT.
+**                  The size of buffer will be used as "Acceptable Length".
+**
+**                  NFA_SNEP_GET_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through registered p_cback. Application may free the buffer
+**                  after receiving these events.
+**
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepGet (tNFA_HANDLE     conn_handle,
+                         UINT32          buff_length,
+                         UINT32          ndef_length,
+                         UINT8           *p_ndef_buff)
+{
+    tNFA_SNEP_API_GET_REQ *p_msg;
+    tNFA_HANDLE            xx;
+
+    SNEP_TRACE_API1 ("NFA_SnepGet (): conn_handle:0x%X", conn_handle);
+
+    xx = conn_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
+        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_CLIENT))  )
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepGet (): Connection handle is invalid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_GET_REQ *) GKI_getbuf (sizeof (tNFA_SNEP_API_GET_REQ))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_GET_REQ_EVT;
+
+        p_msg->conn_handle = conn_handle;
+        p_msg->buff_length = buff_length;
+        p_msg->ndef_length = ndef_length;
+        p_msg->p_ndef_buff = p_ndef_buff;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepPut
+**
+** Description      This function is called by client to send PUT request.
+**
+**                  Application shall allocate a buffer and put desired NDEF message
+**                  to send to server.
+**
+**                  NFA_SNEP_PUT_RESP_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through registered p_cback. Application may free the buffer after
+**                  receiving these events.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepPut (tNFA_HANDLE     conn_handle,
+                         UINT32          ndef_length,
+                         UINT8           *p_ndef_buff)
+{
+    tNFA_SNEP_API_PUT_REQ *p_msg;
+    tNFA_HANDLE            xx;
+
+    SNEP_TRACE_API1 ("NFA_SnepPut (): conn_handle:0x%X", conn_handle);
+
+    xx = conn_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
+        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_CLIENT))  )
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepPut (): Connection handle is invalid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_PUT_REQ *) GKI_getbuf (sizeof (tNFA_SNEP_API_PUT_REQ))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_PUT_REQ_EVT;
+
+        p_msg->conn_handle = conn_handle;
+        p_msg->ndef_length = ndef_length;
+        p_msg->p_ndef_buff = p_ndef_buff;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepGetResponse
+**
+** Description      This function is called by server to send response of GET request.
+**
+**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+**                  it shall allocate a buffer for incoming NDEF message and
+**                  pass the pointer within callback context. This buffer will be
+**                  returned with NFA_SNEP_GET_REQ_EVT after receiving complete
+**                  NDEF message. If buffer is not allocated, NFA_SNEP_RESP_CODE_NOT_FOUND
+**                  (Note:There is no proper response code for this case)
+**                  or NFA_SNEP_RESP_CODE_REJECT will be sent to client.
+**
+**                  Server application shall provide conn_handle which is received in
+**                  NFA_SNEP_GET_REQ_EVT.
+**
+**                  Server application shall allocate a buffer and put NDEF message if
+**                  response code is NFA_SNEP_RESP_CODE_SUCCESS. Otherwise, ndef_length
+**                  shall be set to zero.
+**
+**                  NFA_SNEP_GET_RESP_CMPL_EVT or NFA_SNEP_DISC_EVT will be returned
+**                  through registered callback function. Application may free
+**                  the buffer after receiving these events.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepGetResponse (tNFA_HANDLE         conn_handle,
+                                 tNFA_SNEP_RESP_CODE resp_code,
+                                 UINT32              ndef_length,
+                                 UINT8               *p_ndef_buff)
+{
+    tNFA_SNEP_API_GET_RESP *p_msg;
+    tNFA_HANDLE            xx;
+
+    SNEP_TRACE_API1 ("NFA_SnepGetResponse (): conn_handle:0x%X", conn_handle);
+
+    xx = conn_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
+        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_SERVER))  )
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepGetResponse (): Handle is invalid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_GET_RESP *) GKI_getbuf (sizeof (tNFA_SNEP_API_GET_RESP))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_GET_RESP_EVT;
+
+        p_msg->conn_handle = conn_handle;
+        p_msg->resp_code   = resp_code;
+        p_msg->ndef_length = ndef_length;
+        p_msg->p_ndef_buff = p_ndef_buff;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+
+/*******************************************************************************
+**
+** Function         NFA_SnepPutResponse
+**
+** Description      This function is called by server to send response of PUT request.
+**
+**                  When server application receives NFA_SNEP_ALLOC_BUFF_EVT,
+**                  it shall allocate a buffer for incoming NDEF message and
+**                  pass the pointer within callback context. This buffer will be
+**                  returned with NFA_SNEP_PUT_REQ_EVT after receiving complete
+**                  NDEF message.  If buffer is not allocated, NFA_SNEP_RESP_CODE_REJECT
+**                  will be sent to client or NFA will discard request and send
+**                  NFA_SNEP_RESP_CODE_SUCCESS (Note:There is no proper response code for
+**                  this case).
+**
+**                  Server application shall provide conn_handle which is received in
+**                  NFA_SNEP_PUT_REQ_EVT.
+**
+**                  NFA_SNEP_DISC_EVT will be returned through registered callback
+**                  function when client disconnects data link connection.
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepPutResponse (tNFA_HANDLE         conn_handle,
+                                 tNFA_SNEP_RESP_CODE resp_code)
+{
+    tNFA_SNEP_API_PUT_RESP *p_msg;
+    tNFA_HANDLE            xx;
+
+    SNEP_TRACE_API1 ("NFA_SnepPutResponse (): conn_handle:0x%X", conn_handle);
+
+    xx = conn_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL)
+        ||(!(nfa_snep_cb.conn[xx].flags & NFA_SNEP_FLAG_SERVER))  )
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepPutResponse (): Handle is invalid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_PUT_RESP *) GKI_getbuf (sizeof (tNFA_SNEP_API_PUT_RESP))) != NULL)
+    {
+        p_msg->hdr.event = NFA_SNEP_API_PUT_RESP_EVT;
+
+        p_msg->conn_handle = conn_handle;
+        p_msg->resp_code   = resp_code;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepDisconnect
+**
+** Description      This function is called to disconnect data link connection.
+**                  discard any pending data if flush is set to TRUE
+**
+**                  Client application shall provide conn_handle in NFA_SNEP_GET_RESP_EVT
+**                  or NFA_SNEP_PUT_RESP_EVT.
+**
+**                  Server application shall provide conn_handle in NFA_SNEP_GET_REQ_EVT
+**                  or NFA_SNEP_PUT_REQ_EVT.
+**
+**                  NFA_SNEP_DISC_EVT will be returned
+**
+** Returns          NFA_STATUS_OK if successfully initiated
+**                  NFA_STATUS_BAD_HANDLE if handle is not valid
+**                  NFA_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tNFA_STATUS NFA_SnepDisconnect (tNFA_HANDLE conn_handle, BOOLEAN flush)
+{
+    tNFA_SNEP_API_DISCONNECT *p_msg;
+    tNFA_HANDLE              xx;
+
+    SNEP_TRACE_API2 ("NFA_SnepDisconnect (): conn_handle:0x%X, flush=%d", conn_handle, flush);
+
+    xx = conn_handle & NFA_HANDLE_MASK;
+
+    if (  (xx >= NFA_SNEP_MAX_CONN)
+        ||(nfa_snep_cb.conn[xx].p_cback == NULL))
+    {
+        SNEP_TRACE_ERROR0 ("NFA_SnepDisconnect (): Handle is invalid");
+        return (NFA_STATUS_BAD_HANDLE);
+    }
+
+    if ((p_msg = (tNFA_SNEP_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_SNEP_API_DISCONNECT))) != NULL)
+    {
+        p_msg->hdr.event   = NFA_SNEP_API_DISCONNECT_EVT;
+        p_msg->conn_handle = conn_handle;
+        p_msg->flush       = flush;
+
+        nfa_sys_sendmsg (p_msg);
+
+        return (NFA_STATUS_OK);
+    }
+
+    return (NFA_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function         NFA_SnepSetTraceLevel
+**
+** Description      This function sets the trace level for SNEP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFA_SnepSetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        nfa_snep_cb.trace_level = new_level;
+
+    return (nfa_snep_cb.trace_level);
+}
diff --git a/src/nfa/snep/nfa_snep_default.c b/src/nfa/snep/nfa_snep_default.c
new file mode 100644
index 0000000..07f3061
--- /dev/null
+++ b/src/nfa/snep/nfa_snep_default.c
@@ -0,0 +1,282 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the implementation file for the NFA SNEP default server.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_snep_int.h"
+#include "nfa_mem_co.h"
+#include "nfa_dm_int.h"
+#include "trace_api.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_SNEP_DEFAULT_CB nfa_snep_default_cb;
+#endif
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         nfa_snep_default_init
+**
+** Description      Initialize NFA SNEP default server
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_default_init (void)
+{
+    UINT8 xx;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_default_init ()");
+
+    /* initialize control block */
+    memset (&nfa_snep_default_cb, 0, sizeof (tNFA_SNEP_DEFAULT_CB));
+
+    /* initialize non-zero value */
+    nfa_snep_default_cb.server_handle = NFA_HANDLE_INVALID;
+
+    for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
+    {
+        nfa_snep_default_cb.conn[xx].conn_handle = NFA_HANDLE_INVALID;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_default_service_cback
+**
+** Description      Processing event to default SNEP server/client
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_default_service_cback (tNFA_SNEP_EVT event, tNFA_SNEP_EVT_DATA *p_data)
+{
+    UINT8 xx;
+    tNFA_SNEP_API_DISCONNECT api_disconnect;
+    tNFA_SNEP_API_PUT_RESP   api_put_resp;
+
+    SNEP_TRACE_DEBUG1 ("nfa_snep_default_service_cback () event:0x%X", event);
+
+    switch (event)
+    {
+    case NFA_SNEP_REG_EVT:
+        if (p_data->reg.status == NFA_STATUS_OK)
+        {
+            nfa_snep_default_cb.server_handle = p_data->reg.reg_handle;
+        }
+        else
+        {
+            SNEP_TRACE_ERROR0 ("Default SNEP server failed to register");
+        }
+        break;
+
+    case NFA_SNEP_CONNECTED_EVT:
+        if (p_data->connect.reg_handle == nfa_snep_default_cb.server_handle)
+        {
+            for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
+            {
+                if (nfa_snep_default_cb.conn[xx].conn_handle == NFA_HANDLE_INVALID)
+                {
+                    nfa_snep_default_cb.conn[xx].conn_handle = p_data->connect.conn_handle;
+                    break;
+                }
+            }
+
+            if (xx >= NFA_SNEP_DEFAULT_MAX_CONN)
+            {
+                SNEP_TRACE_ERROR1 ("Default SNEP server cannot handle more than %d connections",
+                                  NFA_SNEP_DEFAULT_MAX_CONN);
+
+                api_disconnect.conn_handle = p_data->connect.conn_handle;
+                api_disconnect.flush       = TRUE;
+                nfa_snep_disconnect ((tNFA_SNEP_MSG *) &api_disconnect);
+            }
+        }
+        break;
+
+    case NFA_SNEP_ALLOC_BUFF_EVT:
+        if (p_data->alloc.req_code == NFA_SNEP_REQ_CODE_GET)
+        {
+            /*
+            ** Default server doesn't support GET
+            ** Send NFA_SNEP_RESP_CODE_NOT_IMPLM to peer
+            */
+            SNEP_TRACE_WARNING0 ("Default SNEP server doesn't support GET");
+            p_data->alloc.p_buff    = NULL;
+            p_data->alloc.resp_code = NFA_SNEP_RESP_CODE_NOT_IMPLM;
+        }
+        else /* NFA_SNEP_REQ_CODE_PUT */
+        {
+            p_data->alloc.p_buff = NULL;
+
+            for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
+            {
+                if (nfa_snep_default_cb.conn[xx].conn_handle == p_data->alloc.conn_handle)
+                {
+                    if (p_data->alloc.ndef_length <= NFA_SNEP_DEFAULT_SERVER_MAX_NDEF_SIZE)
+                    {
+                        /* allocate memory, allocated buffer will be returned in NFA_SNEP_PUT_REQ_EVT */
+                        p_data->alloc.p_buff = (UINT8*) nfa_mem_co_alloc (p_data->alloc.ndef_length);
+                    }
+
+                    /* store buffer pointer in case of failure in the middle */
+                    nfa_snep_default_cb.conn[xx].p_rx_ndef = p_data->alloc.p_buff;
+                    break;
+                }
+            }
+        }
+        break;
+
+    case NFA_SNEP_PUT_REQ_EVT:
+        for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
+        {
+            if (nfa_snep_default_cb.conn[xx].conn_handle == p_data->put_req.conn_handle)
+            {
+                if (!nfa_snep_cb.is_dta_mode)
+                {
+                    nfa_dm_ndef_handle_message (NFA_STATUS_OK,
+                                                p_data->put_req.p_ndef,
+                                                p_data->put_req.ndef_length);
+                }
+#if (BT_TRACE_PROTOCOL == TRUE)
+                else
+                {
+                    DispNDEFMsg (p_data->put_req.p_ndef,
+                                 p_data->put_req.ndef_length, TRUE);
+                }
+#endif
+
+                nfa_mem_co_free (p_data->put_req.p_ndef);
+                nfa_snep_default_cb.conn[xx].p_rx_ndef = NULL;
+
+                api_put_resp.conn_handle = p_data->put_req.conn_handle;
+                api_put_resp.resp_code   = NFA_SNEP_RESP_CODE_SUCCESS;
+
+                nfa_snep_put_resp ((tNFA_SNEP_MSG *) &api_put_resp);
+                break;
+            }
+        }
+        break;
+
+    case NFA_SNEP_DISC_EVT:
+        for (xx = 0; xx < NFA_SNEP_DEFAULT_MAX_CONN; xx++)
+        {
+            if (nfa_snep_default_cb.conn[xx].conn_handle == p_data->disc.conn_handle)
+            {
+                nfa_snep_default_cb.conn[xx].conn_handle = NFA_HANDLE_INVALID;
+
+                /* if buffer is not freed */
+                if (nfa_snep_default_cb.conn[xx].p_rx_ndef)
+                {
+                    nfa_mem_co_free (nfa_snep_default_cb.conn[xx].p_rx_ndef);
+                    nfa_snep_default_cb.conn[xx].p_rx_ndef  = NULL;
+                }
+                break;
+            }
+        }
+        break;
+
+    default:
+        SNEP_TRACE_ERROR0 ("Unexpected event for default SNEP server");
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_start_default_server
+**
+** Description      Launching default SNEP server
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_start_default_server (tNFA_SNEP_MSG *p_msg)
+{
+    tNFA_SNEP_API_REG_SERVER msg;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_start_default_server ()");
+
+    if (nfa_snep_default_cb.server_handle == NFA_HANDLE_INVALID)
+    {
+        msg.server_sap = NFA_SNEP_DEFAULT_SERVER_SAP;
+
+        BCM_STRNCPY_S (msg.service_name, sizeof (msg.service_name),
+                      "urn:nfc:sn:snep", LLCP_MAX_SN_LEN);
+        msg.service_name[LLCP_MAX_SN_LEN] = 0;
+
+        msg.p_cback = nfa_snep_default_service_cback;
+        nfa_snep_reg_server ((tNFA_SNEP_MSG *) &msg);
+    }
+
+    (*p_msg->api_start_default_server.p_cback) (NFA_SNEP_DEFAULT_SERVER_STARTED_EVT, NULL);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_stop_default_server
+**
+** Description      Stoppping default SNEP server
+**
+**
+** Returns          TRUE to deallocate message
+**
+*******************************************************************************/
+BOOLEAN nfa_snep_stop_default_server (tNFA_SNEP_MSG *p_msg)
+{
+    tNFA_SNEP_API_DEREG msg;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_stop_default_server ()");
+
+    if (nfa_snep_default_cb.server_handle != NFA_HANDLE_INVALID)
+    {
+        msg.reg_handle = nfa_snep_default_cb.server_handle;
+
+        nfa_snep_dereg ((tNFA_SNEP_MSG *) &msg);
+
+        nfa_snep_default_cb.server_handle = NFA_HANDLE_INVALID;
+    }
+
+    (*p_msg->api_stop_default_server.p_cback) (NFA_SNEP_DEFAULT_SERVER_STOPPED_EVT, NULL);
+
+    return TRUE;
+}
+
diff --git a/src/nfa/snep/nfa_snep_main.c b/src/nfa/snep/nfa_snep_main.c
new file mode 100644
index 0000000..b2ef6c1
--- /dev/null
+++ b/src/nfa/snep/nfa_snep_main.c
@@ -0,0 +1,219 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA SNEP.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_snep_int.h"
+
+/*****************************************************************************
+**  Global Variables
+*****************************************************************************/
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_SNEP_CB nfa_snep_cb;
+#endif
+
+/*****************************************************************************
+**  Static Functions
+*****************************************************************************/
+
+/* event handler function type */
+static BOOLEAN nfa_snep_evt_hdlr (BT_HDR *p_msg);
+
+/* disable function type */
+static void nfa_snep_sys_disable (void);
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *nfa_snep_evt_code (UINT16 evt_code);
+#endif
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+static const tNFA_SYS_REG nfa_snep_sys_reg =
+{
+    NULL,
+    nfa_snep_evt_hdlr,
+    nfa_snep_sys_disable,
+    NULL
+};
+
+#define NFA_SNEP_NUM_ACTIONS  (NFA_SNEP_LAST_EVT & 0x00ff)
+
+/* type for action functions */
+typedef BOOLEAN (*tNFA_SNEP_ACTION) (tNFA_SNEP_MSG *p_data);
+
+/* action function list */
+const tNFA_SNEP_ACTION nfa_snep_action[] =
+{
+    nfa_snep_start_default_server,          /* NFA_SNEP_API_START_DEFAULT_SERVER_EVT */
+    nfa_snep_stop_default_server,           /* NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT  */
+    nfa_snep_reg_server,                    /* NFA_SNEP_API_REG_SERVER_EVT           */
+    nfa_snep_reg_client,                    /* NFA_SNEP_API_REG_CLIENT_EVT           */
+    nfa_snep_dereg,                         /* NFA_SNEP_API_DEREG_EVT                */
+    nfa_snep_connect,                       /* NFA_SNEP_API_CONNECT_EVT              */
+    nfa_snep_get_req,                       /* NFA_SNEP_API_GET_REQ_EVT              */
+    nfa_snep_put_req,                       /* NFA_SNEP_API_PUT_REQ_EVT              */
+    nfa_snep_get_resp,                      /* NFA_SNEP_API_GET_RESP_EVT             */
+    nfa_snep_put_resp,                      /* NFA_SNEP_API_PUT_RESP_EVT             */
+    nfa_snep_disconnect                     /* NFA_SNEP_API_DISCONNECT_EVT           */
+};
+
+/*******************************************************************************
+**
+** Function         nfa_snep_init
+**
+** Description      Initialize NFA SNEP
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfa_snep_init (BOOLEAN is_dta_mode)
+{
+    /* initialize control block */
+    memset (&nfa_snep_cb, 0, sizeof (tNFA_SNEP_CB));
+    nfa_snep_cb.trace_level = APPL_INITIAL_TRACE_LEVEL;
+    nfa_snep_cb.is_dta_mode = is_dta_mode;
+
+    SNEP_TRACE_DEBUG1 ("nfa_snep_init (): is_dta_mode=%d", is_dta_mode);
+
+    nfa_snep_default_init ();
+
+    /* register message handler on NFA SYS */
+    nfa_sys_register (NFA_ID_SNEP,  &nfa_snep_sys_reg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_sys_disable
+**
+** Description      Clean up and deregister NFA SNEP from NFA SYS/DM
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+static void nfa_snep_sys_disable (void)
+{
+    UINT8 xx;
+
+    SNEP_TRACE_DEBUG0 ("nfa_snep_sys_disable ()");
+
+    /* deallocate any buffer and deregister from LLCP */
+    for (xx = 0; xx < NFA_SNEP_MAX_CONN; xx++)
+    {
+        if (nfa_snep_cb.conn[xx].p_cback != NULL)
+        {
+            LLCP_Deregister (nfa_snep_cb.conn[xx].local_sap);
+            nfa_snep_deallocate_cb (xx);
+        }
+    }
+
+    /* deregister message handler on NFA SYS */
+    nfa_sys_deregister (NFA_ID_SNEP);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_snep_evt_hdlr
+**
+** Description      Processing event for NFA SNEP
+**
+**
+** Returns          TRUE if p_msg needs to be deallocated
+**
+*******************************************************************************/
+static BOOLEAN nfa_snep_evt_hdlr (BT_HDR *p_hdr)
+{
+    BOOLEAN delete_msg = TRUE;
+    UINT16  event;
+
+    tNFA_SNEP_MSG *p_msg = (tNFA_SNEP_MSG *) p_hdr;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    SNEP_TRACE_DEBUG1 ("nfa_snep_evt_hdlr (): Event [%s]", nfa_snep_evt_code (p_msg->hdr.event));
+#else
+    SNEP_TRACE_DEBUG1 ("nfa_snep_evt_hdlr(): Event 0x%02x", p_msg->hdr.event);
+#endif
+
+    event = p_msg->hdr.event & 0x00ff;
+
+    /* execute action functions */
+    if (event < NFA_SNEP_NUM_ACTIONS)
+    {
+        delete_msg = (*nfa_snep_action[event]) (p_msg);
+    }
+    else
+    {
+        SNEP_TRACE_ERROR0 ("Unhandled event");
+    }
+
+    return delete_msg;
+}
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfa_snep_evt_code
+**
+** Description
+**
+** Returns          string of event
+**
+*******************************************************************************/
+static char *nfa_snep_evt_code (UINT16 evt_code)
+{
+    switch (evt_code)
+    {
+    case NFA_SNEP_API_START_DEFAULT_SERVER_EVT:
+        return "API_START_DEFAULT_SERVER";
+    case NFA_SNEP_API_STOP_DEFAULT_SERVER_EVT:
+        return "API_STOP_DEFAULT_SERVER";
+    case NFA_SNEP_API_REG_SERVER_EVT:
+        return "API_REG_SERVER";
+    case NFA_SNEP_API_REG_CLIENT_EVT:
+        return "API_REG_CLIENT";
+    case NFA_SNEP_API_DEREG_EVT:
+        return "API_DEREG";
+    case NFA_SNEP_API_CONNECT_EVT:
+        return "API_CONNECT";
+    case NFA_SNEP_API_GET_REQ_EVT:
+        return "API_GET_REQ";
+    case NFA_SNEP_API_PUT_REQ_EVT:
+        return "API_PUT_REQ";
+    case NFA_SNEP_API_GET_RESP_EVT:
+        return "API_GET_RESP";
+    case NFA_SNEP_API_PUT_RESP_EVT:
+        return "API_PUT_RESP";
+    case NFA_SNEP_API_DISCONNECT_EVT:
+        return "API_DISCONNECT";
+    default:
+        return "Unknown event";
+    }
+}
+#endif  /* Debug Functions */
diff --git a/src/nfa/sys/nfa_sys_cback.c b/src/nfa/sys/nfa_sys_cback.c
new file mode 100644
index 0000000..174fe28
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_cback.c
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Registration/deregistration functions for inter-module callbacks
+ *
+ ******************************************************************************/
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+
+
+
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_reg_enable_complete
+**
+** Description      Called to register an initialization complete callback function
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_reg_enable_complete (tNFA_SYS_ENABLE_CBACK *p_cback)
+{
+    nfa_sys_cb.p_enable_cback = p_cback;
+    nfa_sys_cb.enable_cplt_flags = 0;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_notify_enable_complete
+**
+** Description      Called by other NFA subsystems to notify initialization is
+**                  complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_notify_enable_complete (UINT8 id)
+{
+    nfa_sys_cb.enable_cplt_flags |= (0x0001 << id);
+
+    NFA_TRACE_DEBUG2 ("nfa_sys_cback_notify_enable_complete () enable_cplt_flags=0x%x, enable_cplt_mask=0x%x",
+                       nfa_sys_cb.enable_cplt_flags, nfa_sys_cb.enable_cplt_mask);
+
+    if (  (nfa_sys_cb.enable_cplt_flags == nfa_sys_cb.enable_cplt_mask)
+        &&(nfa_sys_cb.p_enable_cback)  )
+    {
+        nfa_sys_cb.p_enable_cback ();
+        nfa_sys_cb.p_enable_cback = NULL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_reg_nfcc_power_mode_proc_complete
+**
+** Description      Called to register a callback function for complete of processing
+**                  NFCC power mode change from NFA sub-systems
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_reg_nfcc_power_mode_proc_complete (tNFA_SYS_PROC_NFCC_PWR_MODE_CMPL *p_cback)
+{
+    nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback = p_cback;
+    nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags   = 0;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_cback_notify_nfcc_power_mode_proc_complete
+**
+** Description      Called by other NFA subsystems to notify processing NFCC power
+**                  mode is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_cback_notify_nfcc_power_mode_proc_complete (UINT8 id)
+{
+    nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags |= (0x0001 << id);
+
+    NFA_TRACE_DEBUG2 ("nfa_sys_cback_notify_nfcc_power_mode_proc_complete () flags=0x%x, mask=0x%x",
+                       nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags,
+                       nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask);
+
+    if (  (nfa_sys_cb.proc_nfcc_pwr_mode_cplt_flags == nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask) /* except SYS */
+        &&(nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback)  )
+    {
+        nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback ();
+        nfa_sys_cb.p_proc_nfcc_pwr_mode_cmpl_cback = NULL;
+    }
+}
diff --git a/src/nfa/sys/nfa_sys_cfg.c b/src/nfa/sys/nfa_sys_cfg.c
new file mode 100644
index 0000000..9b60ea7
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_cfg.c
@@ -0,0 +1,40 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains compile-time configurable constants for the NFA
+ *  system manager.
+ *
+ ******************************************************************************/
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nfa_sys.h"
+
+const tNFA_SYS_CFG nfa_sys_cfg =
+{
+    NFA_MBOX_EVT_MASK,          /* GKI mailbox event */
+    NFA_MBOX_ID,                /* GKI mailbox id */
+    NFA_TIMER_ID,               /* GKI timer id */
+    APPL_INITIAL_TRACE_LEVEL    /* initial trace level */
+};
+
+tNFA_SYS_CFG *p_nfa_sys_cfg = (tNFA_SYS_CFG *) &nfa_sys_cfg;
+
+
diff --git a/src/nfa/sys/nfa_sys_main.c b/src/nfa/sys/nfa_sys_main.c
new file mode 100644
index 0000000..de8b115
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_main.c
@@ -0,0 +1,418 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This is the main implementation file for the NFA system manager.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfa_api.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+#include "nfa_sys_ptim.h"
+#include "nfa_dm_int.h"
+
+/* protocol timer update period, in milliseconds */
+#ifndef NFA_SYS_TIMER_PERIOD
+#define NFA_SYS_TIMER_PERIOD            10
+#endif
+
+/* system manager control block definition */
+#if NFA_DYNAMIC_MEMORY == FALSE
+tNFA_SYS_CB nfa_sys_cb = {0};   /* nfa_sys control block. statically initialize 'flags' field to 0 */
+#endif
+
+/*******************************************************************************
+**
+** Function         nfa_sys_init
+**
+** Description      NFA initialization; called from task initialization.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_init (void)
+{
+    memset (&nfa_sys_cb, 0, sizeof (tNFA_SYS_CB));
+    nfa_sys_cb.flags |= NFA_SYS_FL_INITIALIZED;
+    nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer);
+    nfa_sys_cb.trace_level = p_nfa_sys_cfg->trace_level;
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function         nfa_sys_event
+**
+** Description      BTA event handler; called from task event handler.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_event (BT_HDR *p_msg)
+{
+    UINT8       id;
+    BOOLEAN     freebuf = TRUE;
+
+    NFA_TRACE_EVENT1 ("NFA got event 0x%04X", p_msg->event);
+
+    /* get subsystem id from event */
+    id = (UINT8) (p_msg->event >> 8);
+
+    /* verify id and call subsystem event handler */
+    if ((id < NFA_ID_MAX) && (nfa_sys_cb.is_reg[id]))
+    {
+        freebuf = (*nfa_sys_cb.reg[id]->evt_hdlr) (p_msg);
+    }
+    else
+    {
+        NFA_TRACE_WARNING1 ("NFA got unregistered event id %d", id);
+    }
+
+    if (freebuf)
+    {
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_timer_update
+**
+** Description      Update the BTA timer list and handle expired timers.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_timer_update (void)
+{
+    if (!nfa_sys_cb.timers_disabled)
+    {
+        nfa_sys_ptim_timer_update (&nfa_sys_cb.ptim_cb);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_register
+**
+** Description      Called by other BTA subsystems to register their event
+**                  handler.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_register (UINT8 id, const tNFA_SYS_REG *p_reg)
+{
+    nfa_sys_cb.reg[id] = (tNFA_SYS_REG *) p_reg;
+    nfa_sys_cb.is_reg[id] = TRUE;
+
+    if ((id != NFA_ID_DM) && (id != NFA_ID_SYS))
+        nfa_sys_cb.enable_cplt_mask |= (0x0001 << id);
+
+    if (id != NFA_ID_SYS)
+    {
+        if (p_reg->proc_nfcc_pwr_mode)
+            nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask |= (0x0001 << id);
+    }
+
+    NFA_TRACE_DEBUG2 ("nfa_sys_register () id=%i, enable_cplt_mask=0x%x",
+                       id, nfa_sys_cb.enable_cplt_mask);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_sys_check_disabled
+**
+** Description      If all subsystems above DM have been disabled, then
+**                  disable DM. Called during NFA shutdown
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_check_disabled (void)
+{
+    UINT8 id;
+    UINT8 done = TRUE;
+
+    /* Check if all subsystems above DM have been disabled. */
+    for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++)
+    {
+        if (nfa_sys_cb.is_reg[id])
+        {
+            /* as long as one subsystem is not done */
+            done = FALSE;
+            break;
+        }
+    }
+
+    /* All subsystems disabled. disable DM */
+    if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM]))
+    {
+        (*nfa_sys_cb.reg[NFA_ID_DM]->disable) ();
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_sys_deregister
+**
+** Description      Called by other BTA subsystems to de-register
+**                  handler.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_deregister (UINT8 id)
+{
+    NFA_TRACE_DEBUG1 ("nfa_sys: deregistering subsystem %i", id);
+
+    nfa_sys_cb.is_reg[id] = FALSE;
+
+    /* If not deregistering DM, then check if any other subsystems above DM are still  */
+    /* registered.                                                                  */
+    if (id != NFA_ID_DM)
+    {
+        /* If all subsystems above NFA_DM have been disabled, then okay to disable DM */
+        nfa_sys_check_disabled ();
+    }
+    else
+    {
+        /* DM (the final sub-system) is deregistering. Clear pending timer events in nfa_sys. */
+        nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_is_register
+**
+** Description      Called by other BTA subsystems to get registeration
+**                  status.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN nfa_sys_is_register (UINT8 id)
+{
+    return nfa_sys_cb.is_reg[id];
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_is_graceful_disable
+**
+** Description      Called by other BTA subsystems to get disable
+**                  parameter.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN nfa_sys_is_graceful_disable (void)
+{
+    return nfa_sys_cb.graceful_disable;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_enable_subsystems
+**
+** Description      Call on NFA Start up
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_enable_subsystems (void)
+{
+    UINT8 id;
+
+    NFA_TRACE_DEBUG0 ("nfa_sys: enabling subsystems");
+
+    /* Enable all subsystems except SYS */
+    for (id = NFA_ID_DM; id < NFA_ID_MAX; id++)
+    {
+        if (nfa_sys_cb.is_reg[id])
+        {
+            if (nfa_sys_cb.reg[id]->enable != NULL)
+            {
+                /* Subsytem has a Disable funciton. Call it now */
+                (*nfa_sys_cb.reg[id]->enable) ();
+            }
+            else
+            {
+                /* Subsytem does not have a Enable function. Report Enable on behalf of subsystem */
+                nfa_sys_cback_notify_enable_complete (id);
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_disable_subsystems
+**
+** Description      Call on NFA shutdown. Disable all subsystems above NFA_DM
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_disable_subsystems (BOOLEAN graceful)
+{
+    UINT8 id;
+    BOOLEAN done = TRUE;
+
+    NFA_TRACE_DEBUG1 ("nfa_sys: disabling subsystems:%d", graceful);
+    nfa_sys_cb.graceful_disable = graceful;
+
+    /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled last) */
+    for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++)
+    {
+        if (nfa_sys_cb.is_reg[id])
+        {
+            done = FALSE;
+            if (nfa_sys_cb.reg[id]->disable != NULL)
+            {
+                /* Subsytem has a Disable funciton. Call it now */
+                (*nfa_sys_cb.reg[id]->disable) ();
+            }
+            else
+            {
+                /* Subsytem does not have a Disable function. Deregister on behalf of subsystem */
+                nfa_sys_deregister (id);
+            }
+        }
+    }
+
+    /* If All subsystems disabled. disable DM */
+    if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM]))
+    {
+        (*nfa_sys_cb.reg[NFA_ID_DM]->disable) ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_notify_nfcc_power_mode
+**
+** Description      Call to notify NFCC power mode to NFA sub-modules
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_notify_nfcc_power_mode (UINT8 nfcc_power_mode)
+{
+    UINT8 id;
+
+    NFA_TRACE_DEBUG1 ("nfa_sys: notify NFCC power mode(%d) to subsystems", nfcc_power_mode);
+
+    /* Notify NFCC power state to all subsystems except NFA_SYS */
+    for (id = NFA_ID_DM; id < NFA_ID_MAX; id++)
+    {
+        if ((nfa_sys_cb.is_reg[id]) && (nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode))
+        {
+            /* Subsytem has a funciton for processing NFCC power mode. Call it now */
+            (*nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode) (nfcc_power_mode);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_sendmsg
+**
+** Description      Send a GKI message to BTA.  This function is designed to
+**                  optimize sending of messages to BTA.  It is called by BTA
+**                  API functions and call-in functions.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_sendmsg (void *p_msg)
+{
+    GKI_send_msg (NFC_TASK, p_nfa_sys_cfg->mbox, p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_start_timer
+**
+** Description      Start a protocol timer for the specified amount
+**                  of time in milliseconds.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout)
+{
+    nfa_sys_ptim_start_timer (&nfa_sys_cb.ptim_cb, p_tle, type, timeout);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_stop_timer
+**
+** Description      Stop a BTA timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_stop_timer (TIMER_LIST_ENT *p_tle)
+{
+    nfa_sys_ptim_stop_timer (&nfa_sys_cb.ptim_cb, p_tle);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfa_sys_disable_timers
+**
+** Description      Disable sys timer event handling
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_disable_timers (void)
+{
+    nfa_sys_cb.timers_disabled = TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_set_trace_level
+**
+** Description      Set trace level for BTA
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_set_trace_level (UINT8 level)
+{
+    nfa_sys_cb.trace_level = level;
+}
diff --git a/src/nfa/sys/nfa_sys_ptim.c b/src/nfa/sys/nfa_sys_ptim.c
new file mode 100644
index 0000000..a10008b
--- /dev/null
+++ b/src/nfa/sys/nfa_sys_ptim.c
@@ -0,0 +1,171 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Protocol timer services (taken from bta ptim)
+ *
+ ******************************************************************************/
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nfa_sys_ptim.h"
+#include "nfa_sys.h"
+#include "nfa_sys_int.h"
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_init
+**
+** Description      Initialize a protocol timer control block.  Parameter
+**                  period is the GKI timer period in milliseconds.  Parameter
+**                  timer_id is the GKI timer id.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_init (tPTIM_CB *p_cb, UINT16 period, UINT8 timer_id)
+{
+    GKI_init_timer_list (&p_cb->timer_queue);
+    p_cb->period = period;
+    p_cb->timer_id = timer_id;
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_timer_update
+**
+** Description      Update the protocol timer list and handle expired timers.
+**                  This function is called from the task running the protocol
+**                  timers when the periodic GKI timer expires.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_timer_update (tPTIM_CB *p_cb)
+{
+    TIMER_LIST_ENT *p_tle;
+    BT_HDR *p_msg;
+    UINT32 new_ticks_count;
+    INT32  period_in_ticks;
+
+    /* To handle the case when the function is called less frequently than the period
+       we must convert determine the number of ticks since the last update, then
+       convert back to milliseconds before updating timer list */
+    new_ticks_count = GKI_get_tick_count ();
+
+    /* Check for wrapped condition */
+    if (new_ticks_count >= p_cb->last_gki_ticks)
+    {
+        period_in_ticks = (INT32) (new_ticks_count - p_cb->last_gki_ticks);
+    }
+    else
+    {
+        period_in_ticks = (INT32) (((UINT32) 0xffffffff - p_cb->last_gki_ticks)
+                            + new_ticks_count + 1);
+    }
+
+    /* update timer list */
+    GKI_update_timer_list (&p_cb->timer_queue, GKI_TICKS_TO_MS (period_in_ticks));
+
+    p_cb->last_gki_ticks = new_ticks_count;
+
+    /* while there are expired timers */
+    while ((p_cb->timer_queue.p_first) && (p_cb->timer_queue.p_first->ticks <= 0))
+    {
+        /* removed expired timer from list */
+        p_tle = p_cb->timer_queue.p_first;
+        NFA_TRACE_DEBUG1 ("nfa_sys_ptim_timer_update expired: %08x", p_tle);
+        GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+        /* call timer callback */
+        if (p_tle->p_cback)
+        {
+            (*p_tle->p_cback) (p_tle);
+        }
+        else if (p_tle->event)
+        {
+            if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL)
+            {
+                p_msg->event = p_tle->event;
+                p_msg->layer_specific = 0;
+                nfa_sys_sendmsg (p_msg);
+            }
+        }
+    }
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (p_cb->timer_queue.p_first == NULL)
+    {
+        NFA_TRACE_DEBUG0 ("ptim timer stop");
+        GKI_stop_timer (p_cb->timer_id);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_start_timer
+**
+** Description      Start a protocol timer for the specified amount
+**                  of time in seconds.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_start_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout)
+{
+    NFA_TRACE_DEBUG1 ("nfa_sys_ptim_start_timer %08x", p_tle);
+
+    /* if timer list is currently empty, start periodic GKI timer */
+    if (p_cb->timer_queue.p_first == NULL)
+    {
+        NFA_TRACE_DEBUG0 ("ptim timer start");
+        p_cb->last_gki_ticks = GKI_get_tick_count ();
+        GKI_start_timer (p_cb->timer_id, GKI_MS_TO_TICKS (p_cb->period), TRUE);
+    }
+
+    GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+    p_tle->event = type;
+    p_tle->ticks = timeout;
+
+    GKI_add_to_timer_list (&p_cb->timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_sys_ptim_stop_timer
+**
+** Description      Stop a protocol timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfa_sys_ptim_stop_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle)
+{
+    NFA_TRACE_DEBUG1 ("nfa_sys_ptim_stop_timer %08x", p_tle);
+
+    GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (p_cb->timer_queue.p_first == NULL)
+    {
+        NFA_TRACE_DEBUG0 ("ptim timer stop");
+        GKI_stop_timer (p_cb->timer_id);
+    }
+}
diff --git a/src/nfc/include/ce_api.h b/src/nfc/include/ce_api.h
new file mode 100644
index 0000000..3abdea9
--- /dev/null
+++ b/src/nfc/include/ce_api.h
@@ -0,0 +1,263 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Card Emulation
+ *  mode related API function external definitions.
+ *
+ ******************************************************************************/
+
+#ifndef CE_API_H
+#define CE_API_H
+
+#include "tags_defs.h"
+
+#define CE_T3T_FIRST_EVT    0x60
+#define CE_T4T_FIRST_EVT    0x80
+
+enum
+{
+    CE_T3T_NDEF_UPDATE_START_EVT = CE_T3T_FIRST_EVT,
+    CE_T3T_NDEF_UPDATE_CPLT_EVT,
+    CE_T3T_UPDATE_EVT,
+    CE_T3T_CHECK_EVT,
+    CE_T3T_RAW_FRAME_EVT,
+    CE_T3T_MAX_EVT,
+
+    CE_T4T_NDEF_UPDATE_START_EVT  = CE_T4T_FIRST_EVT,
+    CE_T4T_NDEF_UPDATE_CPLT_EVT,
+    CE_T4T_NDEF_UPDATE_ABORT_EVT,
+    CE_T4T_RAW_FRAME_EVT,
+    CE_T4T_MAX_EVT
+};
+
+
+#define CE_RAW_FRAME_EVT     0xFF
+
+typedef UINT8 tCE_EVENT;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    BT_HDR         *p_data;
+} tCE_T2T_DATA;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    UINT8          *p_data;
+    BOOLEAN         b_updated;
+    UINT32          length;
+} tCE_UPDATE_INFO;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    UINT8           aid_handle;
+    BT_HDR         *p_data;
+} tCE_RAW_FRAME;
+
+typedef union
+{
+    tNFC_STATUS         status;
+    tCE_UPDATE_INFO     update_info;
+    tCE_RAW_FRAME       raw_frame;
+} tCE_DATA;
+
+typedef void (tCE_CBACK) (tCE_EVENT event, tCE_DATA *p_data);
+
+
+/* T4T definitions */
+typedef UINT8 tCE_T4T_AID_HANDLE;           /* Handle for AID registration  */
+#define CE_T4T_AID_HANDLE_INVALID   0xFF    /* Invalid tCE_T4T_AID_HANDLE               */
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 3 Tag with mandatory NDEF message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSetLocalNDEFMsg (BOOLEAN read_only,
+                                UINT32 size_max,
+                                UINT32 size_current,
+                                UINT8 *p_buf,
+                                UINT8 *p_scratch_buf);
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDefParams
+**
+** Description      Sets T3T-specific NDEF parameters. (Optional - if not
+**                  called, then CE will use default parameters)
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSetLocalNDefParams (UINT8 nbr, UINT8 nbw);
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendCheckRsp
+**
+** Description      Send CHECK response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSendCheckRsp (UINT8 status1, UINT8 status2, UINT8 num_blocks, UINT8 *p_block_data);
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendUpdateRsp
+**
+** Description      Send UPDATE response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T3tSendUpdateRsp (UINT8 status1, UINT8 status2);
+
+/*******************************************************************************
+**
+** Function         CE_T4tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 4 Tag with mandatory NDEF message
+**
+**                  The following event may be returned
+**                      CE_T4T_UPDATE_START_EVT for starting update
+**                      CE_T4T_UPDATE_CPLT_EVT for complete update
+**                      CE_T4T_UPDATE_ABORT_EVT for failure of update
+**                      CE_T4T_RAW_FRAME_EVT for raw frame
+**
+**                  read_only:      TRUE if read only
+**                  ndef_msg_max:   Max NDEF message size
+**                  ndef_msg_len:   NDEF message size
+**                  p_ndef_msg:     NDEF message (excluding NLEN)
+**                  p_scratch_buf:  temp storage for update
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T4tSetLocalNDEFMsg (BOOLEAN    read_only,
+                                                  UINT16     ndef_msg_max,
+                                                  UINT16     ndef_msg_len,
+                                                  UINT8     *p_ndef_msg,
+                                                  UINT8     *p_scratch_buf);
+
+/*******************************************************************************
+**
+** Function         CE_T4tRegisterAID
+**
+** Description      Register AID in CE T4T
+**
+**                  aid_len: length of AID (up to NFC_MAX_AID_LEN)
+**                  p_aid:   AID
+**                  p_cback: Raw frame will be forwarded with CE_RAW_FRAME_EVT
+**
+** Returns          tCE_T4T_AID_HANDLE if successful,
+**                  CE_T4T_AID_HANDLE_INVALID otherwisse
+**
+*******************************************************************************/
+NFC_API extern tCE_T4T_AID_HANDLE CE_T4tRegisterAID (UINT8      aid_len,
+                                                     UINT8      *p_aid,
+                                                     tCE_CBACK  *p_cback);
+
+/*******************************************************************************
+**
+** Function         CE_T4tDeregisterAID
+**
+** Description      Deregister AID in CE T4T
+**
+**                  aid_len: length of AID (up to NFC_MAX_AID_LEN)
+**                  p_aid:   AID
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern void CE_T4tDeregisterAID (tCE_T4T_AID_HANDLE aid_handle);
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetCC
+**
+** Description      Set fields in Capability Container File for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T4TTestSetCC (UINT16 cc_len,
+                                            UINT8  version,
+                                            UINT16 max_le,
+                                            UINT16 max_lc);
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetNDEFCtrlTLV
+**
+** Description      Set fields in NDEF File Control TLV for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_T4TTestSetNDEFCtrlTLV (UINT8  type,
+                                                     UINT8  length,
+                                                     UINT16 file_id,
+                                                     UINT16 max_file_size,
+                                                     UINT8  read_access,
+                                                     UINT8  write_access);
+
+/*******************************************************************************
+**
+** Function         CE_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len);
+
+/*******************************************************************************
+**
+** Function         CE_SetActivatedTagType
+**
+** Description      This function selects the tag type for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS CE_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, UINT16 t3t_system_code, tCE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         CE_SetTraceLevel
+**
+** Description      This function sets the trace level for Card Emulation mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 CE_SetTraceLevel (UINT8 new_level);
+
+#endif /* CE_API_H */
diff --git a/src/nfc/include/llcp_api.h b/src/nfc/include/llcp_api.h
new file mode 100644
index 0000000..32af471
--- /dev/null
+++ b/src/nfc/include/llcp_api.h
@@ -0,0 +1,686 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP API definitions
+ *
+ ******************************************************************************/
+#ifndef LLCP_API_H
+#define LLCP_API_H
+
+#include "nfc_target.h"
+#include "llcp_defs.h"
+
+/*****************************************************************************
+**  Constants
+*****************************************************************************/
+#define LLCP_STATUS_SUCCESS         0       /* Successfully done                */
+#define LLCP_STATUS_FAIL            1       /* Failed without specific reason   */
+#define LLCP_STATUS_CONGESTED       2       /* Data link is congested           */
+
+typedef UINT8 tLLCP_STATUS;
+
+#define LLCP_MIN_OFFSET             (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
+
+#define LLCP_INVALID_SAP            0xFF    /* indication of failure to allocate data link resource */
+
+/*****************************************************************************
+**  Type Definitions
+*****************************************************************************/
+typedef struct
+{
+    BOOLEAN is_initiator;       /* TRUE if we are POLL mode */
+    UINT8   max_payload_size;   /* 64, 128, 192 or 254 */
+    UINT8   waiting_time;
+    UINT8  *p_gen_bytes;
+    UINT8   gen_bytes_len;
+} tLLCP_ACTIVATE_CONFIG;
+
+typedef struct
+{
+    UINT16  miu;                        /* Local receiving MIU      */
+    UINT8   rw;                         /* Local receiving window   */
+    char    sn[LLCP_MAX_SN_LEN + 1];    /* Service name to connect  */
+} tLLCP_CONNECTION_PARAMS;
+
+/*********************************
+**  Callback Functions Prototypes
+**********************************/
+
+/* Link Management Callback Events */
+
+#define LLCP_LINK_ACTIVATION_FAILED_EVT     0x00    /* Fail to activate link    */
+#define LLCP_LINK_ACTIVATION_COMPLETE_EVT   0x01    /* LLCP Link is activated   */
+#define LLCP_LINK_DEACTIVATED_EVT           0x02    /* LLCP Link is deactivated */
+
+/* Link Management Callback Reasons */
+
+#define LLCP_LINK_SUCCESS                   0x00    /* Success                                  */
+#define LLCP_LINK_VERSION_FAILED            0x01    /* Failed to agree version                  */
+#define LLCP_LINK_BAD_GEN_BYTES             0x02    /* Failed to parse received general bytes   */
+#define LLCP_LINK_INTERNAL_ERROR            0x03    /* internal error                           */
+#define LLCP_LINK_LOCAL_INITIATED           0x04    /* Link has been deactivated by local       */
+#define LLCP_LINK_REMOTE_INITIATED          0x05    /* Link has been deactivated by remote      */
+#define LLCP_LINK_TIMEOUT                   0x06    /* Link has been deactivated by timeout     */
+#define LLCP_LINK_FRAME_ERROR               0x07    /* Link has been deactivated by frame error */
+#define LLCP_LINK_RF_TRANSMISSION_ERR       NFC_STATUS_RF_TRANSMISSION_ERR
+#define LLCP_LINK_RF_PROTOCOL_ERR           NFC_STATUS_RF_PROTOCOL_ERR
+#define LLCP_LINK_RF_TIMEOUT                NFC_STATUS_TIMEOUT
+#define LLCP_LINK_RF_LINK_LOSS_ERR          NFC_STATUS_LINK_LOSS
+
+typedef void (tLLCP_LINK_CBACK) (UINT8 event, UINT8 reason);
+
+/* Minimum length of Gen Bytes for LLCP */
+/* In CE4 low power mode, NFCC can store up to 21 bytes */
+#define LLCP_MIN_GEN_BYTES                  20
+
+/* Service Access Point (SAP) Callback Events */
+
+#define LLCP_SAP_EVT_DATA_IND               0x00    /* Received data on SAP         */
+#define LLCP_SAP_EVT_CONNECT_IND            0x01    /* Connection request from peer */
+#define LLCP_SAP_EVT_CONNECT_RESP           0x02    /* Connection accepted by peer  */
+#define LLCP_SAP_EVT_DISCONNECT_IND         0x03    /* Received disconnect request  */
+#define LLCP_SAP_EVT_DISCONNECT_RESP        0x04    /* Received disconnect response */
+#define LLCP_SAP_EVT_CONGEST                0x05    /* congested status is changed  */
+#define LLCP_SAP_EVT_LINK_STATUS            0x06    /* Change of LLCP Link status   */
+#define LLCP_SAP_EVT_TX_COMPLETE            0x07    /* tx queue is empty and all PDU is acked   */
+
+#define LLCP_LINK_TYPE_LOGICAL_DATA_LINK      0x01
+#define LLCP_LINK_TYPE_DATA_LINK_CONNECTION   0x02
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_DATA_IND        */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+    UINT8   link_type;          /* link type                    */
+} tLLCP_SAP_DATA_IND;
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_CONNECT_IND     */
+    UINT8   server_sap;         /* SAP of local server          */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+    UINT16  miu;                /* MIU of peer device           */
+    UINT8   rw;                 /* RW of peer device            */
+    char   *p_service_name;     /* Service name (only for SDP)  */
+} tLLCP_SAP_CONNECT_IND;
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_CONNECT_RESP    */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+    UINT16  miu;                /* MIU of peer device           */
+    UINT8   rw;                 /* RW of peer device            */
+} tLLCP_SAP_CONNECT_RESP;
+
+#define LLCP_SAP_DISCONNECT_REASON_TIMEOUT  0x80
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_DISCONNECT_IND  */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+} tLLCP_SAP_DISCONNECT_IND;
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_DISCONNECT_RESP */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+    UINT8   reason;             /* Reason of DM PDU if not timeout */
+} tLLCP_SAP_DISCONNECT_RESP;
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_CONGEST         */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+    BOOLEAN is_congested;       /* TRUE if congested            */
+    UINT8   link_type;          /* congested link type          */
+} tLLCP_SAP_CONGEST;
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_LINK_STATUS     */
+    UINT8   local_sap;          /* SAP of local device          */
+    BOOLEAN is_activated;       /* TRUE if LLCP link is activated  */
+    BOOLEAN is_initiator;       /* TRUE if local LLCP is initiator */
+} tLLCP_SAP_LINK_STATUS;
+
+typedef struct
+{
+    UINT8   event;              /* LLCP_SAP_EVT_TX_COMPLETE     */
+    UINT8   local_sap;          /* SAP of local device          */
+    UINT8   remote_sap;         /* SAP of remote device         */
+} tLLCP_SAP_TX_COMPLETE;
+
+typedef struct
+{
+    UINT8   event;              /* event                        */
+    UINT8   local_sap;          /* SAP of local device          */
+} tLLCP_SAP_HEADER;
+
+typedef union
+{
+    tLLCP_SAP_HEADER            hdr;                /* common header                */
+    tLLCP_SAP_DATA_IND          data_ind;           /* LLCP_SAP_EVT_DATA_IND        */
+    tLLCP_SAP_CONNECT_IND       connect_ind;        /* LLCP_SAP_EVT_CONNECT_IND     */
+    tLLCP_SAP_CONNECT_RESP      connect_resp;       /* LLCP_SAP_EVT_CONNECT_RESP    */
+    tLLCP_SAP_DISCONNECT_IND    disconnect_ind;     /* LLCP_SAP_EVT_DISCONNECT_IND  */
+    tLLCP_SAP_DISCONNECT_RESP   disconnect_resp;    /* LLCP_SAP_EVT_DISCONNECT_RESP */
+    tLLCP_SAP_CONGEST           congest;            /* LLCP_SAP_EVT_CONGEST         */
+    tLLCP_SAP_LINK_STATUS       link_status;        /* LLCP_SAP_EVT_LINK_STATUS     */
+    tLLCP_SAP_TX_COMPLETE       tx_complete;        /* LLCP_SAP_EVT_TX_COMPLETE     */
+} tLLCP_SAP_CBACK_DATA;
+
+typedef void (tLLCP_APP_CBACK) (tLLCP_SAP_CBACK_DATA *p_data);
+
+/* Service Discovery Callback */
+
+typedef void (tLLCP_SDP_CBACK) (UINT8 tid, UINT8 remote_sap);
+
+/* LLCP DTA Callback - notify DTA responded SNL for connectionless echo service */
+
+typedef void (tLLCP_DTA_CBACK) (void);
+
+/*****************************************************************************
+**  External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         LLCP_SetConfig
+**
+** Description      Set configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_SetConfig (UINT16 link_miu,
+                                     UINT8  opt,
+                                     UINT8  wt,
+                                     UINT16 link_timeout,
+                                     UINT16 inact_timeout_init,
+                                     UINT16 inact_timeout_target,
+                                     UINT16 symm_delay,
+                                     UINT16 data_link_timeout,
+                                     UINT16 delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetConfig
+**
+** Description      Get configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_GetConfig (UINT16 *p_link_miu,
+                                     UINT8  *p_opt,
+                                     UINT8  *p_wt,
+                                     UINT16 *p_link_timeout,
+                                     UINT16 *p_inact_timeout_init,
+                                     UINT16 *p_inact_timeout_target,
+                                     UINT16 *p_symm_delay,
+                                     UINT16 *p_data_link_timeout,
+                                     UINT16 *p_delay_first_pdu_timeout);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetDiscoveryConfig
+**
+** Description      Returns discovery config for LLCP MAC link activation
+**                  This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
+**                  or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
+**
+**                  wt:Waiting time 0 - 8, only for listen
+**                  p_gen_bytes: pointer to store LLCP magic number and paramters
+**                  p_gen_bytes_len: length of buffer for gen bytes as input
+**                                   (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
+**                                   actual gen bytes size as output
+**
+**                  Restrictions on the use of ISO 18092
+**                  1. The DID features shall not be used.
+**                  2. the NAD features shall not be used.
+**                  3. Frame waiting time extentions (WTX) shall not be used.
+**
+** Returns          None
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
+                                              UINT8 *p_gen_bytes,
+                                              UINT8 *p_gen_bytes_len);
+
+/*******************************************************************************
+**
+** Function         LLCP_ActivateLink
+**
+** Description      This function will activate LLCP link with LR, WT and Gen Bytes
+**                  in activation NTF from NFCC.
+**
+**                  LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
+**                  callback function if successful.
+**                  Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
+                                                tLLCP_LINK_CBACK     *p_link_cback);
+
+/*******************************************************************************
+**
+** Function         LLCP_DeactivateLink
+**
+** Description      Deactivate LLCP link
+**
+**                  LLCP_LINK_DEACTIVATED_EVT will be returned through callback
+**                  when LLCP link is deactivated. Then NFC link may be deactivated.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_DeactivateLink (void);
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterServer
+**
+** Description      Register server and callback function
+**
+**                  reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
+**                            Advertized by SDP (0x10 - 0x1F)
+**                            LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**                  p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
+**
+** Returns          SAP between 0x02 and 0x1F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_RegisterServer (UINT8           reg_sap,
+                                           UINT8           link_type,
+                                           char            *p_service_name,
+                                           tLLCP_APP_CBACK *p_sap_cback);
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterClient
+**
+** Description      Register client and callback function
+**
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**
+** Returns          SAP between 0x20 and 0x3F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_RegisterClient (UINT8           link_type,
+                                           tLLCP_APP_CBACK *p_sap_cback);
+
+/*******************************************************************************
+**
+** Function         LLCP_Deregister
+**
+** Description      Deregister server or client
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_Deregister (UINT8 sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_IsLogicalLinkCongested
+**
+** Description      Check if logical link is congested
+**
+**
+** Returns          TRUE if congested
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
+                                                     UINT8 num_pending_ui_pdu,
+                                                     UINT8 total_pending_ui_pdu,
+                                                     UINT8 total_pending_i_pdu);
+
+/*******************************************************************************
+**
+** Function         LLCP_SendUI
+**
+** Description      Send connnectionless data to DSAP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if logical link is congested
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SendUI (UINT8 ssap, UINT8 dsap, BT_HDR *p_buf);
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadLogicalLinkData
+**
+** Description      Read information of UI PDU for local SAP
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into p_data.
+**                  - Information of next UI PDU is not concatenated.
+**                  - Recommended max_data_len is link MIU of local device
+**
+** Returns          TRUE if more information of UI PDU or more UI PDU in queue
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_ReadLogicalLinkData (UINT8  local_sap,
+                                                  UINT32 max_data_len,
+                                                  UINT8  *p_remote_sap,
+                                                  UINT32 *p_data_len,
+                                                  UINT8  *p_data);
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushLogicalLinkRxData
+**
+** Description      Discard received data in logical data link of local SAP
+**
+**
+** Returns          length of data flushed
+**
+*******************************************************************************/
+LLCP_API extern UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReq
+**
+** Description      Create data link connection between registered SAP and DSAP
+**                  in peer LLCP,
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ConnectReq (UINT8 reg_sap, UINT8 dsap,
+                                              tLLCP_CONNECTION_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectCfm
+**
+** Description      Accept connection request from peer LLCP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ConnectCfm (UINT8 local_sap,
+                                              UINT8 remote_sap,
+                                              tLLCP_CONNECTION_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReject
+**
+** Description      Reject connection request from peer LLCP
+**
+**                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
+                                                 UINT8 remote_sap,
+                                                 UINT8 reason);
+
+/*******************************************************************************
+**
+** Function         LLCP_IsDataLinkCongested
+**
+** Description      Check if data link is congested
+**
+**
+** Returns          TRUE if congested
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
+                                                  UINT8 remote_sap,
+                                                  UINT8 num_pending_i_pdu,
+                                                  UINT8 total_pending_ui_pdu,
+                                                  UINT8 total_pending_i_pdu);
+
+/*******************************************************************************
+**
+** Function         LLCP_SendData
+**
+** Description      Send connection-oriented data
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if data link is congested
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SendData (UINT8  local_sap,
+                                            UINT8  remote_sap,
+                                            BT_HDR *p_buf);
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadDataLinkData
+**
+** Description      Read information of I PDU for data link connection
+**
+**                  - Information of I PDU up to max_data_len is copied into p_data.
+**                  - Information of next I PDU is not concatenated.
+**                  - Recommended max_data_len is data link connection MIU of local
+**                    end point
+**
+** Returns          TRUE if more data in queue
+**
+*******************************************************************************/
+LLCP_API extern BOOLEAN LLCP_ReadDataLinkData (UINT8  local_sap,
+                                               UINT8  remote_sap,
+                                               UINT32 max_data_len,
+                                               UINT32 *p_data_len,
+                                               UINT8  *p_data);
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushDataLinkRxData
+**
+** Description      Discard received data in data link connection
+**
+**
+** Returns          length of rx data flushed
+**
+*******************************************************************************/
+LLCP_API extern UINT32 LLCP_FlushDataLinkRxData (UINT8  local_sap,
+                                                 UINT8  remote_sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_DisconnectReq
+**
+** Description      Disconnect data link
+**                  discard any pending data if flush is set to TRUE
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_DisconnectReq (UINT8   local_sap,
+                                                 UINT8   remote_sap,
+                                                 BOOLEAN flush);
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTxCompleteNtf
+**
+** Description      This function is called to get LLCP_SAP_EVT_TX_COMPLETE
+**                  when Tx queue is empty and all PDU is acked.
+**                  This is one time event, so upper layer shall call this function
+**                  again to get next LLCP_SAP_EVT_TX_COMPLETE.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8 local_sap,
+                                                    UINT8 remote_sap);
+
+/*******************************************************************************
+**
+** Function         LLCP_SetLocalBusyStatus
+**
+** Description      Set local busy status
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8   local_sap,
+                                                      UINT8   remote_sap,
+                                                      BOOLEAN is_busy);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteWKS
+**
+** Description      Return well-known service bitmap of connected device
+**
+**
+** Returns          WKS bitmap if success
+**
+*******************************************************************************/
+LLCP_API extern UINT16 LLCP_GetRemoteWKS (void);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteLSC
+**
+** Description      Return link service class of connected device
+**
+**
+** Returns          link service class
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_GetRemoteLSC (void);
+
+/*******************************************************************************
+**
+** Function         LLCP_GetLinkMIU
+**
+** Description      Return local and remote link MIU
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_GetLinkMIU (UINT16 *p_local_link_miu, UINT16 *p_remote_link_miu);
+
+/*******************************************************************************
+**
+** Function         LLCP_DiscoverService
+**
+** Description      Return SAP of service name in connected device through callback
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+LLCP_API extern tLLCP_STATUS LLCP_DiscoverService (char            *p_name,
+                                                   tLLCP_SDP_CBACK *p_cback,
+                                                   UINT8           *p_tid);
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTraceLevel
+**
+** Description      This function sets the trace level for LLCP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+LLCP_API extern UINT8 LLCP_SetTraceLevel (UINT8 new_level);
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterDtaCback
+**
+** Description      Register callback function for LLCP DTA testing
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_RegisterDtaCback (tLLCP_DTA_CBACK *p_dta_cback);
+
+#if (LLCP_TEST_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function         LLCP_SetTestParams
+**
+** Description      Set test parameters for LLCP
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+LLCP_API extern void LLCP_SetTestParams (UINT8 version, UINT16 wks);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* LLCP_API_H */
+
diff --git a/src/nfc/include/llcp_defs.h b/src/nfc/include/llcp_defs.h
new file mode 100644
index 0000000..ed77ffe
--- /dev/null
+++ b/src/nfc/include/llcp_defs.h
@@ -0,0 +1,192 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP definitions
+ *
+ ******************************************************************************/
+#ifndef LLCP_DEFS_H
+#define LLCP_DEFS_H
+
+/*
+** LLCP PDU Descriptions
+*/
+
+#define LLCP_PDU_HEADER_SIZE    2       /* DSAP:PTYPE:SSAP excluding Sequence */
+
+#define LLCP_GET_DSAP(u16)  (((u16) & 0xFC00) >> 10)
+#define LLCP_GET_PTYPE(u16) (((u16) & 0x03C0) >> 6)
+#define LLCP_GET_SSAP(u16)  (((u16) & 0x003F))
+
+#define LLCP_GET_PDU_HEADER(dsap, ptype, ssap) (((UINT16) (dsap) << 10) | ((UINT16) (ptype) << 6) | (UINT16) (ssap))
+
+#define LLCP_GET_NS(u8) ((UINT8)(u8) >> 4)
+#define LLCP_GET_NR(u8) ((UINT8)(u8) & 0x0F)
+#define LLCP_GET_SEQUENCE(NS, NR) (((UINT8) (NS) << 4) | (UINT8) (NR))
+#define LLCP_SEQUENCE_SIZE      1
+
+#define LLCP_PDU_SYMM_TYPE      0
+#define LLCP_PDU_PAX_TYPE       1
+#define LLCP_PDU_AGF_TYPE       2
+#define LLCP_PDU_UI_TYPE        3
+#define LLCP_PDU_CONNECT_TYPE   4
+#define LLCP_PDU_DISC_TYPE      5
+#define LLCP_PDU_CC_TYPE        6
+#define LLCP_PDU_DM_TYPE        7
+#define LLCP_PDU_FRMR_TYPE      8
+#define LLCP_PDU_SNL_TYPE       9
+#define LLCP_PDU_RESERVED_1010  10
+#define LLCP_PDU_RESERVED_1011  11
+#define LLCP_PDU_I_TYPE         12
+#define LLCP_PDU_RR_TYPE        13
+#define LLCP_PDU_RNR_TYPE       14
+#define LLCP_PDU_RESERVED_1111  15
+
+#define LLCP_PDU_SYMM_SIZE      2
+#define LLCP_PDU_DISC_SIZE      2
+#define LLCP_PDU_DM_SIZE        3
+#define LLCP_PDU_FRMR_SIZE      6
+#define LLCP_PDU_RR_SIZE        3
+#define LLCP_PDU_RNR_SIZE       3
+#define LLCP_PDU_AGF_LEN_SIZE   2       /* 2 bytes of length in AGF PDU */
+
+#define LLCP_SAP_DM_REASON_RESP_DISC            0x00
+#define LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION 0x01
+#define LLCP_SAP_DM_REASON_NO_SERVICE           0x02
+#define LLCP_SAP_DM_REASON_APP_REJECTED         0x03
+#define LLCP_SAP_DM_REASON_PERM_REJECT_THIS     0x10
+#define LLCP_SAP_DM_REASON_PERM_REJECT_ANY      0x11
+#define LLCP_SAP_DM_REASON_TEMP_REJECT_THIS     0x20
+#define LLCP_SAP_DM_REASON_TEMP_REJECT_ANY      0x21
+
+#define LLCP_FRMR_W_ERROR_FLAG  0x08    /* Well-formedness Error */
+#define LLCP_FRMR_I_ERROR_FLAG  0x04    /* Information Field Error */
+#define LLCP_FRMR_R_ERROR_FLAG  0x02    /* Receive Sequence Error */
+#define LLCP_FRMR_S_ERROR_FLAG  0x01    /* Send Sequence Error */
+
+#define LLCP_GET_FRMR_W_ERROR_FLAG(u8) (((UINT8) (u8) >> 7) & 0x01)
+#define LLCP_GET_FRMR_I_ERROR_FLAG(u8) (((UINT8) (u8) >> 6) & 0x01)
+#define LLCP_GET_FRMR_R_ERROR_FLAG(u8) (((UINT8) (u8) >> 5) & 0x01)
+#define LLCP_GET_FRMR_S_ERROR_FLAG(u8) (((UINT8) (u8) >> 4) & 0x01)
+#define LLCP_GET_FRMR_PTYPE(u8)        ((UINT8) (u8) & 0x0F)
+#define LLCP_GET_FRMR_VS(u16)          (((UINT16) (u16) >> 12) & 0x000F)
+#define LLCP_GET_FRMR_VR(u16)          (((UINT16) (u16) >>  8) & 0x000F)
+#define LLCP_GET_FRMR_VSA(u16)         (((UINT16) (u16) >>  4) & 0x000F)
+#define LLCP_GET_FRMR_VRA(u16)         (((UINT16) (u16) >>  0) & 0x000F)
+
+/*
+** LLCP Parameter Descriptions
+*/
+
+/* Version */
+#define LLCP_VERSION_TYPE   0x01
+#define LLCP_VERSION_LEN    0x01
+#define LLCP_GET_MAJOR_VERSION(u8)     (((UINT8) (u8) >> 4) & 0x0F)
+#define LLCP_GET_MINOR_VERSION(u8)     ((UINT8) (u8) & 0x0F)
+#define LLCP_MIN_MAJOR_VERSION      0x01
+#define LLCP_MIN_SNL_MAJOR_VERSION  0x01
+#define LLCP_MIN_SNL_MINOR_VERSION  0x01
+
+/* LLCP Version 1.1 */
+#define LLCP_VERSION_MAJOR  0x01
+#define LLCP_VERSION_MINOR  0x01
+#define LLCP_VERSION_VALUE  ((LLCP_VERSION_MAJOR << 4) | LLCP_VERSION_MINOR)
+
+/* Maximum Information Unit Extension */
+#define LLCP_MIUX_TYPE      0x02
+#define LLCP_MIUX_LEN       0x02
+#define LLCP_MIUX_MASK      0x07FF  /* MIUX bit 10:0 */
+#define LLCP_DEFAULT_MIU    128     /* if local LLC doesn't receive MIUX */
+#define LLCP_MAX_MIU        2175    /* 2047 (11bits) + 128 */
+
+/* Well-Known Service */
+#define LLCP_WKS_TYPE       0x03
+#define LLCP_WKS_LEN        0x02
+
+/* Well-Known Service Bitmap */
+#define LLCP_WKS_MASK_LM    0x0001  /* Link Management */
+#define LLCP_WKS_MASK_SDP   0x0002  /* Service Discovery "urn:nfc:sn:sdp" */
+#define LLCP_WKS_MASK_IP    0x0004  /* IP over LLCP Binding "urn:nfc:sn:ip" */
+#define LLCP_WKS_MASK_OBEX  0x0008  /* OBEX over LLCP Binding "urn:nfc:sn:obex" */
+#define LLCP_WKS_MASK_SNEP  0x0010  /* Simple NDEP Exchange Protocol "urn:nfc:sn:snep" */
+
+/* Well-Known Service Access Points */
+#define LLCP_SAP_LM         0x00    /* Link Management */
+#define LLCP_SAP_SDP        0x01    /* Service Discovery "urn:nfc:sn:sdp" */
+#define LLCP_SAP_IP         0x02    /* IP over LLCP Binding "urn:nfc:sn:ip" */
+#define LLCP_SAP_OBEX       0x03    /* OBEX over LLCP Binding "urn:nfc:sn:obex" */
+#define LLCP_SAP_SNEP       0x04    /* Simple NDEP Exchange Protocol "urn:nfc:sn:snep" */
+
+/* Link Timeout, LTO */
+#define LLCP_LTO_TYPE       0x04
+#define LLCP_LTO_LEN        0x01
+#define LLCP_DEFAULT_LTO_IN_MS    100     /* default 100ms. It should be sufficiently larget than RWT */
+#define LLCP_LTO_UNIT       10      /* 10 ms */
+#define LLCP_MAX_LTO_IN_MS  2550    /* 2550 ms; 8bits * 10ms */
+
+/* Receive Window Size, RW */
+#define LLCP_RW_TYPE        0x05
+#define LLCP_RW_LEN         0x01
+#define LLCP_DEFAULT_RW     1       /* if local LLC doesn't receive RW */
+
+/* Service Name, SN */
+#define LLCP_SN_TYPE        0x06
+
+/* Option, OPT */
+#define LLCP_OPT_TYPE       0x07
+#define LLCP_OPT_LEN        0x01
+#define LLCP_GET_OPT_LSC(u8) ((UINT8) (u8) & 0x03)
+
+/* Service Discovery Request, SDREQ */
+#define LLCP_SDREQ_TYPE     0x08
+#define LLCP_SDREQ_MIN_LEN  0x03    /* type(1 byte), length(1 byte), TID(1 byte) */
+
+/* Service Discovery Response, SDRES */
+#define LLCP_SDRES_TYPE     0x09
+#define LLCP_SDRES_LEN      0x02
+
+/* Link Service Class */
+#define LLCP_LSC_UNKNOWN    0x00
+#define LLCP_LSC_1          0x01
+#define LLCP_LSC_2          0x02
+#define LLCP_LSC_3          0x03
+
+#define LLCP_MAGIC_NUMBER_LEN       3
+#define LLCP_MAGIC_NUMBER_BYTE0     0x46
+#define LLCP_MAGIC_NUMBER_BYTE1     0x66
+#define LLCP_MAGIC_NUMBER_BYTE2     0x6D
+
+#define LLCP_SEQ_MODULO             16
+
+#define LLCP_NUM_SAPS               64
+#define LLCP_LOWER_BOUND_WK_SAP     0x00
+#define LLCP_UPPER_BOUND_WK_SAP     0x0F
+#define LLCP_LOWER_BOUND_SDP_SAP    0x10
+#define LLCP_UPPER_BOUND_SDP_SAP    0x1F
+#define LLCP_LOWER_BOUND_LOCAL_SAP  0x20
+#define LLCP_UPPER_BOUND_LOCAL_SAP  0x3F
+
+/* Max Payload */
+#define LLCP_NCI_MAX_PAYL_SIZE      254 /* Maximum Payload size, Length Reduction LRi/LRt */
+#define LLCP_NFC_DEP_HEADER_SIZE      3 /* Data exchange protocol header, 3 bytes */
+#define LLCP_MAX_PAYLOAD_SIZE       (LLCP_NCI_MAX_PAYL_SIZE - LLCP_NFC_DEP_HEADER_SIZE)
+
+#define LLCP_MAX_GEN_BYTES          48
+
+#endif  /* LLCP_DEFS_H */
diff --git a/src/nfc/include/nci_hmsgs.h b/src/nfc/include/nci_hmsgs.h
new file mode 100644
index 0000000..cdde2a2
--- /dev/null
+++ b/src/nfc/include/nci_hmsgs.h
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  defines NCI interface messages (for DH)
+ *
+ ******************************************************************************/
+#ifndef NFC_NCI_HMSGS_H
+#define NFC_NCI_HMSGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nci_defs.h"
+
+
+BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg);
+void nci_proc_rf_management_rsp (BT_HDR *p_msg);
+void nci_proc_ee_management_rsp (BT_HDR *p_msg);
+void nci_proc_core_ntf (BT_HDR *p_msg);
+void nci_proc_rf_management_ntf (BT_HDR *p_msg);
+void nci_proc_ee_management_ntf (BT_HDR *p_msg);
+void nci_proc_prop_rsp (BT_HDR *p_msg);
+void nci_proc_prop_ntf (BT_HDR *p_msg);
+
+
+UINT8 nci_snd_core_reset (UINT8 reset_type);
+UINT8 nci_snd_core_init (void);
+UINT8 nci_snd_core_get_config (UINT8 *param_ids, UINT8 num_ids);
+UINT8 nci_snd_core_set_config (UINT8 *p_param_tlvs, UINT8 tlv_size);
+
+UINT8 nci_snd_core_conn_create (UINT8 dest_type, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs);
+UINT8 nci_snd_core_conn_close (UINT8 conn_id);
+
+
+
+UINT8 nci_snd_discover_cmd (UINT8 num, tNCI_DISCOVER_PARAMS *p_param);
+
+UINT8 nci_snd_discover_select_cmd (UINT8 rf_disc_id, UINT8 protocol, UINT8 rf_interface);
+UINT8 nci_snd_deactivate_cmd (UINT8 de_act_type );
+UINT8 nci_snd_discover_map_cmd (UINT8 num, tNCI_DISCOVER_MAPS *p_maps);
+UINT8 nci_snd_t3t_polling (UINT16 system_code, UINT8 rc, UINT8 tsn);
+UINT8 nci_snd_parameter_update_cmd (UINT8 *p_param_tlvs, UINT8 tlv_size);
+
+#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
+UINT8 nci_snd_nfcee_discover (UINT8 discover_action);
+UINT8 nci_snd_nfcee_mode_set (UINT8 nfcee_id, UINT8 nfcee_mode);
+UINT8 nci_snd_set_routing_cmd (BOOLEAN more, UINT8 target_handle, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs);
+UINT8 nci_snd_get_routing_cmd (void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* NFC_NCI_MSGS_H */
diff --git a/src/nfc/include/ndef_utils.h b/src/nfc/include/ndef_utils.h
new file mode 100644
index 0000000..336cd8b
--- /dev/null
+++ b/src/nfc/include/ndef_utils.h
@@ -0,0 +1,526 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains definitions for some utility functions to help parse
+ *  and build NFC Data Exchange Format (NDEF) messages
+ *
+ ******************************************************************************/
+
+#ifndef NDEF_UTILS_H
+#define NDEF_UTILS_H
+
+#include "bt_types.h"
+
+#define NDEF_MB_MASK            0x80    /* Message Begin */
+#define NDEF_ME_MASK            0x40    /* Message End */
+#define NDEF_CF_MASK            0x20    /* Chunk Flag */
+#define NDEF_SR_MASK            0x10    /* Short Record */
+#define NDEF_IL_MASK            0x08    /* ID Length */
+#define NDEF_TNF_MASK           0x07    /* Type Name Format */
+
+/* NDEF Type Name Format */
+#define NDEF_TNF_EMPTY          0   /* Empty (type/id/payload len =0) */
+#define NDEF_TNF_WKT            1   /* NFC Forum well-known type/RTD */
+#define NDEF_TNF_MEDIA          2   /* Media-type as defined in RFC 2046 */
+#define NDEF_TNF_URI            3   /* Absolute URI as defined in RFC 3986 */
+#define NDEF_TNF_EXT            4   /* NFC Forum external type/RTD */
+#define NDEF_TNF_UNKNOWN        5   /* Unknown (type len =0) */
+#define NDEF_TNF_UNCHANGED      6   /* Unchanged (type len =0) */
+#define NDEF_TNF_RESERVED       7   /* Reserved */
+
+/* Define the status code returned from the Validate, Parse or Build functions
+*/
+enum
+{
+    NDEF_OK,                            /* 0 - OK                                   */
+
+    NDEF_REC_NOT_FOUND,                 /* 1 - No record matching the find criteria */
+    NDEF_MSG_TOO_SHORT,                 /* 2 - Message was too short (< 3 bytes)    */
+    NDEF_MSG_NO_MSG_BEGIN,              /* 3 - No 'begin' flag at start of message  */
+    NDEF_MSG_NO_MSG_END,                /* 4 - No 'end' flag at end of message      */
+    NDEF_MSG_EXTRA_MSG_BEGIN,           /* 5 - 'begin' flag after start of message  */
+    NDEF_MSG_UNEXPECTED_CHUNK,          /* 6 - Unexpected chunk found               */
+    NDEF_MSG_INVALID_EMPTY_REC,         /* 7 - Empty record with non-zero contents  */
+    NDEF_MSG_INVALID_CHUNK,             /* 8 - Invalid chunk found                  */
+    NDEF_MSG_LENGTH_MISMATCH,           /* 9 - Overall message length doesn't match */
+    NDEF_MSG_INSUFFICIENT_MEM           /* 10 - Insuffiecient memory to add record  */
+};
+typedef UINT8 tNDEF_STATUS;
+
+
+#define HR_REC_TYPE_LEN     2       /* Handover Request Record Type     */
+#define HS_REC_TYPE_LEN     2       /* Handover Select Record Type      */
+#define HC_REC_TYPE_LEN     2       /* Handover Carrier recrod Type     */
+#define CR_REC_TYPE_LEN     2       /* Collision Resolution Record Type */
+#define AC_REC_TYPE_LEN     2       /* Alternative Carrier Record Type  */
+#define ERR_REC_TYPE_LEN    3       /* Error Record Type                */
+#define BT_OOB_REC_TYPE_LEN 32      /* Bluetooth OOB Data Type          */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define prefix for exporting APIs from libraries */
+#ifdef  NFC_DLL
+#define EXPORT_NDEF_API __declspec(dllexport)       /* Windows DLL export prefix */
+#else
+#define EXPORT_NDEF_API
+#endif
+
+/* Functions to parse a received NDEF Message
+*/
+/*******************************************************************************
+**
+** Function         NDEF_MsgValidate
+**
+** Description      This function validates an NDEF message.
+**
+** Returns          TRUE if all OK, or FALSE if the message is invalid.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgValidate (UINT8 *p_msg, UINT32 msg_len, BOOLEAN b_allow_chunks);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNumRecs
+**
+** Description      This function gets the number of records in the given NDEF
+**                  message.
+**
+** Returns          The record count, or 0 if the message is invalid.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern INT32 NDEF_MsgGetNumRecs (UINT8 *p_msg);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecLength
+**
+** Description      This function returns length of the current record in the given
+**                  NDEF message.
+**
+** Returns          Length of record
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT32 NDEF_MsgGetRecLength (UINT8 *p_cur_rec);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRec
+**
+** Description      This function gets a pointer to the next record after the
+**                  current one.
+**
+** Returns          Pointer to the start of the record, or NULL if no more
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetNextRec (UINT8 *p_cur_rec);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecByIndex
+**
+** Description      This function gets a pointer to the record with the given
+**                  index (0-based index) in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetRecByIndex (UINT8 *p_msg, INT32 index);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetLastRecInMsg
+**
+** Description      This function gets a pointer to the last record in the
+**                  given NDEF message.
+**
+** Returns          Pointer to the start of the last record, or NULL if some problem
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetLastRecInMsg (UINT8 *p_msg);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecByType
+**
+** Description      This function gets a pointer to the first record with the given
+**                  record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetFirstRecByType (UINT8 *p_msg, UINT8 tnf, UINT8 *p_type, UINT8 tlen);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecByType
+**
+** Description      This function gets a pointer to the next record with the given
+**                  record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetNextRecByType (UINT8 *p_cur_rec, UINT8 tnf, UINT8 *p_type, UINT8 tlen);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecById
+**
+** Description      This function gets a pointer to the first record with the given
+**                  record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetFirstRecById (UINT8 *p_msg, UINT8 *p_id, UINT8 ilen);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecById
+**
+** Description      This function gets a pointer to the next record with the given
+**                  record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_MsgGetNextRecById (UINT8 *p_cur_rec, UINT8 *p_id, UINT8 ilen);
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetType
+**
+** Description      This function gets a pointer to the record type for the given NDEF record.
+**
+** Returns          Pointer to Type (NULL if none). TNF and len are filled in.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_RecGetType (UINT8 *p_rec, UINT8 *p_tnf, UINT8 *p_type_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetId
+**
+** Description      This function gets a pointer to the record id for the given NDEF record.
+**
+** Returns          Pointer to Id (NULL if none). ID Len is filled in.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_RecGetId (UINT8 *p_rec, UINT8 *p_id_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetPayload
+**
+** Description      This function gets a pointer to the payload for the given NDEF record.
+**
+** Returns          a pointer to the payload (NULL if none). Payload len filled in.
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern UINT8 *NDEF_RecGetPayload (UINT8 *p_rec, UINT32 *p_payload_len);
+
+
+/* Functions to build an NDEF Message
+*/
+/*******************************************************************************
+**
+** Function         NDEF_MsgInit
+**
+** Description      This function initializes an NDEF message.
+**
+** Returns          void
+**                  *p_cur_size is initialized to 0
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern void NDEF_MsgInit (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddRec
+**
+** Description      This function adds an NDEF record to the end of an NDEF message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS  NDEF_MsgAddRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                     UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+                                     UINT8 *p_id, UINT8  id_len,
+                                     UINT8 *p_payload, UINT32 payload_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgInsertRec
+**
+** Description      This function inserts a record at a specific index into the
+**                  given NDEF message
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS  NDEF_MsgInsertRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size, INT32 index,
+                                        UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+                                        UINT8 *p_id, UINT8  id_len,
+                                        UINT8 *p_payload, UINT32 payload_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendRec
+**
+** Description      This function adds NDEF records to the end of an NDEF message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS  NDEF_MsgAppendRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                        UINT8 *p_new_rec, UINT32 new_rec_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendPayload
+**
+** Description      This function appends extra payload to a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the extra payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendPayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                           UINT8 *p_rec, UINT8 *p_add_pl, UINT32 add_pl_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplacePayload
+**
+** Description      This function replaces the payload of a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the new payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgReplacePayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                            UINT8 *p_rec, UINT8 *p_new_pl, UINT32 new_pl_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceType
+**
+** Description      This function replaces the type field of a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the new type field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgReplaceType (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                         UINT8 *p_rec, UINT8 *p_new_type, UINT8 new_type_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceId
+**
+** Description      This function replaces the ID field of a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the new ID field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgReplaceId (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                       UINT8 *p_rec, UINT8 *p_new_id, UINT8 new_id_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgRemoveRec
+**
+** Description      This function removes the record at the given
+**                  index in the given NDEF message.
+**
+** Returns          OK, or error if the index was invalid
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgRemoveRec (UINT8 *p_msg, UINT32 *p_cur_size, INT32 index);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCopyAndDechunk
+**
+** Description      This function copies and de-chunks an NDEF message.
+**                  It is assumed that the destination is at least as large
+**                  as the source, since the source may not actually contain
+**                  any chunks.
+**
+** Returns          The output byte count
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgCopyAndDechunk (UINT8 *p_src, UINT32 src_len, UINT8 *p_dest, UINT32 *p_out_len);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCreateWktHr
+**
+** Description      This function creates Handover Request Record with version.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgCreateWktHr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                 UINT8 version );
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCreateWktHs
+**
+** Description      This function creates Handover Select Record with version.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgCreateWktHs (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                 UINT8 version );
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktHc
+**
+** Description      This function adds Handover Carrier Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktHc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                              char  *p_id_str, UINT8 ctf,
+                                              UINT8 carrier_type_len, UINT8 *p_carrier_type,
+                                              UINT8 carrier_data_len, UINT8 *p_carrier_data);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktAc
+**
+** Description      This function adds Alternative Carrier Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktAc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                              UINT8 cps, char *p_carrier_data_ref_str,
+                                              UINT8 aux_data_ref_count, char *p_aux_data_ref_str[]);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktCr
+**
+** Description      This function adds Collision Resolution Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktCr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                              UINT16 random_number );
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktErr
+**
+** Description      This function adds Error Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddWktErr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                               UINT8 error_reason, UINT32 error_data );
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddMediaBtOob
+**
+** Description      This function adds BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAddMediaBtOob (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                   char *p_id_str, BD_ADDR bd_addr);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobCod
+**
+** Description      This function appends COD EIR data at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobCod (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                         char *p_id_str, DEV_CLASS cod);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobName
+**
+** Description      This function appends Bluetooth Local Name EIR data
+**                  at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobName (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                          char *p_id_str, BOOLEAN is_complete,
+                                                          UINT8 name_len, UINT8 *p_name);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobHashCRandR
+**
+** Description      This function appends Hash C and Rand R at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobHashCRandR (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                                char *p_id_str, UINT8 *p_hash_c, UINT8 *p_rand_r);
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobEirData
+**
+** Description      This function appends EIR Data at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+EXPORT_NDEF_API extern tNDEF_STATUS NDEF_MsgAppendMediaBtOobEirData (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                             char *p_id_str,
+                                                             UINT8 eir_type, UINT8 data_len, UINT8 *p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NDEF_UTILS_H */
diff --git a/src/nfc/include/nfc_api.h b/src/nfc/include/nfc_api.h
new file mode 100644
index 0000000..2fac0e7
--- /dev/null
+++ b/src/nfc/include/nfc_api.h
@@ -0,0 +1,1251 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) API function
+ *  external definitions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_API_H
+#define NFC_API_H
+
+#include "nfc_target.h"
+#include "nci_defs.h"
+#include "nfc_hal_api.h"
+#include "gki.h"
+
+/* NFC application return status codes */
+#define NFC_STATUS_OK                   NCI_STATUS_OK                   /* Command succeeded    */
+#define NFC_STATUS_REJECTED             NCI_STATUS_REJECTED             /* Command is rejected. */
+#define NFC_STATUS_MSG_CORRUPTED        NCI_STATUS_MESSAGE_CORRUPTED    /* Message is corrupted */
+#define NFC_STATUS_BUFFER_FULL          NCI_STATUS_BUFFER_FULL          /* buffer full          */
+#define NFC_STATUS_FAILED               NCI_STATUS_FAILED               /* failed               */
+#define NFC_STATUS_NOT_INITIALIZED      NCI_STATUS_NOT_INITIALIZED      /* not initialized      */
+#define NFC_STATUS_SYNTAX_ERROR         NCI_STATUS_SYNTAX_ERROR         /* Syntax error         */
+#define NFC_STATUS_SEMANTIC_ERROR       NCI_STATUS_SEMANTIC_ERROR       /* Semantic error       */
+#define NFC_STATUS_UNKNOWN_GID          NCI_STATUS_UNKNOWN_GID          /* Unknown NCI Group ID */
+#define NFC_STATUS_UNKNOWN_OID          NCI_STATUS_UNKNOWN_OID          /* Unknown NCI Opcode   */
+#define NFC_STATUS_INVALID_PARAM        NCI_STATUS_INVALID_PARAM        /* Invalid Parameter    */
+#define NFC_STATUS_MSG_SIZE_TOO_BIG     NCI_STATUS_MSG_SIZE_TOO_BIG     /* Message size too big */
+#define NFC_STATUS_ALREADY_STARTED      NCI_STATUS_ALREADY_STARTED      /* Already started      */
+#define NFC_STATUS_ACTIVATION_FAILED    NCI_STATUS_ACTIVATION_FAILED    /* Activation Failed    */
+#define NFC_STATUS_TEAR_DOWN            NCI_STATUS_TEAR_DOWN            /* Tear Down Error      */
+#define NFC_STATUS_RF_TRANSMISSION_ERR  NCI_STATUS_RF_TRANSMISSION_ERR  /* RF transmission error*/
+#define NFC_STATUS_RF_PROTOCOL_ERR      NCI_STATUS_RF_PROTOCOL_ERR      /* RF protocol error    */
+#define NFC_STATUS_TIMEOUT              NCI_STATUS_TIMEOUT              /* RF Timeout           */
+#define NFC_STATUS_EE_INTF_ACTIVE_FAIL  NCI_STATUS_EE_INTF_ACTIVE_FAIL  /* EE Intf activate err */
+#define NFC_STATUS_EE_TRANSMISSION_ERR  NCI_STATUS_EE_TRANSMISSION_ERR  /* EE transmission error*/
+#define NFC_STATUS_EE_PROTOCOL_ERR      NCI_STATUS_EE_PROTOCOL_ERR      /* EE protocol error    */
+#define NFC_STATUS_EE_TIMEOUT           NCI_STATUS_EE_TIMEOUT           /* EE Timeout           */
+
+/* 0xE0 ~0xFF are proprietary status codes */
+#define NFC_STATUS_CMD_STARTED          0xE3/* Command started successfully                     */
+#define NFC_STATUS_HW_TIMEOUT           0xE4/* NFCC Timeout in responding to an NCI command     */
+#define NFC_STATUS_CONTINUE             0xE5/* More (same) event to follow                      */
+#define NFC_STATUS_REFUSED              0xE6/* API is called to perform illegal function        */
+#define NFC_STATUS_BAD_RESP             0xE7/* Wrong format of R-APDU, CC file or NDEF file     */
+#define NFC_STATUS_CMD_NOT_CMPLTD       0xE8/* 7816 Status Word is not command complete(0x9000) */
+#define NFC_STATUS_NO_BUFFERS           0xE9/* Out of GKI buffers                               */
+#define NFC_STATUS_WRONG_PROTOCOL       0xEA/* Protocol mismatch between API and activated one  */
+#define NFC_STATUS_BUSY                 0xEB/* Another Tag command is already in progress       */
+
+#define NFC_STATUS_LINK_LOSS            0xFC                      /* Link Loss                  */
+#define NFC_STATUS_BAD_LENGTH           0xFD                      /* data len exceeds MIU       */
+#define NFC_STATUS_BAD_HANDLE           0xFE                      /* invalid handle             */
+#define NFC_STATUS_CONGESTED            0xFF                      /* congested                  */
+typedef UINT8 tNFC_STATUS;
+
+
+
+/**********************************************
+ * NFC Config Parameter IDs defined by NCI
+ **********************************************/
+#define NFC_PMID_TOTAL_DURATION     NCI_PARAM_ID_TOTAL_DURATION
+#define NFC_PMID_CON_DEVICES_LIMIT  NCI_PARAM_ID_CON_DEVICES_LIMIT
+#define NFC_PMID_PA_BAILOUT         NCI_PARAM_ID_PA_BAILOUT
+#define NFC_PMID_PB_AFI             NCI_PARAM_ID_PB_AFI
+#define NFC_PMID_PB_BAILOUT         NCI_PARAM_ID_PB_BAILOUT
+#define NFC_PMID_PB_ATTRIB_PARAM1   NCI_PARAM_ID_PB_ATTRIB_PARAM1
+#define NFC_PMID_PF_BIT_RATE        NCI_PARAM_ID_PF_BIT_RATE
+#define NFC_PMID_PB_H_INFO          NCI_PARAM_ID_PB_H_INFO
+#define NFC_PMID_BITR_NFC_DEP       NCI_PARAM_ID_BITR_NFC_DEP
+#define NFC_PMID_ATR_REQ_GEN_BYTES  NCI_PARAM_ID_ATR_REQ_GEN_BYTES
+#define NFC_PMID_ATR_REQ_CONFIG     NCI_PARAM_ID_ATR_REQ_CONFIG
+#define NFC_PMID_LA_HIST_BY         NCI_PARAM_ID_LA_HIST_BY
+#define NFC_PMID_LA_NFCID1          NCI_PARAM_ID_LA_NFCID1
+#define NFC_PMID_PI_BIT_RATE        NCI_PARAM_ID_PI_BIT_RATE
+#define NFC_PMID_LA_BIT_FRAME_SDD   NCI_PARAM_ID_LA_BIT_FRAME_SDD
+#define NFC_PMID_LA_PLATFORM_CONFIG NCI_PARAM_ID_LA_PLATFORM_CONFIG
+#define NFC_PMID_LA_SEL_INFO        NCI_PARAM_ID_LA_SEL_INFO
+#define NFC_PMID_LI_BIT_RATE        NCI_PARAM_ID_LI_BIT_RATE
+#define NFC_PMID_LB_SENSB_INFO      NCI_PARAM_ID_LB_SENSB_INFO
+#define NFC_PMID_LB_PROTOCOL        NCI_PARAM_ID_LB_PROTOCOL
+#define NFC_PMID_LB_H_INFO          NCI_PARAM_ID_LB_H_INFO_RSP
+#define NFC_PMID_LB_NFCID0          NCI_PARAM_ID_LB_NFCID0
+#define NFC_PMID_LB_APPDATA         NCI_PARAM_ID_LB_APPDATA
+#define NFC_PMID_LB_SFGI            NCI_PARAM_ID_LB_SFGI
+#define NFC_PMID_LB_ADC_FO          NCI_PARAM_ID_LB_ADC_FO
+#define NFC_PMID_LF_T3T_ID1         NCI_PARAM_ID_LF_T3T_ID1
+#define NFC_PMID_LF_T3T_ID2         NCI_PARAM_ID_LF_T3T_ID2
+#define NFC_PMID_LF_T3T_ID3         NCI_PARAM_ID_LF_T3T_ID3
+#define NFC_PMID_LF_T3T_ID4         NCI_PARAM_ID_LF_T3T_ID4
+#define NFC_PMID_LF_T3T_ID5         NCI_PARAM_ID_LF_T3T_ID5
+#define NFC_PMID_LF_T3T_ID6         NCI_PARAM_ID_LF_T3T_ID6
+#define NFC_PMID_LF_T3T_ID7         NCI_PARAM_ID_LF_T3T_ID7
+#define NFC_PMID_LF_T3T_ID8         NCI_PARAM_ID_LF_T3T_ID8
+#define NFC_PMID_LF_T3T_ID9         NCI_PARAM_ID_LF_T3T_ID9
+#define NFC_PMID_LF_T3T_ID10        NCI_PARAM_ID_LF_T3T_ID10
+#define NFC_PMID_LF_T3T_ID11        NCI_PARAM_ID_LF_T3T_ID11
+#define NFC_PMID_LF_T3T_ID12        NCI_PARAM_ID_LF_T3T_ID12
+#define NFC_PMID_LF_T3T_ID13        NCI_PARAM_ID_LF_T3T_ID13
+#define NFC_PMID_LF_T3T_ID14        NCI_PARAM_ID_LF_T3T_ID14
+#define NFC_PMID_LF_T3T_ID15        NCI_PARAM_ID_LF_T3T_ID15
+#define NFC_PMID_LF_T3T_ID16        NCI_PARAM_ID_LF_T3T_ID16
+#define NFC_PMID_LF_PROTOCOL        NCI_PARAM_ID_LF_PROTOCOL
+#define NFC_PMID_LF_T3T_PMM         NCI_PARAM_ID_LF_T3T_PMM
+#define NFC_PMID_LF_T3T_MAX         NCI_PARAM_ID_LF_T3T_MAX
+#define NFC_PMID_LF_T3T_FLAGS2      NCI_PARAM_ID_LF_T3T_FLAGS2
+#define NFC_PMID_FWI                NCI_PARAM_ID_FWI
+#define NFC_PMID_LF_CON_BITR_F      NCI_PARAM_ID_LF_CON_BITR_F
+#define NFC_PMID_WT                 NCI_PARAM_ID_WT
+#define NFC_PMID_ATR_RES_GEN_BYTES  NCI_PARAM_ID_ATR_RES_GEN_BYTES
+#define NFC_PMID_ATR_RSP_CONFIG     NCI_PARAM_ID_ATR_RSP_CONFIG
+#define NFC_PMID_RF_FIELD_INFO      NCI_PARAM_ID_RF_FIELD_INFO
+#define NFC_PMID_NFC_DEP_OP         NCI_PARAM_ID_NFC_DEP_OP
+#define NFC_PARAM_ID_RF_EE_ACTION   NCI_PARAM_ID_RF_EE_ACTION
+#define NFC_PARAM_ID_ISO_DEP_OP     NCI_PARAM_ID_ISO_DEP_OP
+
+#define NFC_ROUTE_TAG_TECH           NCI_ROUTE_TAG_TECH      /* Technology based routing  */
+#define NFC_ROUTE_TAG_PROTO          NCI_ROUTE_TAG_PROTO     /* Protocol based routing  */
+#define NFC_ROUTE_TAG_AID            NCI_ROUTE_TAG_AID       /* AID routing */
+#define NFC_ROUTE_TLV_ENTRY_SIZE     4 /* tag, len, 2 byte value for technology/protocol based routing */
+
+/* For routing */
+#define NFC_DH_ID                NCI_DH_ID   /* for DH */
+/* To identify the loopback test */
+#define NFC_TEST_ID              NCI_TEST_ID            /* use a proprietary range */
+
+typedef UINT8 tNFC_PMID;
+#define NFC_TL_SIZE                     2
+#define NFC_SAVED_CMD_SIZE              2
+
+typedef tNCI_DISCOVER_MAPS   tNFC_DISCOVER_MAPS;
+typedef tNCI_DISCOVER_PARAMS tNFC_DISCOVER_PARAMS;
+
+/* all NFC Manager Callback functions have prototype like void (cback) (UINT8 event, void *p_data)
+ * tNFC_DATA_CBACK uses connection id as the first parameter; range 0x00-0x0F.
+ * tNFC_DISCOVER_CBACK uses tNFC_DISCOVER_EVT; range  0x4000 ~
+ * tNFC_RESPONSE_CBACK uses tNFC_RESPONSE_EVT; range  0x5000 ~
+ */
+
+#define NFC_FIRST_DEVT      0x4000
+#define NFC_FIRST_REVT      0x5000
+#define NFC_FIRST_CEVT      0x6000
+#define NFC_FIRST_TEVT      0x8000
+
+/* the events reported on tNFC_RESPONSE_CBACK */
+enum
+{
+    NFC_ENABLE_REVT = NFC_FIRST_REVT,       /* 0  Enable event                  */
+    NFC_DISABLE_REVT,                       /* 1  Disable event                 */
+    NFC_SET_CONFIG_REVT,                    /* 2  Set Config Response           */
+    NFC_GET_CONFIG_REVT,                    /* 3  Get Config Response           */
+    NFC_NFCEE_DISCOVER_REVT,                /* 4  Discover NFCEE response       */
+    NFC_NFCEE_INFO_REVT,                    /* 5  Discover NFCEE Notification   */
+    NFC_NFCEE_MODE_SET_REVT,                /* 6  NFCEE Mode Set response       */
+    NFC_RF_FIELD_REVT,                      /* 7  RF Field information          */
+    NFC_EE_ACTION_REVT,                     /* 8  EE Action notification        */
+    NFC_EE_DISCOVER_REQ_REVT,               /* 9  EE Discover Req notification  */
+    NFC_SET_ROUTING_REVT,                   /* 10 Configure Routing response    */
+    NFC_GET_ROUTING_REVT,                   /* 11 Retrieve Routing response     */
+    NFC_RF_COMM_PARAMS_UPDATE_REVT,         /* 12 RF Communication Param Update */
+    NFC_GEN_ERROR_REVT,                     /* 13 generic error notification    */
+    NFC_NFCC_RESTART_REVT,                  /* 14 NFCC has been re-initialized  */
+    NFC_NFCC_TIMEOUT_REVT,                  /* 15 NFCC is not responding        */
+    NFC_NFCC_TRANSPORT_ERR_REVT,            /* 16 NCI Tranport error            */
+    NFC_NFCC_POWER_OFF_REVT,                /* 17 NFCC turned off               */
+
+    NFC_FIRST_VS_REVT                       /* First vendor-specific rsp event  */
+};
+typedef UINT16 tNFC_RESPONSE_EVT;
+
+enum
+{
+    NFC_CONN_CREATE_CEVT = NFC_FIRST_CEVT,  /* 0  Conn Create Response          */
+    NFC_CONN_CLOSE_CEVT,                    /* 1  Conn Close Response           */
+    NFC_DEACTIVATE_CEVT,                    /* 2  Deactivate response/notificatn*/
+    NFC_DATA_CEVT,                          /* 3  Data                          */
+    NFC_ERROR_CEVT                          /* 4  generic or interface error    */
+};
+typedef UINT16 tNFC_CONN_EVT;
+
+#define NFC_NFCC_INFO_LEN       4
+#ifndef NFC_NFCC_MAX_NUM_VS_INTERFACE
+#define NFC_NFCC_MAX_NUM_VS_INTERFACE   4
+#endif
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status.                */
+    UINT8                   nci_version;    /* the NCI version of NFCC          */
+    UINT8                   max_conn;       /* max number of connections by NFCC*/
+    UINT32                  nci_features;   /* the NCI features of NFCC         */
+    UINT16                  nci_interfaces; /* the NCI interfaces of NFCC       */
+    UINT16                  max_ce_table;   /* the max routing table size       */
+    UINT16                  max_param_size; /* Max Size for Large Parameters    */
+    UINT8                   manufacture_id; /* the Manufacture ID for NFCC      */
+    UINT8                   nfcc_info[NFC_NFCC_INFO_LEN];/* the Manufacture Info for NFCC      */
+    UINT8                   vs_interface[NFC_NFCC_MAX_NUM_VS_INTERFACE];  /* the NCI VS interfaces of NFCC    */
+} tNFC_ENABLE_REVT;
+
+#define NFC_MAX_NUM_IDS     125
+/* the data type associated with NFC_SET_CONFIG_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status.                */
+    UINT8                   num_param_id;   /* Number of rejected NCI Param ID  */
+    UINT8                   param_ids[NFC_MAX_NUM_IDS];/* NCI Param ID          */
+} tNFC_SET_CONFIG_REVT;
+
+/* the data type associated with NFC_GET_CONFIG_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status.    */
+    UINT16                  tlv_size;       /* The length of TLV    */
+    UINT8                   *p_param_tlvs;  /* TLV                  */
+} tNFC_GET_CONFIG_REVT;
+
+/* the data type associated with NFC_NFCEE_DISCOVER_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status.    */
+    UINT8                   num_nfcee;      /* The number of NFCEE  */
+} tNFC_NFCEE_DISCOVER_REVT;
+
+#define NFC_NFCEE_INTERFACE_APDU         NCI_NFCEE_INTERFACE_APDU
+#define NFC_NFCEE_INTERFACE_HCI_ACCESS   NCI_NFCEE_INTERFACE_HCI_ACCESS
+#define NFC_NFCEE_INTERFACE_T3T          NCI_NFCEE_INTERFACE_T3T
+#define NFC_NFCEE_INTERFACE_TRANSPARENT  NCI_NFCEE_INTERFACE_TRANSPARENT
+#define NFC_NFCEE_INTERFACE_PROPRIETARY  NCI_NFCEE_INTERFACE_PROPRIETARY
+typedef UINT8 tNFC_NFCEE_INTERFACE;
+
+#define NFC_NFCEE_TAG_HW_ID             NCI_NFCEE_TAG_HW_ID
+#define NFC_NFCEE_TAG_ATR_BYTES         NCI_NFCEE_TAG_ATR_BYTES
+#define NFC_NFCEE_TAG_T3T_INFO          NCI_NFCEE_TAG_T3T_INFO
+#define NFC_NFCEE_TAG_HCI_HOST_ID       NCI_NFCEE_TAG_HCI_HOST_ID
+typedef UINT8 tNFC_NFCEE_TAG;
+/* additional NFCEE Info */
+typedef struct
+{
+    tNFC_NFCEE_TAG          tag;
+    UINT8                   len;
+    UINT8                   info[NFC_MAX_EE_INFO];
+} tNFC_NFCEE_TLV;
+
+#define NFC_NFCEE_STATUS_INACTIVE       NCI_NFCEE_STS_CONN_INACTIVE/* NFCEE connected and inactive */
+#define NFC_NFCEE_STATUS_ACTIVE         NCI_NFCEE_STS_CONN_ACTIVE  /* NFCEE connected and active   */
+#define NFC_NFCEE_STATUS_REMOVED        NCI_NFCEE_STS_REMOVED      /* NFCEE removed                */
+/* the data type associated with NFC_NFCEE_INFO_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;                 /* The event status - place holder  */
+    UINT8                   nfcee_id;               /* NFCEE ID                         */
+    UINT8                   ee_status;              /* The NFCEE status.                */
+    UINT8                   num_interface;          /* number of NFCEE interfaces       */
+    UINT8                   ee_interface[NFC_MAX_EE_INTERFACE];/* NFCEE interface       */
+    UINT8                   num_tlvs;               /* number of TLVs                   */
+    tNFC_NFCEE_TLV          ee_tlv[NFC_MAX_EE_TLVS];/* The TLVs associated with NFCEE   */
+} tNFC_NFCEE_INFO_REVT;
+
+#define NFC_MODE_ACTIVATE          NCI_NFCEE_MD_ACTIVATE
+#define NFC_MODE_DEACTIVATE        NCI_NFCEE_MD_DEACTIVATE
+typedef UINT8 tNFC_NFCEE_MODE;
+/* the data type associated with NFC_NFCEE_MODE_SET_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;                 /* The event status.*/
+    UINT8                   nfcee_id;               /* NFCEE ID         */
+    tNFC_NFCEE_MODE         mode;                   /* NFCEE mode       */
+} tNFC_NFCEE_MODE_SET_REVT;
+
+#define NFC_MAX_AID_LEN     NCI_MAX_AID_LEN     /* 16 */
+
+/* the data type associated with NFC_CE_GET_ROUTING_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status                 */
+    UINT8                   nfcee_id;       /* NFCEE ID                         */
+    UINT8                   num_tlvs;       /* number of TLVs                   */
+    UINT8                   tlv_size;       /* the total len of all TLVs        */
+    UINT8                   param_tlvs[NFC_MAX_EE_TLV_SIZE];/* the TLVs         */
+} tNFC_GET_ROUTING_REVT;
+
+
+/* the data type associated with NFC_CONN_CREATE_CEVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status                 */
+    UINT8                   dest_type;      /* the destination type             */
+    UINT8                   id;             /* NFCEE ID  or RF Discovery ID     */
+    UINT8                   buff_size;      /* The max buffer size              */
+    UINT8                   num_buffs;      /* The number of buffers            */
+} tNFC_CONN_CREATE_CEVT;
+
+/* the data type associated with NFC_CONN_CLOSE_CEVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status                 */
+} tNFC_CONN_CLOSE_CEVT;
+
+/* the data type associated with NFC_DATA_CEVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status                 */
+    BT_HDR                  *p_data;        /* The received Data                */
+} tNFC_DATA_CEVT;
+
+/* RF Field Status */
+#define NFC_RF_STS_NO_REMOTE    NCI_RF_STS_NO_REMOTE    /* No field generated by remote device  */
+#define NFC_RF_STS_REMOTE       NCI_RF_STS_REMOTE       /* field generated by remote device     */
+typedef UINT8 tNFC_RF_STS;
+
+/* RF Field Technologies */
+#define NFC_RF_TECHNOLOGY_A     NCI_RF_TECHNOLOGY_A
+#define NFC_RF_TECHNOLOGY_B     NCI_RF_TECHNOLOGY_B
+#define NFC_RF_TECHNOLOGY_F     NCI_RF_TECHNOLOGY_F
+#define NFC_RF_TECHNOLOGY_15693 NCI_RF_TECHNOLOGY_15693
+typedef UINT8 tNFC_RF_TECH;
+
+
+/* Supported Protocols */
+#define NFC_PROTOCOL_UNKNOWN    NCI_PROTOCOL_UNKNOWN  /* Unknown */
+#define NFC_PROTOCOL_T1T        NCI_PROTOCOL_T1T      /* Type1Tag    - NFC-A            */
+#define NFC_PROTOCOL_T2T        NCI_PROTOCOL_T2T      /* Type2Tag    - NFC-A            */
+#define NFC_PROTOCOL_T3T        NCI_PROTOCOL_T3T      /* Type3Tag    - NFC-F            */
+#define NFC_PROTOCOL_ISO_DEP    NCI_PROTOCOL_ISO_DEP  /* Type 4A,4B  - NFC-A or NFC-B   */
+#define NFC_PROTOCOL_NFC_DEP    NCI_PROTOCOL_NFC_DEP  /* NFCDEP/LLCP - NFC-A or NFC-F       */
+#define NFC_PROTOCOL_B_PRIME    NCI_PROTOCOL_B_PRIME
+#define NFC_PROTOCOL_15693      NCI_PROTOCOL_15693
+#define NFC_PROTOCOL_KOVIO      NCI_PROTOCOL_KOVIO
+typedef UINT8 tNFC_PROTOCOL;
+
+/* Discovery Types/Detected Technology and Mode */
+#define NFC_DISCOVERY_TYPE_POLL_A           NCI_DISCOVERY_TYPE_POLL_A
+#define NFC_DISCOVERY_TYPE_POLL_B           NCI_DISCOVERY_TYPE_POLL_B
+#define NFC_DISCOVERY_TYPE_POLL_F           NCI_DISCOVERY_TYPE_POLL_F
+#define NFC_DISCOVERY_TYPE_POLL_A_ACTIVE    NCI_DISCOVERY_TYPE_POLL_A_ACTIVE
+#define NFC_DISCOVERY_TYPE_POLL_F_ACTIVE    NCI_DISCOVERY_TYPE_POLL_F_ACTIVE
+#define NFC_DISCOVERY_TYPE_POLL_ISO15693    NCI_DISCOVERY_TYPE_POLL_ISO15693
+#define NFC_DISCOVERY_TYPE_POLL_B_PRIME     NCI_DISCOVERY_TYPE_POLL_B_PRIME
+#define NFC_DISCOVERY_TYPE_POLL_KOVIO       NCI_DISCOVERY_TYPE_POLL_KOVIO
+#define NFC_DISCOVERY_TYPE_LISTEN_A         NCI_DISCOVERY_TYPE_LISTEN_A
+#define NFC_DISCOVERY_TYPE_LISTEN_B         NCI_DISCOVERY_TYPE_LISTEN_B
+#define NFC_DISCOVERY_TYPE_LISTEN_F         NCI_DISCOVERY_TYPE_LISTEN_F
+#define NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE  NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE
+#define NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE  NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE
+#define NFC_DISCOVERY_TYPE_LISTEN_ISO15693  NCI_DISCOVERY_TYPE_LISTEN_ISO15693
+#define NFC_DISCOVERY_TYPE_LISTEN_B_PRIME   NCI_DISCOVERY_TYPE_LISTEN_B_PRIME
+typedef UINT8 tNFC_DISCOVERY_TYPE;
+typedef UINT8 tNFC_RF_TECH_N_MODE;
+
+/* Select Response codes */
+#define NFC_SEL_RES_NFC_FORUM_T2T           0x00
+#define NFC_SEL_RES_MF_CLASSIC              0x08
+
+/* Bit Rates */
+#define NFC_BIT_RATE_106        NCI_BIT_RATE_106    /* 106 kbit/s */
+#define NFC_BIT_RATE_212        NCI_BIT_RATE_212    /* 212 kbit/s */
+#define NFC_BIT_RATE_424        NCI_BIT_RATE_424    /* 424 kbit/s */
+#define NFC_BIT_RATE_848        NCI_BIT_RATE_848    /* 848 Kbit/s */
+#define NFC_BIT_RATE_1696       NCI_BIT_RATE_1696   /* 1696 Kbit/s*/
+#define NFC_BIT_RATE_3392       NCI_BIT_RATE_3392   /* 3392 Kbit/s*/
+#define NFC_BIT_RATE_6784       NCI_BIT_RATE_6784   /* 6784 Kbit/s*/
+typedef UINT8 tNFC_BIT_RATE;
+
+/**********************************************
+ * Interface Types
+ **********************************************/
+#define NFC_INTERFACE_EE_DIRECT_RF  NCI_INTERFACE_EE_DIRECT_RF
+#define NFC_INTERFACE_FRAME         NCI_INTERFACE_FRAME
+#define NFC_INTERFACE_ISO_DEP       NCI_INTERFACE_ISO_DEP
+#define NFC_INTERFACE_NDEF          NCI_INTERFACE_NDEF
+#define NFC_INTERFACE_NFC_DEP       NCI_INTERFACE_NFC_DEP
+#define NFC_INTERFACE_LLCP_LOW      NCI_INTERFACE_LLCP_LOW
+#define NFC_INTERFACE_LLCP_HIGH     NCI_INTERFACE_LLCP_HIGH
+#define NFC_INTERFACE_VS_T2T_CE     NCI_INTERFACE_VS_T2T_CE
+typedef tNCI_INTF_TYPE tNFC_INTF_TYPE;
+
+/**********************************************
+ *  Deactivation Type
+ **********************************************/
+#define NFC_DEACTIVATE_TYPE_IDLE        NCI_DEACTIVATE_TYPE_IDLE
+#define NFC_DEACTIVATE_TYPE_SLEEP       NCI_DEACTIVATE_TYPE_SLEEP
+#define NFC_DEACTIVATE_TYPE_SLEEP_AF    NCI_DEACTIVATE_TYPE_SLEEP_AF
+#define NFC_DEACTIVATE_TYPE_DISCOVERY   NCI_DEACTIVATE_TYPE_DISCOVERY
+typedef UINT8 tNFC_DEACT_TYPE;
+
+/**********************************************
+ *  Deactivation Reasons
+ **********************************************/
+#define NFC_DEACTIVATE_REASON_DH_REQ        NCI_DEACTIVATE_REASON_DH_REQ
+#define NFC_DEACTIVATE_REASON_ENDPOINT_REQ  NCI_DEACTIVATE_REASON_ENDPOINT_REQ
+#define NFC_DEACTIVATE_REASON_RF_LINK_LOSS  NCI_DEACTIVATE_REASON_RF_LINK_LOSS
+#define NFC_DEACTIVATE_REASON_NFCB_BAD_AFI  NCI_DEACTIVATE_REASON_NFCB_BAD_AFI
+typedef UINT8 tNFC_DEACT_REASON;
+
+/* the data type associated with NFC_RF_FIELD_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;     /* The event status - place holder. */
+    tNFC_RF_STS             rf_field;   /* RF Field Status                  */
+} tNFC_RF_FIELD_REVT;
+
+#define NFC_MAX_APP_DATA_LEN    40
+typedef struct
+{
+    UINT8                   len_aid;                /* length of application id */
+    UINT8                   aid[NFC_MAX_AID_LEN];   /* application id           */
+} tNFC_AID;
+typedef struct
+{
+    UINT8                   len_aid;                /* length of application id */
+    UINT8                   aid[NFC_MAX_AID_LEN];   /* application id           */
+    UINT8                   len_data;               /* len of application data  */
+    UINT8                   data[NFC_MAX_APP_DATA_LEN];  /* application data    */
+} tNFC_APP_INIT;
+
+#define NFC_EE_TRIG_SELECT              NCI_EE_TRIG_7816_SELECT  /* ISO 7816-4 SELECT command */
+#define NFC_EE_TRIG_RF_PROTOCOL         NCI_EE_TRIG_RF_PROTOCOL  /* RF Protocol changed       */
+#define NFC_EE_TRIG_RF_TECHNOLOGY       NCI_EE_TRIG_RF_TECHNOLOGY/* RF Technology changed     */
+#define NFC_EE_TRIG_APP_INIT            NCI_EE_TRIG_APP_INIT     /* Application initiation    */
+typedef UINT8 tNFC_EE_TRIGGER;
+typedef struct
+{
+    tNFC_EE_TRIGGER         trigger;        /* the trigger of this event        */
+    union
+    {
+        tNFC_PROTOCOL       protocol;
+        tNFC_RF_TECH        technology;
+        tNFC_AID            aid;
+        tNFC_APP_INIT       app_init;
+    } param; /* Discovery Type specific parameters */
+} tNFC_ACTION_DATA;
+
+/* the data type associated with NFC_EE_ACTION_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status - place holder  */
+    UINT8                   nfcee_id;       /* NFCEE ID                         */
+    tNFC_ACTION_DATA        act_data;       /* data associated /w the action    */
+} tNFC_EE_ACTION_REVT;
+
+#define NFC_EE_DISC_OP_ADD      0
+#define NFC_EE_DISC_OP_REMOVE   1
+typedef UINT8 tNFC_EE_DISC_OP;
+typedef struct
+{
+    tNFC_EE_DISC_OP         op;             /* add or remove this entry         */
+    UINT8                   nfcee_id;       /* NFCEE ID                         */
+    tNFC_RF_TECH_N_MODE     tech_n_mode;    /* Discovery Technology and Mode    */
+    tNFC_PROTOCOL           protocol;       /* NFC protocol                     */
+} tNFC_EE_DISCOVER_INFO;
+
+#ifndef NFC_MAX_EE_DISC_ENTRIES
+#define NFC_MAX_EE_DISC_ENTRIES     6
+#endif
+#define NFC_EE_DISCOVER_ENTRY_LEN   5 /* T, L, V(NFCEE ID, TechnMode, Protocol) */
+#define NFC_EE_DISCOVER_INFO_LEN    3 /* NFCEE ID, TechnMode, Protocol */
+/* the data type associated with NFC_EE_DISCOVER_REQ_REVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status - place holder  */
+    UINT8                   num_info;       /* number of entries in info[]      */
+    tNFC_EE_DISCOVER_INFO   info[NFC_MAX_EE_DISC_ENTRIES];  /* discovery request from NFCEE */
+} tNFC_EE_DISCOVER_REQ_REVT;
+
+typedef union
+{
+    tNFC_STATUS                 status;     /* The event status. */
+    tNFC_ENABLE_REVT            enable;
+    tNFC_SET_CONFIG_REVT        set_config;
+    tNFC_GET_CONFIG_REVT        get_config;
+    tNFC_NFCEE_DISCOVER_REVT    nfcee_discover;
+    tNFC_NFCEE_INFO_REVT        nfcee_info;
+    tNFC_NFCEE_MODE_SET_REVT    mode_set;
+    tNFC_RF_FIELD_REVT          rf_field;
+    tNFC_STATUS                 cfg_routing;
+    tNFC_GET_ROUTING_REVT       get_routing;
+    tNFC_EE_ACTION_REVT         ee_action;
+    tNFC_EE_DISCOVER_REQ_REVT   ee_discover_req;
+    void                        *p_vs_evt_data;
+} tNFC_RESPONSE;
+
+/*************************************
+**  RESPONSE Callback Functions
+**************************************/
+typedef void (tNFC_RESPONSE_CBACK) (tNFC_RESPONSE_EVT event, tNFC_RESPONSE *p_data);
+
+/* The events reported on tNFC_VS_CBACK */
+/* The event is (NCI_RSP_BIT|oid) for response and (NCI_NTF_BIT|oid) for notification*/
+
+typedef UINT8 tNFC_VS_EVT;
+
+/*************************************
+**  Proprietary (Vendor Specific) Callback Functions
+**************************************/
+typedef void (tNFC_VS_CBACK) (tNFC_VS_EVT event, UINT16 data_len, UINT8 *p_data);
+
+/* the events reported on tNFC_DISCOVER_CBACK */
+enum
+{
+    NFC_START_DEVT = NFC_FIRST_DEVT,    /* Status of NFC_DiscoveryStart     */
+    NFC_MAP_DEVT,                       /* Status of NFC_DiscoveryMap       */
+    NFC_RESULT_DEVT,                    /* The responses from remote device */
+    NFC_SELECT_DEVT,                    /* Status of NFC_DiscoverySelect    */
+    NFC_ACTIVATE_DEVT,                  /* RF interface is activated        */
+    NFC_DEACTIVATE_DEVT                 /* Status of RF deactivation        */
+};
+typedef UINT16 tNFC_DISCOVER_EVT;
+
+/* the data type associated with NFC_START_DEVT */
+typedef tNFC_STATUS tNFC_START_DEVT;
+
+typedef tNCI_RF_PA_PARAMS tNFC_RF_PA_PARAMS;
+#define NFC_MAX_SENSB_RES_LEN         NCI_MAX_SENSB_RES_LEN
+#define NFC_NFCID0_MAX_LEN          4
+typedef struct
+{
+    UINT8       sensb_res_len;/* Length of SENSB_RES Response (Byte 2 - Byte 12 or 13) Available after Technology Detection */
+    UINT8       sensb_res[NFC_MAX_SENSB_RES_LEN]; /* SENSB_RES Response (ATQ) */
+    UINT8       nfcid0[NFC_NFCID0_MAX_LEN];
+} tNFC_RF_PB_PARAMS;
+
+#define NFC_MAX_SENSF_RES_LEN       NCI_MAX_SENSF_RES_LEN
+#define NFC_NFCID2_LEN              NCI_NFCID2_LEN
+typedef struct
+{
+    UINT8       bit_rate;/* NFC_BIT_RATE_212 or NFC_BIT_RATE_424 */
+    UINT8       sensf_res_len;/* Length of SENSF_RES Response (Byte 2 - Byte 17 or 19) Available after Technology Detection */
+    UINT8       sensf_res[NFC_MAX_SENSF_RES_LEN]; /* SENSB_RES Response */
+    UINT8       nfcid2[NFC_NFCID2_LEN];  /* NFCID2 generated by the Local NFCC for NFC-DEP Protocol.Available for Frame Interface  */
+    UINT8       mrti_check;
+    UINT8       mrti_update;
+} tNFC_RF_PF_PARAMS;
+
+typedef tNCI_RF_LF_PARAMS tNFC_RF_LF_PARAMS;
+
+#define NFC_ISO15693_UID_LEN        8
+typedef struct
+{
+    UINT8       flag;
+    UINT8       dsfid;
+    UINT8       uid[NFC_ISO15693_UID_LEN];
+} tNFC_RF_PISO15693_PARAMS;
+
+#define NFC_KOVIO_MAX_LEN       16
+typedef struct
+{
+    UINT8       uid_len;
+    UINT8       uid[NFC_KOVIO_MAX_LEN];
+} tNFC_RF_PKOVIO_PARAMS;
+
+typedef struct
+{
+    tNFC_DISCOVERY_TYPE     mode;
+    union
+    {
+        tNFC_RF_PA_PARAMS   pa;
+        tNFC_RF_PB_PARAMS   pb;
+        tNFC_RF_PF_PARAMS   pf;
+        tNFC_RF_LF_PARAMS   lf;
+        tNFC_RF_PISO15693_PARAMS pi93;
+        tNFC_RF_PKOVIO_PARAMS pk;
+    } param; /* Discovery Type specific parameters */
+} tNFC_RF_TECH_PARAMS;
+
+/* the data type associated with NFC_RESULT_DEVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status - place holder. */
+    UINT8                   rf_disc_id;     /* RF Discovery ID                  */
+    UINT8                   protocol;       /* supported protocol               */
+    tNFC_RF_TECH_PARAMS     rf_tech_param;  /* RF technology parameters         */
+    BOOLEAN                 more;           /* 0: last notification             */
+} tNFC_RESULT_DEVT;
+
+/* the data type associated with NFC_SELECT_DEVT */
+typedef tNFC_STATUS tNFC_SELECT_DEVT;
+
+/* the data type associated with NFC_STOP_DEVT */
+typedef tNFC_STATUS tNFC_STOP_DEVT;
+
+#define NFC_MAX_ATS_LEN             NCI_MAX_ATS_LEN
+#define NFC_MAX_HIS_BYTES_LEN       NCI_MAX_HIS_BYTES_LEN
+#define NFC_MAX_GEN_BYTES_LEN       NCI_MAX_GEN_BYTES_LEN
+
+
+typedef struct
+{
+    UINT8       ats_res_len;                /* Length of ATS RES                */
+    UINT8       ats_res[NFC_MAX_ATS_LEN];   /* ATS RES                          */
+    BOOLEAN     nad_used;                   /* NAD is used or not               */
+    UINT8       fwi;                        /* Frame Waiting time Integer       */
+    UINT8       sfgi;                       /* Start-up Frame Guard time Integer*/
+    UINT8       his_byte_len;               /* len of historical bytes          */
+    UINT8       his_byte[NFC_MAX_HIS_BYTES_LEN];/* historical bytes             */
+} tNFC_INTF_PA_ISO_DEP;
+
+typedef struct
+{
+    UINT8       rats;  /* RATS */
+} tNFC_INTF_LA_ISO_DEP;
+
+
+typedef struct
+{
+    UINT8       atr_res_len;                /* Length of ATR_RES            */
+    UINT8       atr_res[NFC_MAX_ATS_LEN];   /* ATR_RES (Byte 3 - Byte 17+n) */
+    UINT8       max_payload_size;           /* 64, 128, 192 or 254          */
+    UINT8       gen_bytes_len;              /* len of general bytes         */
+    UINT8       gen_bytes[NFC_MAX_GEN_BYTES_LEN];/* general bytes           */
+    UINT8       waiting_time;               /* WT -> Response Waiting Time RWT = (256 x 16/fC) x 2WT */
+} tNFC_INTF_PA_NFC_DEP;
+
+/* Note: keep tNFC_INTF_PA_NFC_DEP data member in the same order as tNFC_INTF_LA_NFC_DEP */
+typedef struct
+{
+    UINT8       atr_req_len;                /* Length of ATR_REQ            */
+    UINT8       atr_req[NFC_MAX_ATS_LEN];   /* ATR_REQ (Byte 3 - Byte 18+n) */
+    UINT8       max_payload_size;           /* 64, 128, 192 or 254          */
+    UINT8       gen_bytes_len;              /* len of general bytes         */
+    UINT8       gen_bytes[NFC_MAX_GEN_BYTES_LEN];/* general bytes           */
+} tNFC_INTF_LA_NFC_DEP;
+typedef tNFC_INTF_LA_NFC_DEP tNFC_INTF_LF_NFC_DEP;
+typedef tNFC_INTF_PA_NFC_DEP tNFC_INTF_PF_NFC_DEP;
+
+#define NFC_MAX_ATTRIB_LEN      NCI_MAX_ATTRIB_LEN
+
+typedef struct
+{
+    UINT8       attrib_res_len;                /* Length of ATTRIB RES      */
+    UINT8       attrib_res[NFC_MAX_ATTRIB_LEN];/* ATTRIB RES                */
+    UINT8       hi_info_len;                   /* len of Higher layer Info  */
+    UINT8       hi_info[NFC_MAX_GEN_BYTES_LEN];/* Higher layer Info         */
+    UINT8       mbli;                          /* Maximum buffer length.    */
+} tNFC_INTF_PB_ISO_DEP;
+
+typedef struct
+{
+    UINT8       attrib_req_len;                /* Length of ATTRIB REQ      */
+    UINT8       attrib_req[NFC_MAX_ATTRIB_LEN];/* ATTRIB REQ (Byte 2 - 10+k)*/
+    UINT8       hi_info_len;                   /* len of Higher layer Info  */
+    UINT8       hi_info[NFC_MAX_GEN_BYTES_LEN];/* Higher layer Info         */
+    UINT8       nfcid0[NFC_NFCID0_MAX_LEN];    /* NFCID0                    */
+} tNFC_INTF_LB_ISO_DEP;
+
+
+#ifndef NFC_MAX_RAW_PARAMS
+#define NFC_MAX_RAW_PARAMS      16
+#endif
+#define NFC_MAX_RAW_PARAMS       16
+typedef struct
+{
+    UINT8       param_len;
+    UINT8       param[NFC_MAX_RAW_PARAMS];
+} tNFC_INTF_FRAME;
+
+typedef struct
+{
+    tNFC_INTF_TYPE      type;  /* Interface Type  1 Byte  See Table 67 */
+    union
+    {
+        tNFC_INTF_LA_ISO_DEP    la_iso;
+        tNFC_INTF_PA_ISO_DEP    pa_iso;
+        tNFC_INTF_LB_ISO_DEP    lb_iso;
+        tNFC_INTF_PB_ISO_DEP    pb_iso;
+        tNFC_INTF_LA_NFC_DEP    la_nfc;
+        tNFC_INTF_PA_NFC_DEP    pa_nfc;
+        tNFC_INTF_LF_NFC_DEP    lf_nfc;
+        tNFC_INTF_PF_NFC_DEP    pf_nfc;
+        tNFC_INTF_FRAME         frame;
+    } intf_param;       /* Activation Parameters   0 - n Bytes */
+} tNFC_INTF_PARAMS;
+
+/* the data type associated with NFC_ACTIVATE_DEVT */
+typedef struct
+{
+    UINT8                   rf_disc_id;     /* RF Discovery ID          */
+    tNFC_PROTOCOL           protocol;       /* supported protocol       */
+    tNFC_RF_TECH_PARAMS     rf_tech_param;  /* RF technology parameters */
+    tNFC_BIT_RATE           tx_bitrate;     /* Data Exchange Tx Bitrate */
+    tNFC_BIT_RATE           rx_bitrate;     /* Data Exchange Rx Bitrate */
+    tNFC_INTF_PARAMS        intf_param;     /* interface type and params*/
+} tNFC_ACTIVATE_DEVT;
+
+/* the data type associated with NFC_DEACTIVATE_DEVT and NFC_DEACTIVATE_CEVT */
+typedef struct
+{
+    tNFC_STATUS             status;         /* The event status.        */
+    tNFC_DEACT_TYPE         type;           /* De-activate type         */
+    BOOLEAN                 is_ntf;         /* TRUE, if deactivate notif*/
+} tNFC_DEACTIVATE_DEVT;
+
+typedef union
+{
+    tNFC_STATUS             status;         /* The event status.        */
+    tNFC_START_DEVT         start;
+    tNFC_RESULT_DEVT        result;
+    tNFC_SELECT_DEVT        select;
+    tNFC_STOP_DEVT          stop;
+    tNFC_ACTIVATE_DEVT      activate;
+    tNFC_DEACTIVATE_DEVT    deactivate;
+} tNFC_DISCOVER;
+
+/* Min TR0 indicates to tag the min delay before responding after the end of command */
+#define NFC_RF_PARAM_MIN_TR0_DEFAULT    0x00
+#define NFC_RF_PARAM_MIN_TR0_48X        0x01    /* 48 x 16/fc */
+#define NFC_RF_PARAM_MIN_TR0_16X        0x02    /* 16 x 16/fc */
+
+/* Min TR1 indicates to tag the min delay between subcarrier modulation and data transmission */
+#define NFC_RF_PARAM_MIN_TR1_DEFAULT    0x00
+#define NFC_RF_PARAM_MIN_TR1_64X        0x01    /* 64 x 16/fc */
+#define NFC_RF_PARAM_MIN_TR1_16X        0x02    /* 16 x 16/fc */
+
+/* Min TR2 indicates to RW the min delay between EoS of tag and SoS of RW */
+#define NFC_RF_PARAM_MIN_TR2_1792       0x00    /* 1792/fc (10etu + 32/fc) */
+#define NFC_RF_PARAM_MIN_TR2_3328       0x01    /* 3328/fc (10etu + 128/fc) */
+#define NFC_RF_PARAM_MIN_TR2_5376       0x02    /* 5376/fc (10etu + 256/fc) */
+#define NFC_RF_PARAM_MIN_TR2_9472       0x03    /* 9472/fc (10etu + 512/fc) */
+
+#define NFC_RF_PARAM_EOS_REQUIRED       0x00    /* EoS required */
+#define NFC_RF_PARAM_EOS_NOT_REQUIRED   0x01    /* EoS not required */
+
+#define NFC_RF_PARAM_SOS_REQUIRED       0x00    /* SoS required */
+#define NFC_RF_PARAM_SOS_NOT_REQUIRED   0x01    /* SoS not required */
+
+typedef struct
+{
+    BOOLEAN                 include_rf_tech_mode;   /* TRUE if including RF Tech and Mode update    */
+    tNFC_RF_TECH_N_MODE     rf_tech_n_mode;         /* RF tech and mode                             */
+    BOOLEAN                 include_tx_bit_rate;    /* TRUE if including Tx bit rate update         */
+    tNFC_BIT_RATE           tx_bit_rate;            /* Transmit Bit Rate                            */
+    BOOLEAN                 include_rx_bit_rate;    /* TRUE if including Rx bit rate update         */
+    tNFC_BIT_RATE           rx_bit_rate;            /* Receive Bit Rate                             */
+    BOOLEAN                 include_nfc_b_config;   /* TRUE if including NFC-B data exchange config */
+    UINT8                   min_tr0;                /* Minimun TR0                                  */
+    UINT8                   min_tr1;                /* Minimun TR1                                  */
+    UINT8                   suppression_eos;        /* Suppression of EoS                           */
+    UINT8                   suppression_sos;        /* Suppression of SoS                           */
+    UINT8                   min_tr2;                /* Minimun TR1                                  */
+} tNFC_RF_COMM_PARAMS;
+
+/*************************************
+**  DISCOVER Callback Functions
+**************************************/
+typedef void (tNFC_DISCOVER_CBACK) (tNFC_DISCOVER_EVT event, tNFC_DISCOVER *p_data);
+
+/* the events reported on tNFC_TEST_CBACK */
+enum
+{
+    NFC_LOOPBACK_TEVT = NFC_FIRST_TEVT, /* 0  Loopback test             */
+    NFC_RF_CONTROL_TEVT,                /* 1  RF control Test response  */
+    NFC_RF_FIELD_DONE_TEVT              /* 1  RF control Test notificatn*/
+};
+typedef UINT16 tNFC_TEST_EVT;
+
+/* the data type associated with NFC_LOOPBACK_TEVT */
+typedef struct
+{
+    tNFC_STATUS             status;     /* The event status.            */
+    BT_HDR                  *p_data;    /* The loop back data from NFCC */
+} tNFC_LOOPBACK_TEVT;
+
+/* the data type associated with NFC_RF_CONTROL_TEVT */
+typedef tNFC_STATUS tNFC_RF_CONTROL_TEVT;
+
+typedef union
+{
+    tNFC_STATUS             status;     /* The event status.            */
+    tNFC_LOOPBACK_TEVT      loop_back;
+    tNFC_RF_CONTROL_TEVT    rf_control;
+} tNFC_TEST;
+
+/*************************************
+**  TEST Callback Functions
+**************************************/
+typedef void (tNFC_TEST_CBACK) (tNFC_TEST_EVT event, tNFC_TEST *p_data);
+
+
+typedef tNFC_DEACTIVATE_DEVT tNFC_DEACTIVATE_CEVT;
+typedef union
+{
+    tNFC_STATUS             status;     /* The event status. */
+    tNFC_CONN_CREATE_CEVT   conn_create;
+    tNFC_CONN_CLOSE_CEVT    conn_close;
+    tNFC_DEACTIVATE_CEVT    deactivate;
+    tNFC_DATA_CEVT          data;
+} tNFC_CONN;
+
+/*************************************
+**  Data Callback Functions
+**************************************/
+typedef void (tNFC_CONN_CBACK) (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+#define NFC_MAX_CONN_ID                15
+#define NFC_ILLEGAL_CONN_ID            0xFF
+#define NFC_RF_CONN_ID                 0    /* the static connection ID for RF traffic */
+
+
+
+/*************************************
+**  Status callback function
+**************************************/
+typedef void (tNFC_STATUS_CBACK) (tNFC_STATUS status);
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Function         NFC_Enable
+**
+** Description      This function enables NFC. Prior to calling NFC_Enable:
+**                  - the NFCC must be powered up, and ready to receive commands.
+**                  - GKI must be enabled
+**                  - NFC_TASK must be started
+**                  - NCIT_TASK must be started (if using dedicated NCI transport)
+**
+**                  This function opens the NCI transport (if applicable),
+**                  resets the NFC controller, and initializes the NFC subsystems.
+**
+**                  When the NFC startup procedure is completed, an
+**                  NFC_ENABLE_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_Enable (tNFC_RESPONSE_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_Disable
+**
+** Description      This function performs clean up routines for shutting down
+**                  NFC and closes the NCI transport (if using dedicated NCI
+**                  transport).
+**
+**                  When the NFC shutdown procedure is completed, an
+**                  NFC_DISABLED_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          nothing
+**
+*******************************************************************************/
+NFC_API extern void NFC_Disable (void);
+
+/*******************************************************************************
+**
+** Function         NFC_Init
+**
+** Description      This function initializes control blocks for NFC
+**
+** Returns          nothing
+**
+*******************************************************************************/
+NFC_API extern void NFC_Init(tHAL_NFC_ENTRY *p_hal_entry_tbl);
+
+/*******************************************************************************
+**
+** Function         NFC_GetLmrtSize
+**
+** Description      Called by application wto query the Listen Mode Routing
+**                  Table size supported by NFCC
+**
+** Returns          Listen Mode Routing Table size
+**
+*******************************************************************************/
+NFC_API extern UINT16 NFC_GetLmrtSize(void);
+
+/*******************************************************************************
+**
+** Function         NFC_SetConfig
+**
+** Description      This function is called to send the configuration parameter
+**                  TLV to NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
+**
+** Parameters       tlv_size - the length of p_param_tlvs.
+**                  p_param_tlvs - the parameter ID/Len/Value list
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SetConfig (UINT8     tlv_size,
+                                          UINT8    *p_param_tlvs);
+
+/*******************************************************************************
+**
+** Function         NFC_GetConfig
+**
+** Description      This function is called to retrieve the parameter TLV from NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_GET_CONFIG_REVT.
+**
+** Parameters       num_ids - the number of parameter IDs
+**                  p_param_ids - the parameter ID list.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_GetConfig (UINT8     num_ids,
+                                          UINT8    *p_param_ids);
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeDiscover
+**
+** Description      This function is called to enable or disable NFCEE Discovery.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_DISCOVER_REVT.
+**                  The notification from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_INFO_REVT.
+**
+** Parameters       discover - 1 to enable discover, 0 to disable.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_NfceeDiscover (BOOLEAN discover);
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeModeSet
+**
+** Description      This function is called to activate or de-activate an NFCEE
+**                  connected to the NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_MODE_SET_REVT.
+**
+** Parameters       nfcee_id - the NFCEE to activate or de-activate.
+**                  mode - 0 to activate NFCEE, 1 to de-activate.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_NfceeModeSet (UINT8              nfcee_id,
+                                             tNFC_NFCEE_MODE    mode);
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryMap
+**
+** Description      This function is called to set the discovery interface mapping.
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+**                  NFC_MAP_DEVT.
+**
+** Parameters       num - the number of items in p_params.
+**                  p_maps - the discovery interface mappings
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_DiscoveryMap(UINT8 num, tNFC_DISCOVER_MAPS *p_maps,
+                                        tNFC_DISCOVER_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryStart
+**
+** Description      This function is called to start Polling and/or Listening.
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+**                  NFC_START_DEVT. The notification from NFCC is reported by
+**                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
+**
+** Parameters       num_params - the number of items in p_params.
+**                  p_params - the discovery parameters
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_DiscoveryStart(UINT8                 num_params,
+                                              tNFC_DISCOVER_PARAMS *p_params,
+                                              tNFC_DISCOVER_CBACK  *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoverySelect
+**
+** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
+**                  the application needs to use this function to select the
+**                  the logical endpoint to continue. The response from NFCC is
+**                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
+**
+** Parameters       rf_disc_id - The ID identifies the remote device.
+**                  protocol - the logical endpoint on the remote devide
+**                  rf_interface - the RF interface to communicate with NFCC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_DiscoverySelect (UINT8    rf_disc_id,
+                                                UINT8    protocol,
+                                                UINT8    rf_interface);
+
+/*******************************************************************************
+**
+** Function         NFC_ConnCreate
+**
+** Description      This function is called to create a logical connection with
+**                  NFCC for data exchange.
+**                  The response from NFCC is reported in tNFC_CONN_CBACK
+**                  as NFC_CONN_CREATE_CEVT.
+**
+** Parameters       dest_type - the destination type
+**                  id   - the NFCEE ID or RF Discovery ID .
+**                  protocol - the protocol
+**                  p_cback - the data callback function to receive data fron NFCC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_ConnCreate(UINT8             dest_type,
+                                          UINT8             id,
+                                          UINT8             protocol,
+                                          tNFC_CONN_CBACK  *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_ConnClose
+**
+** Description      This function is called to close a logical connection with
+**                  NFCC.
+**                  The response from NFCC is reported in tNFC_CONN_CBACK
+**                  as NFC_CONN_CLOSE_CEVT.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_ConnClose(UINT8 conn_id);
+
+/*******************************************************************************
+**
+** Function         NFC_SetStaticRfCback
+**
+** Description      This function is called to update the data callback function
+**                  to receive the data for the given connection id.
+**
+** Parameters       p_cback - the connection callback function
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+NFC_API extern void NFC_SetStaticRfCback(tNFC_CONN_CBACK    *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_SendData
+**
+** Description      This function is called to send the given data packet
+**                  to the connection identified by the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**                  p_data - the data packet
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SendData(UINT8       conn_id,
+                                        BT_HDR     *p_data);
+
+/*******************************************************************************
+**
+** Function         NFC_FlushData
+**
+** Description      This function is called to discard the tx data queue of
+**                  the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_FlushData (UINT8       conn_id);
+
+/*******************************************************************************
+**
+** Function         NFC_Deactivate
+**
+** Description      This function is called to stop the discovery process or
+**                  put the listen device in sleep mode or terminate the NFC link.
+**
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
+**                  as NFC_DEACTIVATE_DEVT.
+**
+** Parameters       deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_Deactivate(tNFC_DEACT_TYPE deactivate_type);
+
+/*******************************************************************************
+**
+** Function         NFC_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication parameters
+**                  once the Frame RF Interface has been activated.
+**
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_RF_COMM_PARAMS_UPDATE_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_UpdateRFCommParams (tNFC_RF_COMM_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function         NFC_SetPowerOffSleep
+**
+** Description      This function closes/opens transport and turns off/on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SetPowerOffSleep (BOOLEAN enable);
+
+/*******************************************************************************
+**
+** Function         NFC_PowerCycleNFCC
+**
+** Description      This function turns off and then on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_PowerCycleNFCC (void);
+
+/*******************************************************************************
+**
+** Function         NFC_SetRouting
+**
+** Description      This function is called to configure the CE routing table.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_SET_ROUTING_REVT.
+**
+** Parameters
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SetRouting(BOOLEAN     more,
+                                            UINT8       nfcee_id,
+                                            UINT8       num_tlv,
+                                            UINT8       tlv_size,
+                                            UINT8      *p_param_tlvs);
+
+/*******************************************************************************
+**
+** Function         NFC_GetRouting
+**
+** Description      This function is called to retrieve the CE routing table from
+**                  NFCC. The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_GET_ROUTING_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_GetRouting(void);
+
+/*******************************************************************************
+**
+** Function         NFC_RegVSCback
+**
+** Description      This function is called to register or de-register a callback
+**                  function to receive Proprietary NCI response and notification
+**                  events.
+**                  The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_RegVSCback (BOOLEAN          is_register,
+                                           tNFC_VS_CBACK   *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_SendVsCommand
+**
+** Description      This function is called to send the given vendor specific
+**                  command to NFCC. The response from NFCC is reported to the
+**                  given tNFC_VS_CBACK as (oid).
+**
+** Parameters       oid - The opcode of the VS command.
+**                  p_data - The parameters for the VS command
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_SendVsCommand(UINT8          oid,
+                                             BT_HDR        *p_data,
+                                             tNFC_VS_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         NFC_TestLoopback
+**
+** Description      This function is called to send the given data packet
+**                  to NFCC for loopback test.
+**                  When loopback data is received from NFCC, tNFC_TEST_CBACK .
+**                  reports a NFC_LOOPBACK_TEVT.
+**
+** Parameters       p_data - the data packet
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS NFC_TestLoopback(BT_HDR *p_data);
+
+
+/*******************************************************************************
+**
+** Function         NFC_SetTraceLevel
+**
+** Description      This function sets the trace level for NFC.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 NFC_SetTraceLevel (UINT8 new_level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_API_H */
diff --git a/src/nfc/include/rw_api.h b/src/nfc/include/rw_api.h
new file mode 100644
index 0000000..5adf492
--- /dev/null
+++ b/src/nfc/include/rw_api.h
@@ -0,0 +1,1265 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Reader/Writer mode
+ *  related API function external definitions.
+ *
+ ******************************************************************************/
+
+#ifndef RW_API_H
+#define RW_API_H
+#include "tags_defs.h"
+
+#define RW_T1T_BLD_ADD(a, k, y)   a = ((k & 0xF) << 3) | (y&0x7);
+#define RW_T1T_BLD_ADDS(a, s)     a = ((s & 0xF) << 4);
+
+#define RW_T1T_FIRST_EVT    0x20
+#define RW_T2T_FIRST_EVT    0x40
+#define RW_T3T_FIRST_EVT    0x60
+#define RW_T4T_FIRST_EVT    0x80
+#define RW_I93_FIRST_EVT    0xA0
+
+enum
+{
+    /* Note: the order of these events can not be changed */
+    /* Type 1 tag events for tRW_CBACK */
+    RW_T1T_RID_EVT = RW_T1T_FIRST_EVT,          /* Read ID command completd              */
+    RW_T1T_RALL_CPLT_EVT,                       /* Read All command completed            */
+    RW_T1T_READ_CPLT_EVT,                       /* Read byte completed                   */
+    RW_T1T_WRITE_E_CPLT_EVT,                    /* Write byte after erase completed      */
+    RW_T1T_WRITE_NE_CPLT_EVT,                   /* Write byte with no erase completed    */
+    RW_T1T_RSEG_CPLT_EVT,                       /* Read segment completed                */
+    RW_T1T_READ8_CPLT_EVT,                      /* Read block completed                  */
+    RW_T1T_WRITE_E8_CPLT_EVT,                   /* Write block after erase completed     */
+    RW_T1T_WRITE_NE8_CPLT_EVT,                  /* Write block with no erase completed   */
+    RW_T1T_TLV_DETECT_EVT,                      /* Lock/Mem/Prop tlv detection complete  */
+    RW_T1T_NDEF_DETECT_EVT,                     /* NDEF detection complete               */
+    RW_T1T_NDEF_READ_EVT,                       /* NDEF read completed                   */
+    RW_T1T_NDEF_WRITE_EVT,                      /* NDEF write complete                   */
+    RW_T1T_SET_TAG_RO_EVT,                      /* Tag is set as read only               */
+    RW_T1T_RAW_FRAME_EVT,                       /* Response of raw frame sent            */
+    RW_T1T_PRESENCE_CHECK_EVT,                  /* Response to RW_T1tPresenceCheck       */
+    RW_T1T_FORMAT_CPLT_EVT,                     /* Tag Formated                          */
+    RW_T1T_INTF_ERROR_EVT,                      /* RF Interface error event              */
+    RW_T1T_MAX_EVT,
+
+    /* Type 2 tag events */
+    RW_T2T_READ_CPLT_EVT = RW_T2T_FIRST_EVT,    /* Read completed                        */
+    RW_T2T_WRITE_CPLT_EVT,                      /* Write completed                       */
+    RW_T2T_SELECT_CPLT_EVT,                     /* Sector select completed               */
+    RW_T2T_NDEF_DETECT_EVT,                     /* NDEF detection complete               */
+    RW_T2T_TLV_DETECT_EVT,                      /* Lock/Mem/Prop tlv detection complete  */
+    RW_T2T_NDEF_READ_EVT,                       /* NDEF read completed                   */
+    RW_T2T_NDEF_WRITE_EVT,                      /* NDEF write complete                   */
+    RW_T2T_SET_TAG_RO_EVT,                      /* Tag is set as read only               */
+    RW_T2T_RAW_FRAME_EVT,                       /* Response of raw frame sent            */
+    RW_T2T_PRESENCE_CHECK_EVT,                  /* Response to RW_T2tPresenceCheck       */
+    RW_T2T_FORMAT_CPLT_EVT,                     /* Tag Formated                          */
+    RW_T2T_INTF_ERROR_EVT,                      /* RF Interface error event              */
+    RW_T2T_MAX_EVT,
+
+    /* Type 3 tag events for tRW_CBACK */
+    RW_T3T_CHECK_CPLT_EVT = RW_T3T_FIRST_EVT,   /* Read completed                           */
+    RW_T3T_UPDATE_CPLT_EVT,                     /* Write completed                          */
+    RW_T3T_CHECK_EVT,                           /* Segment of data received from type 3 tag */
+    RW_T3T_RAW_FRAME_EVT,                       /* SendRawFrame response                    */
+    RW_T3T_NDEF_DETECT_EVT,                     /* NDEF detection complete                  */
+    RW_T3T_PRESENCE_CHECK_EVT,                  /* Response to RW_T3tPresenceCheck          */
+    RW_T3T_POLL_EVT,                            /* Response to RW_T3tPoll                   */
+    RW_T3T_GET_SYSTEM_CODES_EVT,                /* Response to RW_T3tGetSystemCodes         */
+    RW_T3T_FORMAT_CPLT_EVT,                     /* Tag Formated (Felica-Lite only)          */
+    RW_T3T_INTF_ERROR_EVT,                      /* RF Interface error event                 */
+    RW_T3T_MAX_EVT,
+
+    /* Type 4 tag events for tRW_CBACK */
+    RW_T4T_NDEF_DETECT_EVT = RW_T4T_FIRST_EVT,  /* Result of NDEF detection procedure       */
+                                                /* Mandatory NDEF file is selected          */
+    RW_T4T_NDEF_READ_EVT,                       /* Segment of data received from type 4 tag */
+    RW_T4T_NDEF_READ_CPLT_EVT,                  /* Read operation completed                 */
+    RW_T4T_NDEF_READ_FAIL_EVT,                  /* Read operation failed                    */
+    RW_T4T_NDEF_UPDATE_CPLT_EVT,                /* Update operation completed               */
+    RW_T4T_NDEF_UPDATE_FAIL_EVT,                /* Update operation failed                  */
+    RW_T4T_PRESENCE_CHECK_EVT,                  /* Response to RW_T4tPresenceCheck          */
+    RW_T4T_RAW_FRAME_EVT,                       /* Response of raw frame sent               */
+    RW_T4T_INTF_ERROR_EVT,                      /* RF Interface error event                 */
+    RW_T4T_MAX_EVT,
+
+    /* ISO 15693 tag events for tRW_CBACK */
+    RW_I93_NDEF_DETECT_EVT = RW_I93_FIRST_EVT,  /* Result of NDEF detection procedure */
+    RW_I93_NDEF_READ_EVT,                       /* Segment of data received from tag  */
+    RW_I93_NDEF_READ_CPLT_EVT,                  /* Read operation completed           */
+    RW_I93_NDEF_READ_FAIL_EVT,                  /* Read operation failed              */
+    RW_I93_NDEF_UPDATE_CPLT_EVT,                /* Update operation completed         */
+    RW_I93_NDEF_UPDATE_FAIL_EVT,                /* Update operation failed            */
+    RW_I93_FORMAT_CPLT_EVT,                     /* Format procedure complete          */
+    RW_I93_SET_TAG_RO_EVT,                      /* Set read-only procedure complete   */
+    RW_I93_INVENTORY_EVT,                       /* Response of Inventory              */
+    RW_I93_DATA_EVT,                            /* Response of Read, Get Multi Security */
+    RW_I93_SYS_INFO_EVT,                        /* Response of System Information     */
+    RW_I93_CMD_CMPL_EVT,                        /* Command complete                   */
+    RW_I93_PRESENCE_CHECK_EVT,                  /* Response to RW_I93PresenceCheck    */
+    RW_I93_RAW_FRAME_EVT,                       /* Response of raw frame sent         */
+    RW_I93_INTF_ERROR_EVT,                      /* RF Interface error event           */
+    RW_I93_MAX_EVT
+};
+
+#define RW_RAW_FRAME_EVT     0xFF
+
+typedef UINT8 tRW_EVENT;
+
+#define RW_NDEF_FL_READ_ONLY                    0x01    /* Tag is read only              */
+#define RW_NDEF_FL_FORMATED                     0x02    /* Tag formated for NDEF         */
+#define RW_NDEF_FL_SUPPORTED                    0x04    /* NDEF supported by the tag     */
+#define RW_NDEF_FL_UNKNOWN                      0x08    /* Unable to find if tag is ndef capable/formated/read only */
+#define RW_NDEF_FL_FORMATABLE                   0x10    /* Tag supports format operation */
+#define RW_NDEF_FL_SOFT_LOCKABLE                0x20    /* Tag can be soft locked */
+#define RW_NDEF_FL_HARD_LOCKABLE                0x40    /* Tag can be hard locked */
+#define RW_NDEF_FL_OTP                          0x80    /* Tag is one time programmable */
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    UINT8           hr[T1T_HR_LEN];
+    UINT8           uid[T1T_CMD_UID_LEN];
+} tRW_T1T_RID_EVT;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    UINT16          msg_len;            /* Length of the NDEF message */
+} tRW_T2T_DETECT;
+
+typedef struct
+{
+    tNFC_STATUS     status;             /* Status of the POLL request */
+    UINT8           rc;                 /* RC (request code) used in the POLL request */
+    UINT8           response_num;       /* Number of SENSF_RES responses */
+    UINT8           response_bufsize;   /* Size of SENSF_RES responses */
+    UINT8           *response_buf;      /* Buffer of responses (length + SENSF_RES) see $8.1.2.2 of NCI specs */
+} tRW_T3T_POLL;
+
+typedef struct
+{
+    tNFC_STATUS     status;             /* Status of the Get System Codes request */
+    UINT8           num_system_codes;   /* Number of system codes */
+    UINT16          *p_system_codes;    /* Table of system codes */
+} tRW_T3T_SYSTEM_CODES;
+
+typedef struct
+{
+    tNFC_STATUS     status;             /* status of NDEF detection */
+    tNFC_PROTOCOL   protocol;           /* protocol used to detect NDEF */
+    UINT32          max_size;           /* max number of bytes available for NDEF data */
+    UINT32          cur_size;           /* current size of stored NDEF data (in bytes) */
+    UINT8           flags;              /* Flags to indicate NDEF capability,formated,formatable and read only */
+} tRW_DETECT_NDEF_DATA;
+
+typedef struct
+{
+    tNFC_STATUS     status;             /* status of NDEF detection */
+    tNFC_PROTOCOL   protocol;           /* protocol used to detect TLV */
+    UINT8           num_bytes;          /* number of reserved/lock bytes based on the type of tlv */
+} tRW_DETECT_TLV_DATA;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    BT_HDR         *p_data;
+} tRW_READ_DATA;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    UINT8           sw1;
+    UINT8           sw2;
+} tRW_T4T_SW;
+
+typedef struct                              /* RW_I93_INVENTORY_EVT        */
+{
+    tNFC_STATUS     status;                 /* status of Inventory command */
+    UINT8           dsfid;                  /* DSFID                       */
+    UINT8           uid[I93_UID_BYTE_LEN];  /* UID[0]:MSB, ... UID[7]:LSB  */
+} tRW_I93_INVENTORY;
+
+typedef struct                              /* RW_I93_DATA_EVT               */
+{
+    tNFC_STATUS     status;                 /* status of Read/Get security status command */
+    UINT8           command;                /* sent command                  */
+    BT_HDR         *p_data;                 /* block data of security status */
+} tRW_I93_DATA;
+
+typedef struct                              /* RW_I93_SYS_INFO_EVT             */
+{
+    tNFC_STATUS     status;                 /* status of Get Sys Info command  */
+    UINT8           info_flags;             /* information flags               */
+    UINT8           uid[I93_UID_BYTE_LEN];  /* UID[0]:MSB, ... UID[7]:LSB      */
+    UINT8           dsfid;                  /* DSFID if I93_INFO_FLAG_DSFID    */
+    UINT8           afi;                    /* AFI if I93_INFO_FLAG_AFI        */
+    UINT16          num_block;              /* number of blocks if I93_INFO_FLAG_MEM_SIZE   */
+    UINT8           block_size;             /* block size in byte if I93_INFO_FLAG_MEM_SIZE */
+    UINT8           IC_reference;           /* IC Reference if I93_INFO_FLAG_IC_REF         */
+} tRW_I93_SYS_INFO;
+
+typedef struct                              /* RW_I93_CMD_CMPL_EVT             */
+{
+    tNFC_STATUS     status;                 /* status of sent command          */
+    UINT8           command;                /* sent command                    */
+    UINT8           error_code;             /* error code; I93_ERROR_CODE_XXX  */
+} tRW_I93_CMD_CMPL;
+
+typedef struct
+{
+    tNFC_STATUS     status;
+    BT_HDR         *p_data;
+} tRW_RAW_FRAME;
+
+typedef union
+{
+    tNFC_STATUS             status;
+    tRW_T3T_POLL            t3t_poll;   /* Response to t3t poll command          */
+    tRW_T3T_SYSTEM_CODES    t3t_sc;     /* Received system codes from t3 tag     */
+    tRW_DETECT_TLV_DATA     tlv;        /* The information of detected TLV data  */
+    tRW_DETECT_NDEF_DATA    ndef;       /* The information of detected NDEF data */
+    tRW_READ_DATA           data;       /* The received data from a tag          */
+    tRW_RAW_FRAME           raw_frame;  /* Response of raw frame sent            */
+    tRW_T4T_SW              t4t_sw;     /* Received status words from a tag      */
+    tRW_I93_INVENTORY       i93_inventory;  /* ISO 15693 Inventory response      */
+    tRW_I93_DATA            i93_data;       /* ISO 15693 Data response           */
+    tRW_I93_SYS_INFO        i93_sys_info;   /* ISO 15693 System Information      */
+    tRW_I93_CMD_CMPL        i93_cmd_cmpl;   /* ISO 15693 Command complete        */
+} tRW_DATA;
+
+
+typedef void (tRW_CBACK) (tRW_EVENT event, tRW_DATA *p_data);
+
+/*******************************************************************************
+**
+** Function         RW_T1tRid
+**
+** Description      This function send a RID command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tRid (void);
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadAll
+**
+** Description      This function send a RALL command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tReadAll (void);
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead
+**
+** Description      This function send a READ command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tRead (UINT8 block, UINT8 byte);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase
+**
+** Description      This function send a WRITE-E command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteErase (UINT8 block, UINT8 byte, UINT8 new_byte);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase
+**
+** Description      This function send a WRITE-NE command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteNoErase (UINT8 block, UINT8 byte, UINT8 new_byte);
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadSeg
+**
+** Description      This function send a RSEG command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tReadSeg (UINT8 segment);
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead8
+**
+** Description      This function send a READ8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tRead8 (UINT8 block);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase8
+**
+** Description      This function send a WRITE-E8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteErase8 (UINT8 block, UINT8 *p_new_dat);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase8
+**
+** Description      This function send a WRITE-NE8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteNoErase8 (UINT8 block, UINT8 *p_new_dat);
+
+/*******************************************************************************
+**
+** Function         RW_T1tLocateTlv
+**
+** Description      This function is called to find the start of the given TLV
+**
+** Parameters:      void
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type);
+
+/*******************************************************************************
+**
+** Function         RW_T2tDetectNDef
+**
+** Description      This function can be called to detect if there is an NDEF
+**                  message on the tag.
+**
+** Parameters:      void
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadNDef
+**
+** Description      This function can be called to read the NDEF message on the tag.
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tReadNDef (UINT8 *p_buffer, UINT16 buf_len);
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNDef
+**
+** Description      This function can be called to write an NDEF message to the tag.
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg);
+
+/*******************************************************************************
+**
+** Function         RW_T1tSetTagReadOnly
+**
+** Description      This function can be called to set the tag in to read only
+**                  state
+**
+** Parameters:      b_hard_lock: To hard lock or just soft lock the tag
+**
+** Returns          NCI_STATUS_OK, if set readonly operation started.
+**                                 Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock);
+
+/*****************************************************************************
+**
+** Function         RW_T1tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T1tPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function         RW_T1tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tFormatNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_T2tLocateTlv
+**
+** Description      This function is called to find the start of the given TLV
+**
+** Returns          Pointer to the TLV, if successful. Otherwise, NULL.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tLocateTlv(UINT8 tlv_type);
+
+/*******************************************************************************
+**
+** Function         RW_T2tRead
+**
+** Description      This function issues the Type 2 Tag READ command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_READ_EVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tRead (UINT16 block);
+
+/*******************************************************************************
+**
+** Function         RW_T2tWrite
+**
+** Description      This function issues the Type 2 Tag WRITE command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_WRITE_EVT.
+**
+**                  p_write_data points to the array of 4 bytes to be written
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tWrite (UINT16 block, UINT8 *p_write_data);
+
+/*******************************************************************************
+**
+** Function         RW_T2tSectorSelect
+**
+** Description      This function issues the Type 2 Tag SECTOR-SELECT command
+**                  packet 1. If a NACK is received as the response, the callback
+**                  function will be called with a RW_T2T_SECTOR_SELECT_EVT. If
+**                  an ACK is received as the response, the command packet 2 with
+**                  the given sector number is sent to the peer device. When the
+**                  response for packet 2 is received, the callback function will
+**                  be called with a RW_T2T_SECTOR_SELECT_EVT.
+**
+**                  A sector is 256 contiguous blocks (1024 bytes).
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tSectorSelect (UINT8 sector);
+
+/*******************************************************************************
+**
+** Function         RW_T2tDetectNDef
+**
+** Description      This function will find NDEF message if any in the Tag
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_T2tReadNDef
+**
+** Description      This function can be called to read the NDEF message on the tag.
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tReadNDef (UINT8 *p_buffer, UINT16 buf_len);
+
+/*******************************************************************************
+**
+** Function         RW_T2tWriteNDef
+**
+** Description      This function can be called to write an NDEF message to the tag.
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tWriteNDef (UINT16 msg_len, UINT8 *p_msg );
+
+/*******************************************************************************
+**
+** Function         RW_T2tSetTagReadOnly
+**
+** Description      This function can be called to set the tag in to read only
+**                  state
+**
+** Parameters:      b_hard_lock:   To indicate hard lock the tag or not
+**
+** Returns          NCI_STATUS_OK, if set readonly operation started.
+**                                 Otherwise, error status.
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tSetTagReadOnly (BOOLEAN b_hard_lock);
+
+/*****************************************************************************
+**
+** Function         RW_T2tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T2tPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function         RW_T2tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_FAILED: otherwise
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tFormatNDef (void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tDetectNDef
+**
+** Description
+**      This function is used to perform NDEF detection on a Type 3 tag, and
+**      retrieve the tag's NDEF attribute information (block 0).
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tDetectNDef (void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tFormatNDef
+**
+** Description
+**      Format a type-3 tag for NDEF.
+**
+**      Only Felica-Lite tags are supported by this API. The
+**      RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tFormatNDef (void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheckNDef
+**
+** Description
+**      Retrieve NDEF contents from a Type3 tag.
+**
+**      The RW_T3T_CHECK_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to
+**      notify the application all segments have been received.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Check
+**      commands (if necessary) - depending on the tag's Nbr (max number of
+**      blocks per read) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tCheckNDef (void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdateNDef
+**
+** Description
+**      Write NDEF contents to a Type3 tag.
+**
+**      The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
+**      application of the response.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Update
+**      commands (if necessary) - depending on the tag's Nbw (max number of
+**      blocks per write) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_REFUSED: tag is read-only
+**      NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheck
+**
+** Description
+**      Read (non-NDEF) contents from a Type3 tag.
+**
+**      The RW_READ_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
+**      notify the application all segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks);
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdate
+**
+** Description
+**      Write (non-NDEF) contents to a Type3 tag.
+**
+**      The RW_WRITE_CPLT_EVT event is used to notify the application all
+**      segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the tag's
+**      Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T3tSendRawFrame
+**
+** Description
+**      This function is called to send a raw data frame to the peer device.
+**      When type 3 tag receives response from peer, the callback function
+**      will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+**      The raw frame should be a properly formatted Type 3 tag message.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T3tPoll
+**
+** Description
+**      Send POLL command
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn);
+
+/*****************************************************************************
+**
+** Function         RW_T3tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tPresenceCheck (void);
+
+/*****************************************************************************
+**
+** Function         RW_T3tGetSystemCodes
+**
+** Description
+**      Get systems codes supported by the activated tag:
+**              Poll for wildcard (FFFF):
+**                  - If felica-lite code then poll for ndef (12fc)
+**                  - Otherwise send RequestSystmCode command to get
+**                    system codes.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T3tGetSystemCodes (void);
+
+/*******************************************************************************
+**
+** Function         RW_T4tDetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_T4T_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tDetectNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_T4tReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_T4tDetectNDef() must be called before using this
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_T4T_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+**                      RW_T4T_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tReadNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_T4tUpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_T4tDetectNDef() must be called before using this
+**                        Updating data must not be removed until returning event
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tUpdateNDef (UINT16 length, UINT8 *p_data);
+
+/*****************************************************************************
+**
+** Function         RW_T4tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_T4tPresenceCheck (void);
+
+
+/*******************************************************************************
+**
+** Function         RW_I93Inventory
+**
+** Description      This function send Inventory command
+**                  If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93Inventory (UINT8 afi, UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function         RW_I93StayQuiet
+**
+** Description      This function send Inventory command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93StayQuiet (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadSingleBlock
+**
+** Description      This function send Read Single Block command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ReadSingleBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteSingleBlock
+**
+** Description      This function send Write Single Block command
+**                  Application must get block size first by calling RW_I93GetSysInfo().
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteSingleBlock (UINT8 block_number,
+                                                   UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         RW_I93LockBlock
+**
+** Description      This function send Lock Block command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93LockBlock (UINT8 block_number);
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadMultipleBlocks
+**
+** Description      This function send Read Multiple Blocks command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ReadMultipleBlocks (UINT8 first_block_number,
+                                                     UINT16 number_blocks);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteMultipleBlocks
+**
+** Description      This function send Write Multiple Blocks command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8  first_block_number,
+                                                      UINT16 number_blocks,
+                                                      UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         RW_I93Select
+**
+** Description      This function send Select command
+**
+**                  UID[0]: 0xE0, MSB
+**                  UID[1]: IC Mfg Code
+**                  ...
+**                  UID[7]: LSB
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93Select (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function         RW_I93ResetToReady
+**
+** Description      This function send Reset To Ready command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ResetToReady (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteAFI
+**
+** Description      This function send Write AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteAFI (UINT8 afi);
+
+/*******************************************************************************
+**
+** Function         RW_I93LockAFI
+**
+** Description      This function send Lock AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93LockAFI (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteDSFID
+**
+** Description      This function send Write DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid);
+
+/*******************************************************************************
+**
+** Function         RW_I93LockDSFID
+**
+** Description      This function send Lock DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93LockDSFID (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93GetSysInfo
+**
+** Description      This function send Get System Information command
+**                  If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid);
+
+/*******************************************************************************
+**
+** Function         RW_I93GetMultiBlockSecurityStatus
+**
+** Description      This function send Get Multiple Block Security Status command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT8  first_block_number,
+                                                              UINT16 number_blocks);
+
+/*******************************************************************************
+**
+** Function         RW_I93DetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_I93_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93DetectNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_I93DetectNDef() must be called before using this
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+**                      RW_I93_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93ReadNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93UpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_I93DetectNDef() must be called before using this
+**                        Updating data must not be removed until returning event
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_I93_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function         RW_I93FormatNDef
+**
+** Description      This function performs formatting procedure
+**
+**                  RW_I93_FORMAT_CPLT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93FormatNDef (void);
+
+/*******************************************************************************
+**
+** Function         RW_I93SetTagReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: RW_I93DetectNDef() must be called before using this
+**                        Updating data must not be removed until returning event
+**
+**                  The RW_I93_SET_TAG_RO_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93SetTagReadOnly (void);
+
+/*****************************************************************************
+**
+** Function         RW_I93PresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
+**                  presence or non-presence.
+**
+** Returns          NFC_STATUS_OK, if raw data frame sent
+**                  NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**                  NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+NFC_API extern tNFC_STATUS RW_I93PresenceCheck (void);
+
+/*******************************************************************************
+**
+** Function         RW_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len);
+
+/*******************************************************************************
+**
+** Function         RW_SetActivatedTagType
+**
+** Description      This function sets tag type for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+NFC_API extern tNFC_STATUS RW_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, tRW_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         RW_SetTraceLevel
+**
+** Description      This function sets the trace level for Reader/Writer mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+NFC_API extern UINT8 RW_SetTraceLevel (UINT8 new_level);
+
+#endif /* RW_API_H */
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
new file mode 100644
index 0000000..78a0bb3
--- /dev/null
+++ b/src/nfc/include/tags_defs.h
@@ -0,0 +1,519 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Tags related
+ *  definitions from the specification.
+ *
+ ******************************************************************************/
+
+#ifndef TAGS_DEFS_H
+#define TAGS_DEFS_H
+
+/* Manufacturer ID */
+#define TAG_BRCM_MID            0x2E  /* BROADCOM CORPORATION                           */
+#define TAG_MIFARE_MID          0x04  /* MIFARE                                         */
+#define TAG_KOVIO_MID           0x37  /* KOVIO                                          */
+#define TAG_INFINEON_MID        0x05  /* Infineon Technologies                          */
+
+/* TLV types present in Type1 and Type 2 Tags */
+#define TAG_NULL_TLV            0     /* May be used for padding. SHALL ignore this     */
+#define TAG_LOCK_CTRL_TLV       1     /* Defines details of the lock bytes              */
+#define TAG_MEM_CTRL_TLV        2     /* Identifies reserved memory areas               */
+#define TAG_NDEF_TLV            3     /* Contains the NDEF message                      */
+#define TAG_PROPRIETARY_TLV     0xFD  /* Tag proprietary information                    */
+#define TAG_TERMINATOR_TLV      0xFE  /* Last TLV block in the data area                */
+#define TAG_BITS_PER_BYTE       0x08  /* Number of bits in every tag byte               */
+#define TAG_MAX_UID_LEN         0x0A  /* Max UID Len of type 1 and type 2 tag           */
+
+#define TAG_LONG_NDEF_LEN_FIELD_BYTE0   0xFF  /* Byte 0 Length field to indicate LNDEF  */
+#define TAG_DEFAULT_TLV_LEN             3     /* Tlv len for LOCK_CTRL/MEM TLV per spec */
+
+/* Type 1 Tag related definitions */
+
+#define T1T_STATIC_BLOCKS       0x0F  /* block 0 to Block E                             */
+#define T1T_BLOCK_SIZE          0x08  /* T1T Block size in bytes                        */
+
+#define T1T_STATIC_SIZE         T1T_STATIC_BLOCKS * T1T_BLOCK_SIZE /* Static Tag size   */
+
+#define T1T_SEGMENT_SIZE        0x80  /* Size of Type 1 Tag segment in bytes            */
+#define T1T_MAX_SEGMENTS        0x10  /* Maximum segment supported by Type 1 Tag        */
+#define T1T_BLOCKS_PER_SEGMENT  0x10  /* Number of blocks present in a segment          */
+#define T1T_OTP_LOCK_RES_BYTES  0x10  /* No.of default OTP,staticlocks,res bytes in tag */
+
+#define T1T_STATIC_HR0          0x11  /* HRO value to indicate static Tag               */
+#define T1T_DYNAMIC_HR0         0x12  /* 0x1y, as long as (y!=1)                        */
+#define T1T_NDEF_SUPPORTED      0x10  /* HR0 value is 0x1y, indicates NDEF supported    */
+#define T1T_HR1                 0x00  /* should be ignored                              */
+#define T1T_UID_BLOCK           0x00  /* UID block                                      */
+#define T1T_RES_BLOCK           0x0D  /* Reserved block                                 */
+#define T1T_LOCK_BLOCK          0x0E  /* Static lock block                              */
+#define T1T_MID_OFFSET          0x06  /* Manufacturer ID offset                         */
+#define T1T_STATIC_RES_OFFSET   0x68  /* Reserved bytes offset                          */
+#define T1T_LOCK_0_OFFSET       0x70  /* Static lock offset                             */
+#define T1T_LOCK_1_OFFSET       0x71  /* Static lock offset                             */
+#define T1T_DYNAMIC_LOCK_OFFSET 0x78  /* Block F - typically used for dynamic locks     */
+#define T1T_DYNAMIC_LOCK_BYTES  0x08
+
+#define T1T_RES_BYTE_LEN        1     /* the len of reserved byte in T1T block 0        */
+
+/* Capability Container definitions */
+#define T1T_CC_BLOCK            1     /* Capability container block                     */
+#define T1T_CC_LEN              4     /* the len of CC used in T1T tag                  */
+/* CC offset */
+#define T1T_CC_NMN_OFFSET       0x00  /* Offset for NDEF magic number in CC             */
+#define T1T_CC_VNO_OFFSET       0x01  /* Offset for Version number in CC                */
+#define T1T_CC_TMS_OFFSET       0x02  /* Offset for Tag memory size in CC               */
+#define T1T_CC_RWA_OFFSET       0x03  /* Offset for Read/Write access in CC             */
+#define T1T_CC_NMN_BYTE         0x08  /* NDEF Magic Number byte number                  */
+#define T1T_CC_VNO_BYTE         0x09  /* Version Number byte number                     */
+#define T1T_CC_TMS_BYTE         0x0A  /* Tag Memory Size byte number                    */
+#define T1T_CC_RWA_BYTE         0x0B  /* Read Write Access byte number                  */
+#define T1T_CC_NMN              0xE1  /* NDEF Magic Number                              */
+#define T1T_CC_LEGACY_VNO       0x10  /* Supported Legacy Version                       */
+#define T1T_CC_VNO              0x11  /* Version Number                                 */
+#define T1T_CC_TMS_STATIC       0x0E  /* TMS static memory - (8 * (n+1)).               */
+#define T1T_CC_RWA_RW           0x00  /* RWA - Read/write allowed                       */
+#define T1T_CC_RWA_RO           0x0F  /* RWA - Read only                                */
+
+#define T1T_TAG_NULL            0     /* May be used for padding. SHALL ignore this     */
+#define T1T_TAG_LOCK_CTRL       1     /* Defines details of the lock bytes              */
+#define T1T_TAG_MEM_CTRL        2     /* Identifies reserved memory areas               */
+#define T1T_TAG_NDEF            3     /* Contains the NDEF message                      */
+#define T1T_TAG_PROPRIETARY     0xFD  /* Tag proprietary information                    */
+#define T1T_TAG_TERMINATOR      0xFE  /* Last TLV block in the data area                */
+
+#define T1T_DEFAULT_TLV_LEN     3     /* Tlv len for LOCK_CTRL/MEM TLV per spec         */
+#define T1T_TLV_TYPE_LEN        1     /* Tlv type identifier len                        */
+#define T1T_DEFAULT_TLV_LEN_FIELD_LEN   1     /* Length field size of  lock/mem tlv     */
+
+#define T1T_HR_LEN              2     /* the len of HR used in Type 1 Tag               */
+#define T1T_CMD_UID_LEN         4     /* the len of UID used in Type 1 Tag Commands     */
+#define T1T_UID_LEN             7     /* the len of UID used in Type 1 Tag              */
+#define T1T_ADD_LEN             1
+
+#define T1T_SHORT_NDEF_LEN_FIELD_LEN    1 /* Length Field size of short NDEF Message    */
+#define T1T_LONG_NDEF_LEN_FIELD_LEN     3 /* Length Field size of Long NDEF Message     */
+#define T1T_LONG_NDEF_LEN_FIELD_BYTE0   0xFF /* Byte 0 in Length field to indicate LNDEF*/
+#define T1T_LONG_NDEF_MIN_LEN           0x00FF /* Min. len of NDEF to qualify as LNDEF  */
+
+/* Type 1 Tag Commands (7 bits) */
+#define T1T_CMD_RID             0x78    /* read id                                      */
+#define T1T_CMD_RALL            0x00    /* read all bytes                               */
+#define T1T_CMD_READ            0x01    /* read (1 byte)                                */
+#define T1T_CMD_WRITE_E         0x53    /* write with erase (1 byte)                    */
+#define T1T_CMD_WRITE_NE        0x1A    /* write no erase (1 byte)                      */
+/* dynamic memory only */
+#define T1T_CMD_RSEG            0x10    /* read segment                                 */
+#define T1T_CMD_READ8           0x02    /* read (8 byte)                                */
+#define T1T_CMD_WRITE_E8        0x54    /* write with erase (8 byte)                    */
+#define T1T_CMD_WRITE_NE8       0x1B    /* write no erase (8 byte)                      */
+
+/* Lock */
+#define T1T_NUM_STATIC_LOCK_BYTES           2   /* Number of static lock bytes in tag   */
+#define T1T_BYTES_LOCKED_BY_STATIC_LOCK_BIT 4   /* Bytes locked by one static lock bit  */
+
+
+/* Type 2 Tag related definitions */
+#define T2T_STATIC_MEM_STR      0
+#define T2T_DYNAMIC_MEM_STR     1
+#define T2T_STATIC_SIZE         64
+#define T2T_STATIC_BLOCKS       16      /* block 0 to Block 15 */
+#define T2T_BLOCK_SIZE          4
+#define T2T_HEADER_BLOCKS       4
+#define T2T_HEADER_SIZE         16
+#define T2T_SECTOR_SIZE         1024
+#define T2T_BLOCKS_PER_SECTOR   0x100
+
+#define T2T_UID_LEN             4     /* the len of UID used in T2T tag */
+#define T2T_BLOCK0_UID_LEN      3     /* the len of UID in Block 0 of T2T tag */
+#define T2T_BCC0_LEN            1     /* the len of BCC0 of T2T tag */
+#define T2T_BLOCK1_UID_LEN      4     /* the len of UID in Block 1 of T2T tag */
+#define T2T_BCC1_LEN            1     /* the len of BCC0 of T2T tag */
+#define T2T_SNO_LEN             4     /* the len of Serial number used in T2T tag */
+#define T2T_INTERNAL_BYTES_LEN  2     /* the len of internal used in T2T tag */
+#define T2T_STATIC_LOCK_LEN     2     /* the len of static lock used in T2T tag */
+/* Static Lock Bytes */
+#define T2T_STATIC_LOCK0        0x0A  /* Static Lock 0 offset */
+#define T2T_STATIC_LOCK1        0x0B  /* Static Lock 1 offset */
+
+#define T2T_CC_LEN              4     /* the len of CC used in T2T tag                  */
+
+/* Capability Container definitions */
+#define T2T_CC_BLOCK		    0x03  /* Capability container block */
+#define T2T_CC0_NMN_BYTE        0x0C  /* NDEF Magic Number byte number */
+#define T2T_CC1_VNO_BYTE        0x0D  /* Version Number byte number*/
+#define T2T_CC2_TMS_BYTE        0x0E  /* Tag Memory Size byte number */
+#define T2T_CC3_RWA_BYTE        0x0F  /* Read Write Access byte number */
+#define T2T_DATA_MEM            0x10  /* Data Memory */
+
+#define T2T_CC0_NMN             0xE1  /* NDEF Magic Number */
+#define T2T_CC1_VNO             0x11  /* Version Number */
+#define T2T_CC1_LEGACY_VNO      0x10  /* Legacy Version Number */
+#define T2T_CC1_NEW_VNO         0x12  /* Another supported Version Number */
+#define T2T_CC2_TMS_STATIC      0x06  /* TMS static memory - (4 * (n+1)). */
+#define T2T_CC3_RWA_RW          0x00  /* RWA - Read/write allowed */
+#define T2T_CC3_RWA_RO          0x0F  /* RWA - Read only */
+
+#define T2T_TMS_TAG_FACTOR      0x08  /* Factor to multiply to get tag data size from TMS */
+#define T2T_DEFAULT_LOCK_BLPB   0x08  /* Bytes locked per lock bit of default locks */
+
+/* Type 2 Tag Commands  */
+#define T2T_CMD_READ            0x30    /* read  4 blocks (16 bytes) */
+#define T2T_CMD_WRITE           0xA2    /* write 1 block  (4 bytes)  */
+#define T2T_CMD_SEC_SEL         0xC2    /* Sector select             */
+#define T2T_RSP_ACK			    0xA
+#define T2T_RSP_NACK5		    0x5
+#define T2T_RSP_NACK1           0x1     /* Nack can be either 1    */
+
+#define T2T_FIRST_DATA_BLOCK    4
+#define T2T_READ_BLOCKS         4
+#define T2T_BLOCK_LEN           4
+#define T2T_READ_DATA_LEN       (T2T_BLOCK_LEN * T2T_READ_BLOCKS)
+#define T2T_WRITE_DATA_LEN      4
+
+
+/* Type 2 TLV definitions */
+#define T2T_TLV_TYPE_NULL         0     /* May be used for padding. SHALL ignore this */
+#define T2T_TLV_TYPE_LOCK_CTRL    1     /* Defines details of the lock bytes */
+#define T2T_TLV_TYPE_MEM_CTRL     2     /* Identifies reserved memory areas */
+#define T2T_TLV_TYPE_NDEF         3     /* Contains the NDEF message */
+#define T2T_TLV_TYPE_PROPRIETARY  0xFD  /* Tag proprietary information */
+#define T2T_TLV_TYPE_TERMINATOR   0xFE  /* Last TLV block in the data area */
+
+
+#define T2T_TLEN_LOCK_CTRL_TLV    3      /* Tag len for LOCK_CTRL TLV per spec */
+#define T2T_TLEN_MEM_CTRL_TLV     3      /* Tag len for MEM_CTRL TLV per spec */
+
+#define T2T_MAX_SECTOR            2      /* Maximum number of sectors supported */
+
+#define T2T_TLV_TYPE_LEN                1     /* Tlv type identifier len                */
+
+#define T2T_DEFAULT_TLV_LEN             3 /* Tlv len for LOCK_CTRL/MEM TLV per spec     */
+#define T2T_SHORT_NDEF_LEN_FIELD_LEN    1 /* Length Field size of short NDEF Message    */
+#define T2T_LONG_NDEF_LEN_FIELD_LEN     3 /* Length Field size of Long NDEF Message     */
+#define T2T_LONG_NDEF_LEN_FIELD_BYTE0   0xFF /* Byte 0 in Length field to indicate LNDEF*/
+#define T2T_LONG_NDEF_MIN_LEN           0x00FF /* Min. len of NDEF to qualify as LNDEF  */
+
+/* Lock */
+#define T2T_NUM_STATIC_LOCK_BYTES           2   /* Number of static lock bytes in tag   */
+#define T2T_BYTES_LOCKED_BY_STATIC_LOCK_BIT 4   /* Bytes locked by one static lock bit  */
+
+#define T2T_CC2_TMS_MULC          0x12
+/*
+**
+**  Type 3 Tag Definitions
+**
+*/
+
+#define T3T_SYSTEM_CODE_NDEF        0x12FC  /* System Code for NDEF tags */
+#define T3T_SYSTEM_CODE_FELICA_LITE 0x88B4  /* System Code for felica-lite tags */
+#define T3T_MAX_SYSTEM_CODES        16
+
+/* Block descriptor, used to describe a block to check/update */
+typedef struct
+{
+    UINT16 service_code;    /* Block service code. Set to T3T_SERVICE_CODE_NDEF (0x000B) for NDEF data */
+    UINT16 block_number;    /* Block number */
+} tT3T_BLOCK_DESC;
+
+/* Poll RC (request code) definitions */
+#define T3T_POLL_RC_NONE    0   /* No RD requested in SENSF_RES */
+#define T3T_POLL_RC_SC      1   /* System code requested in SENSF_RES */
+#define T3T_POLL_RC_COMM    2   /* Avanced protocol features requested in SENSF_RES */
+typedef UINT8 tT3T_POLL_RC;
+
+/* Definitions for constructing t3t command messages */
+
+/* NFC Forum / Felica commands */
+#define T3T_MSG_OPC_CHECK_CMD   0x06
+#define T3T_MSG_OPC_CHECK_RSP   0x07
+#define T3T_MSG_OPC_UPDATE_CMD  0x08
+#define T3T_MSG_OPC_UPDATE_RSP  0x09
+
+/* Felica commands (not specified in NFC-Forum Type 3 tag specifications) */
+#define T3T_MSG_OPC_POLL_CMD            0x00
+#define T3T_MSG_OPC_POLL_RSP            0x01
+#define T3T_MSG_OPC_REQ_SERVICE_CMD     0x02
+#define T3T_MSG_OPC_REQ_SERVICE_RSP     0x03
+#define T3T_MSG_OPC_REQ_RESPONSE_CMD    0x04
+#define T3T_MSG_OPC_REQ_RESPONSE_RSP    0x05
+#define T3T_MSG_OPC_REQ_SYSTEMCODE_CMD  0x0C
+#define T3T_MSG_OPC_REQ_SYSTEMCODE_RSP  0x0D
+
+#define T3T_MSG_NDEF_SC_RO          0x000B      /* Service code: read-only NDEF */
+#define T3T_MSG_NDEF_SC_RW          0x0009      /* Service code: read/write NDEF */
+#define T3T_MSG_NDEF_VERSION        0x10        /* NDEF Mapping Version 1.0 */
+#define T3T_MSG_NDEF_WRITEF_OFF     0x00
+#define T3T_MSG_NDEF_WRITEF_ON      0x0F
+#define T3T_MSG_NDEF_RWFLAG_RO      0x00
+#define T3T_MSG_NDEF_RWFLAG_RW      0x01
+#define T3T_MSG_NDEF_ATTR_INFO_SIZE 14          /* Size of NDEF attribute info block (minus checksum) */
+
+#define T3T_MSG_OFFSET_IDM                          1       /* offset of Manufacturer ID in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_NUM_SERVICES                 9       /* offset of Number of Services parameter in UPDATE/CHECK messages */
+#define T3T_MSG_OFFSET_SERVICE_CODE_LIST            10      /* offset of Service Code List parameter in UPDATE/CHECK messages */
+#define T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT     0x80    /* len flag for Block List Element */
+#define T3T_MSG_SERVICE_LIST_MASK                   0x0F    /* service code list mask */
+#define T3T_MSG_SERVICE_LIST_MAX                    16
+
+#define T3T_MSG_NUM_SERVICES_UPDATE_MAX             12      /* Max Number of Services per UPDATE command */
+#define T3T_MSG_NUM_SERVICES_CHECK_MAX              15      /* Max Number of Services per CHECK command */
+#define T3T_MSG_NUM_BLOCKS_UPDATE_MAX               13      /* Max Number of Blocks per UPDATE command */
+#define T3T_MSG_NUM_BLOCKS_CHECK_MAX                15      /* Max Number of Blocks per CHECK command */
+
+#define T3T_MSG_BLOCKSIZE                           16      /* Data block size for UPDATE and CHECK commands */
+
+/* Common header definitions for T3t commands */
+#define T3T_MSG_CMD_COMMON_HDR_LEN          11      /* Common header: SoD + cmdcode + NFCID2 + num_services */
+
+/* Common header definition for T3t responses */
+#define T3T_MSG_RSP_COMMON_HDR_LEN          11      /* Common header: rspcode + NFCID2 + StatusFlag1 + StatusFlag2  */
+#define T3T_MSG_RSP_CHECK_HDR_LEN           (T3T_MSG_RSP_COMMON_HDR_LEN + 1)    /* Common header + NumBlocks */
+#define T3T_MSG_RSP_OFFSET_RSPCODE          0       /* Offset for Response code */
+#define T3T_MSG_RSP_OFFSET_IDM              1       /* Offset for Manufacturer ID */
+#define T3T_MSG_RSP_OFFSET_STATUS1          9       /* Offset for Status Flag1 */
+#define T3T_MSG_RSP_OFFSET_NUMBLOCKS        11      /* Offset for NumberOfBlocks (in CHECK response) */
+#define T3T_MSG_RSP_OFFSET_CHECK_DATA       12      /* Offset for Block Data (in CHECK response) */
+#define T3T_MSG_RSP_OFFSET_POLL_PMM         9       /* Offset for PMm (in POLL response) */
+#define T3T_MSG_RSP_OFFSET_POLL_RD          17      /* Offset for RD (in POLL response) */
+#define T3T_MSG_RSP_OFFSET_NUMSYS           9       /* Offset for Number of Systems */
+
+#define T3T_MSG_RSP_STATUS_OK                       0x00
+#define T3T_MSG_RSP_STATUS_ERROR                    0x01
+
+#define T3T_MSG_RSP_STATUS2_ERROR_MEMORY            0x70
+#define T3T_MSG_RSP_STATUS2_ERROR_EXCESSIVE_WRITES  0x71
+#define T3T_MSG_RSP_STATUS2_ERROR_PROCESSING        0xFF
+
+#define T3T_NFC_F_MAX_PAYLOAD_LEN                   0xFE    /* Maximum payload lenght for NFC-F messages (including SoD) */
+
+/* Felica Lite defintions */
+#define T3T_MSG_FELICALITE_BLOCK_ID_MC              0x88    /* Block ID for MC (memory configuration)                       */
+#define T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP         0x03    /* Memory Configuration Block offset: SYS_OP (System Option)    */
+
+
+
+/*
+**
+**  Type 4 Tag Definitions
+**
+*/
+#define T4T_CMD_MIN_HDR_SIZE            4       /* CLA, INS, P1, P2 */
+#define T4T_CMD_MAX_HDR_SIZE            5       /* CLA, INS, P1, P2, Lc */
+
+#define T4T_VERSION_2_0                 0x20    /* version 2.0 */
+#define T4T_VERSION_1_0                 0x10    /* version 1.0 */
+#define T4T_MY_VERSION                  T4T_VERSION_2_0
+#define T4T_GET_MAJOR_VERSION(x)        ((x) >> 4)
+#define T4T_GET_MINOR_VERSION(x)        ((x) & 0x0F )
+
+#define T4T_CMD_CLASS                   0x00
+#define T4T_CMD_INS_SELECT              0xA4
+#define T4T_CMD_INS_READ_BINARY         0xB0
+#define T4T_CMD_INS_UPDATE_BINARY       0xD6
+#define T4T_CMD_P1_SELECT_BY_NAME       0x04
+#define T4T_CMD_P1_SELECT_BY_FILE_ID    0x00
+#define T4T_CMD_P2_FIRST_OR_ONLY_00H    0x00
+#define T4T_CMD_P2_FIRST_OR_ONLY_0CH    0x0C
+
+#define T4T_MAX_LENGTH_LE               0xFF    /* Max number of bytes to be read from file in ReadBinary Command */
+#define T4T_MAX_LENGTH_LC               0xFF    /* Max number of bytes written to NDEF file in UpdateBinary Command */
+
+#define T4T_RSP_STATUS_WORDS_SIZE       0x02
+
+#define T4T_RSP_CMD_CMPLTED             0x9000
+#define T4T_RSP_NOT_FOUND               0x6A82
+#define T4T_RSP_WRONG_PARAMS            0x6B00
+#define T4T_RSP_CLASS_NOT_SUPPORTED     0x6E00
+#define T4T_RSP_WRONG_LENGTH            0x6700
+#define T4T_RSP_INSTR_NOT_SUPPORTED     0x6D00
+#define T4T_RSP_CMD_NOT_ALLOWED         0x6986
+
+#define T4T_V10_NDEF_TAG_AID_LEN        0x07    /* V1.0 Type 4 Tag Applicaiton ID length */
+#define T4T_V20_NDEF_TAG_AID_LEN        0x07    /* V2.0 Type 4 Tag Applicaiton ID length */
+
+#define T4T_MIN_MLE                     0x000F  /* Min of Max R-APDU data size */
+
+#define T4T_FILE_ID_SIZE                0x02
+#define T4T_CC_FILE_ID                  0xE103
+#define T4T_CC_FILE_MIN_LEN             0x000F
+
+#define T4T_VERSION_OFFSET_IN_CC        0x02
+#define T4T_FC_TLV_OFFSET_IN_CC         0x07
+
+#define T4T_NDEF_FILE_CONTROL_TYPE      0x04    /* NDEF File Control Type */
+#define T4T_PROP_FILE_CONTROL_TYPE      0x05    /* Proprietary File Control Type */
+
+#define T4T_FILE_CONTROL_TLV_SIZE       0x08    /* size of T(1),L(1),V(6) for file control */
+#define T4T_FILE_CONTROL_LENGTH         0x06    /* size of V(6) for file control */
+
+#define T4T_FC_READ_ACCESS              0x00    /* read access granted without any security */
+#define T4T_FC_WRITE_ACCESS             0x00    /* write access granted without any security */
+#define T4T_FC_NO_WRITE_ACCESS          0xFF    /* no write access granted at all (read-only) */
+
+#define T4T_FILE_LENGTH_SIZE            0x02
+
+/*
+**
+**  ISO 15693 Tag Definitions
+**
+*/
+
+/* Request flags 1 to 4 definition */
+#define I93_FLAG_SUB_CARRIER_MASK           0x01    /* Sub_carrier_flag */
+#define I93_FLAG_SUB_CARRIER_SINGLE         0x00    /* A single sub-carrier frequency shall be used by VICC */
+#define I93_FLAG_SUB_CARRIER_DOUBLE         0x01    /* Two sub-carriers shall be used by VICC               */
+
+#define I93_FLAG_DATA_RATE_MASK             0x02    /* Data_rate_flag */
+#define I93_FLAG_DATA_RATE_LOW              0x00    /* Low data rate shall be used  */
+#define I93_FLAG_DATA_RATE_HIGH             0x02    /* High data rate shall be used */
+
+#define I93_FLAG_INVENTORY_MASK             0x04    /* Inventory_flag */
+#define I93_FLAG_INVENTORY_UNSET            0x00    /* Flags 5 to 8 meaning is according to table 4 */
+#define I93_FLAG_INVENTORY_SET              0x04    /* Flags 5 to 8 meaning is according to table 5 */
+
+#define I93_FLAG_PROT_EXT_MASK              0x08    /* Protocol_Extension_flag */
+#define I93_FLAG_PROT_EXT_NO                0x00    /* No protocol format extension                         */
+#define I93_FLAG_PROT_EXT_YES               0x08    /* Protocol format is extended. Reserved for future use */
+
+/* Request flags 5 to 6 definition when inventory flag is not set */
+#define I93_FLAG_SELECT_MASK                0x10    /* Select_flag */
+#define I93_FLAG_SELECT_UNSET               0x00    /* Request shall be executed by any VICC according to the setting of Address_flag */
+#define I93_FLAG_SELECT_SET                 0x10    /* Request shall be executed only by VICC in selected state */
+                                                    /* The Address_flag shall be set to 0 and the UID field shall bot be included in the request */
+
+#define I93_FLAG_ADDRESS_MASK               0x20    /* Address_flag */
+#define I93_FLAG_ADDRESS_UNSET              0x00    /* Request is not addressed. UID field is not included. It shall be executed by any VICC */
+#define I93_FLAG_ADDRESS_SET                0x20    /* Request is addressed. UID field is included. It shall be executed only by VICC */
+                                                    /* whose UID matches the UID specified in the request */
+
+/* Request flags 5 to 6 definition when inventory flag is set */
+#define I93_FLAG_AFI_MASK                   0x10    /* AFI_flag */
+#define I93_FLAG_AFI_NOT_PRESENT            0x00    /* AFI field is not present */
+#define I93_FLAG_AFI_PRESENT                0x10    /* AFI field is present     */
+
+#define I93_FLAG_SLOT_MASK                  0x20    /* Nb_slots_flag */
+#define I93_FLAG_SLOT_16                    0x00    /* 16 slots */
+#define I93_FLAG_SLOT_ONE                   0x20    /* 1 slot   */
+
+/* Request flags 6 to 8 definition when inventory flag is set or not set */
+
+#define I93_FLAG_OPTION_MASK                0x40    /* Option_flag */
+#define I93_FLAG_OPTION_UNSET               0x00    /* Meaning is defined by the command description. */
+                                                    /* It shall be set to 0 if not otherwise defined by command */
+#define I93_FLAG_OPTION_SET                 0x40    /* Meaning is defined by the command description. */
+
+/* Response flags */
+#define I93_FLAG_ERROR_MASK                 0x01    /* Error_flag */
+#define I93_FLAG_ERORR_NOT_DETECTED         0x00    /* No error                                           */
+#define I93_FLAG_ERROR_DETECTED             0x01    /* Error detected, Error code is in the "Error" field */
+
+/* Response error code */
+#define I93_ERROR_CODE_NOT_SUPPORTED        0x01    /* The command is not supported, i.e. the request code is not recognized */
+#define I93_ERROR_CODE_NOT_RECOGNIZED       0x02    /* The command is not recognized, for example: a format error occured    */
+#define I93_ERROR_CODE_OPTION_NOT_SUPPORTED 0x03    /* The command option is not supported                                   */
+#define I93_ERROR_CODE_NO_INFO              0x0F    /* Error with no information given or a specific error code is not supported */
+#define I93_ERROR_CODE_BLOCK_NOT_AVAILABLE  0x10    /* The specific block is not available (doesn't exist)                   */
+#define I93_ERROR_CODE_BLOCK_ALREADY_LOCKED 0x11    /* The specific block is already locked and thus cannot be locked again  */
+#define I93_ERROR_CODE_BLOCK_LOCKED         0x12    /* The specific block is locked and its content cannot be changed        */
+#define I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE  0x13    /* The specific block is was not successfully programmed                 */
+#define I93_ERROR_CODE_BLOCK_FAIL_TO_LOCK   0x14    /* The specific block is was not successfully locked                     */
+
+#define I93_UID_BYTE_LEN                    8       /* UID length in bytes                  */
+#define I93_DFS_UNSUPPORTED                 0x00    /* Data Storage Format is not supported */
+#define I93_BLOCK_UNLOCKED                  0x00    /* Block is not locked                  */
+#define I93_BLOCK_LOCKED                    0x01    /* Block is locked                      */
+
+/* ISO 15693 Mandatory commands */
+#define I93_CMD_INVENTORY                   0x01    /* Inventory  */
+#define I93_CMD_STAY_QUIET                  0x02    /* Stay Quiet */
+
+/* ISO 15693 Optional commands */
+#define I93_CMD_READ_SINGLE_BLOCK           0x20    /* Read single block     */
+#define I93_CMD_WRITE_SINGLE_BLOCK          0x21    /* Write single block    */
+#define I93_CMD_LOCK_BLOCK                  0x22    /* Lock block            */
+#define I93_CMD_READ_MULTI_BLOCK            0x23    /* Read multiple blocks  */
+#define I93_CMD_WRITE_MULTI_BLOCK           0x24    /* Write multiple blocks */
+#define I93_CMD_SELECT                      0x25    /* Select                */
+#define I93_CMD_RESET_TO_READY              0x26    /* Reset to ready        */
+#define I93_CMD_WRITE_AFI                   0x27    /* Wreite AFI            */
+#define I93_CMD_LOCK_AFI                    0x28    /* Lock AFI              */
+#define I93_CMD_WRITE_DSFID                 0x29    /* Write DSFID           */
+#define I93_CMD_LOCK_DSFID                  0x2A    /* Lock DSFID            */
+#define I93_CMD_GET_SYS_INFO                0x2B    /* Get system information             */
+#define I93_CMD_GET_MULTI_BLK_SEC           0x2C    /* Get multiple block security status */
+
+/* Information flags definition */
+#define I93_INFO_FLAG_DSFID                 0x01    /* DSFID is supported and DSFID field is present */
+#define I93_INFO_FLAG_AFI                   0x02    /* AFI is supported and AFI field is present     */
+#define I93_INFO_FLAG_MEM_SIZE              0x04    /* VICC memory size field is present             */
+#define I93_INFO_FLAG_IC_REF                0x08    /* IC reference field is present                 */
+
+#define I93_MAX_BLOCK_LENGH                 32      /* Max block size in bytes */
+#define I93_MAX_NUM_BLOCK                   256     /* Max number of blocks    */
+
+/* ICODE Capability Container(CC) definition */
+#define I93_ICODE_CC_MAGIC_NUMER            0xE1    /* magic number in CC[0]  */
+#define I93_ICODE_CC_MAJOR_VER_MASK         0xC0    /* major version in CC[1] */
+#define I93_ICODE_CC_MINOR_VER_MASK         0x30    /* minor version in CC[1] */
+#define I93_ICODE_CC_READ_ACCESS_MASK       0x0C    /* read access condition in CC[1]        */
+#define I93_ICODE_CC_READ_ACCESS_GRANTED    0x00    /* read access granted without security  */
+#define I93_ICODE_CC_WRITE_ACCESS_MASK      0x03    /* write access condition in CC[1]       */
+#define I93_ICODE_CC_WRITE_ACCESS_GRANTED   0x00    /* write access granted without security */
+#define I93_ICODE_CC_READ_ONLY              0x03    /* write access not granted at all       */
+#define I93_ICODE_CC_MBREAD_MASK            0x01    /* read multi block supported in CC[3]   */
+#define I93_ICODE_CC_IPREAD_MASK            0x02    /* inventory page read supported in CC[3] */
+
+/* ICODE TLV type */
+#define I93_ICODE_TLV_TYPE_NULL             0x00    /* NULL TLV         */
+#define I93_ICODE_TLV_TYPE_NDEF             0x03    /* NDEF message TLV */
+#define I93_ICODE_TLV_TYPE_PROP             0xFD    /* Proprietary TLV  */
+#define I93_ICODE_TLV_TYPE_TERM             0xFE    /* Terminator TLV   */
+
+/* UID Coding (UID Bit 64-57), First byte of ISO 15693 UID */
+#define I93_UID_FIRST_BYTE                      0xE0
+
+/* UID Coding (UID Bit 56-49), IC manufacturer code */
+#define I93_UID_IC_MFG_CODE_NXP                 0x04
+#define I93_UID_IC_MFG_CODE_TI                  0x07
+
+/* NXP, UID Coding of ICODE type (UID Bit 48-41) */
+#define I93_UID_ICODE_SLI                       0x01    /* ICODE SLI, SLIX     */
+#define I93_UID_ICODE_SLI_S                     0x02    /* ICODE SLI-S, SLIX-S */
+#define I93_UID_ICODE_SLI_L                     0x03    /* ICODE SLI-L, SLIX-L */
+
+#define I93_IC_REF_ICODE_SLI_L                  0x03    /* IC Reference for ICODE SLI-L */
+#define I93_ICODE_IC_REF_MBREAD_MASK            0x02    /* read multi block supported check bit */
+
+/* TI, UID Coding of product version (UID Bit 48-42) */
+#define I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK     0xFE    /* upper 7 bits                     */
+#define I93_UID_TAG_IT_HF_I_PLUS_INLAY          0x00    /* Tag-it HF-I Plus Inlay           */
+#define I93_UID_TAG_IT_HF_I_PLUS_CHIP           0x80    /* Tag-it HF-I Plus Chip            */
+#define I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY      0xC0    /* Tag-it HF-I Standard Chip/Inlyas */
+#define I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY      0xC4    /* Tag-it HF-I Pro Chip/Inlyas      */
+
+#define I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK   11
+#define I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK   12
+
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE         4
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK     8
+#define I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION    40   /* LSB in Block 0x0A */
+
+#endif /* TAGS_DEFS_H */
diff --git a/src/nfc/int/ce_int.h b/src/nfc/int/ce_int.h
new file mode 100644
index 0000000..2d1d9fe
--- /dev/null
+++ b/src/nfc/int/ce_int.h
@@ -0,0 +1,174 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Card Emulation
+ *  mode related internal function / definitions.
+ *
+ ******************************************************************************/
+
+#ifndef CE_INT_H_
+#define CE_INT_H_
+
+#include "ce_api.h"
+
+#if (CE_TEST_INCLUDED == FALSE)
+#define CE_MIN_SUP_PROTO    NCI_PROTOCOL_FELICA
+#define CE_MAX_SUP_PROTO    NCI_PROTOCOL_ISO4
+#else
+#define CE_MIN_SUP_PROTO    NCI_PROTOCOL_TYPE1
+#define CE_MAX_SUP_PROTO    NCI_PROTOCOL_MIFARE
+#endif
+
+#define CE_MAX_BYTE_PER_PAGE    7   /* 2^8=256. CB use UINT8 for BytesPerPage, so max is 7 */
+
+/* CE Type 3 Tag structures */
+
+/* Type 3 Tag NDEF card-emulation */
+typedef struct {
+    BOOLEAN         initialized;
+    UINT8           version;        /* Ver: peer version */
+    UINT8           nbr;            /* NBr: number of blocks that can be read using one Check command */
+    UINT8           nbw;            /* Nbw: number of blocks that can be written using one Update command */
+    UINT16          nmaxb;          /* Nmaxb: maximum number of blocks available for NDEF data */
+    UINT8           writef;         /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
+    UINT8           rwflag;         /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+    UINT32          ln;
+    UINT8           *p_buf;         /* Current contents for READs */
+
+    /* Scratch NDEF buffer (for update NDEF commands) */
+    UINT8           scratch_writef;
+    UINT32          scratch_ln;
+    UINT8           *p_scratch_buf; /* Scratch buffer for WRITE/readback */
+} tCE_T3T_NDEF_INFO;
+
+/* Type 3 Tag current command processing */
+typedef struct {
+    UINT16          service_code_list[T3T_MSG_SERVICE_LIST_MAX];
+    UINT8           *p_block_list_start;
+    UINT8           *p_block_data_start;
+    UINT8           num_services;
+    UINT8           num_blocks;
+} tCE_T3T_CUR_CMD;
+
+/* Type 3 Tag control blcok */
+typedef struct
+{
+    UINT8               state;
+    UINT16              system_code;
+    UINT8               local_nfcid2[NCI_RF_F_UID_LEN];
+    UINT8               local_pmm[NCI_T3T_PMM_LEN];
+    tCE_T3T_NDEF_INFO   ndef_info;
+    tCE_T3T_CUR_CMD     cur_cmd;
+} tCE_T3T_MEM;
+
+/* CE Type 4 Tag control blocks */
+typedef struct
+{
+    UINT8               aid_len;
+    UINT8               aid[NFC_MAX_AID_LEN];
+    tCE_CBACK          *p_cback;
+} tCE_T4T_REG_AID;      /* registered AID table */
+
+typedef struct
+{
+    TIMER_LIST_ENT      timer;              /* timeout for update file              */
+    UINT8               cc_file[T4T_FC_TLV_OFFSET_IN_CC + T4T_FILE_CONTROL_TLV_SIZE];
+    UINT8              *p_ndef_msg;         /* storage of NDEF message              */
+    UINT16              nlen;               /* current size of NDEF message         */
+    UINT16              max_file_size;      /* size of storage + 2 bytes for NLEN   */
+    UINT8              *p_scratch_buf;      /* temp storage of NDEF message for update */
+
+#define CE_T4T_STATUS_T4T_APP_SELECTED      0x01    /* T4T CE App is selected       */
+#define CE_T4T_STATUS_REG_AID_SELECTED      0x02    /* Registered AID is selected   */
+#define CE_T4T_STATUS_CC_FILE_SELECTED      0x04    /* CC file is selected          */
+#define CE_T4T_STATUS_NDEF_SELECTED         0x08    /* NDEF file is selected        */
+#define CE_T4T_STATUS_NDEF_FILE_READ_ONLY   0x10    /* NDEF is read-only            */
+#define CE_T4T_STATUS_NDEF_FILE_UPDATING    0x20    /* NDEF is updating             */
+#define CE_T4T_STATUS_WILDCARD_AID_SELECTED 0x40    /* Wildcard AID selected        */
+
+    UINT8               status;
+
+    tCE_CBACK          *p_wildcard_aid_cback;               /* registered wildcard AID callback */
+    tCE_T4T_REG_AID     reg_aid[CE_T4T_MAX_REG_AID];        /* registered AID table             */
+    UINT8               selected_aid_idx;
+} tCE_T4T_MEM;
+
+#define CE_T4T_WILDCARD_AID_HANDLE  (CE_T4T_MAX_REG_AID)    /* reserved handle for wildcard aid */
+
+/* CE memory control blocks */
+typedef struct
+{
+    tCE_T3T_MEM         t3t;
+    tCE_T4T_MEM         t4t;
+} tCE_MEM;
+
+/* CE control blocks */
+typedef struct
+{
+    tCE_MEM             mem;
+    tCE_CBACK           *p_cback;
+    UINT8               *p_ndef;     /* the memory starting from NDEF */
+    UINT16              ndef_max;    /* max size of p_ndef */
+    UINT16              ndef_cur;    /* current size of p_ndef */
+    tNFC_RF_TECH        tech;
+    UINT8               trace_level;
+
+} tCE_CB;
+
+/*
+** CE Type 4 Tag Definition
+*/
+
+/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
+#define CE_T4T_MAX_LE           (NFC_CE_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - T4T_RSP_STATUS_WORDS_SIZE)
+
+/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2, Lc */
+#define CE_T4T_MAX_LC           (NFC_CE_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_DATA_HDR_SIZE - T4T_CMD_MAX_HDR_SIZE)
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global NFC data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+NFC_API extern tCE_CB  ce_cb;
+#else
+NFC_API extern tCE_CB *ce_cb_ptr;
+#define ce_cb (*ce_cb_ptr)
+#endif
+
+extern void ce_init (void);
+
+/* ce_t3t internal functions */
+void ce_t3t_init (void);
+tNFC_STATUS ce_select_t3t (UINT16 system_code, UINT8 nfcid2[NCI_RF_F_UID_LEN]);
+
+/* ce_t4t internal functions */
+extern tNFC_STATUS ce_select_t4t (void);
+extern void ce_t4t_process_timeout (TIMER_LIST_ENT *p_tle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CE_INT_H_ */
diff --git a/src/nfc/int/llcp_int.h b/src/nfc/int/llcp_int.h
new file mode 100644
index 0000000..62dd384
--- /dev/null
+++ b/src/nfc/int/llcp_int.h
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains LLCP internal definitions
+ *
+ ******************************************************************************/
+#ifndef LLCP_INT_H
+#define LLCP_INT_H
+
+#include "llcp_api.h"
+#include "nfc_api.h"
+
+/*
+** LLCP link states
+*/
+enum
+{
+    LLCP_LINK_STATE_DEACTIVATED,                /* llcp link is deactivated     */
+    LLCP_LINK_STATE_ACTIVATED,                  /* llcp link has been activated */
+    LLCP_LINK_STATE_DEACTIVATING                /* llcp link is deactivating    */
+};
+typedef UINT8 tLLCP_LINK_STATE;
+
+/*
+** LLCP Symmetric state
+*/
+
+#define LLCP_LINK_SYMM_LOCAL_XMIT_NEXT   0
+#define LLCP_LINK_SYMM_REMOTE_XMIT_NEXT  1
+
+/*
+** LLCP link control block
+*/
+typedef struct
+{
+    tLLCP_LINK_STATE    link_state;             /* llcp link state                              */
+    tLLCP_LINK_CBACK   *p_link_cback;           /* callback function to report llcp link status */
+    UINT16              wks;                    /* well-known service bit-map                   */
+
+    BOOLEAN             is_initiator;           /* TRUE if initiator role                       */
+    BOOLEAN             is_sending_data;        /* TRUE if llcp_link_check_send_data() is excuting    */
+    UINT8               agreed_major_version;   /* llcp major version used in activated state   */
+    UINT8               agreed_minor_version;   /* llcp minor version used in activated state   */
+
+    UINT8               peer_version;           /* llcp version of peer device                  */
+    UINT16              peer_miu;               /* link MIU of peer device                      */
+    UINT16              peer_wks;               /* WKS of peer device                           */
+    UINT16              peer_lto;               /* link timeout of peer device in ms            */
+    UINT8               peer_opt;               /* Option field of peer device                  */
+    UINT16              effective_miu;          /* MIU to send PDU in activated state           */
+
+    TIMER_LIST_ENT      timer;                  /* link timer for LTO and SYMM response         */
+    UINT8               symm_state;             /* state of symmectric procedure                */
+    BOOLEAN             ll_served;              /* TRUE if last transmisstion was for UI        */
+    UINT8               ll_idx;                 /* for scheduler of logical link connection     */
+    UINT8               dl_idx;                 /* for scheduler of data link connection        */
+
+    TIMER_LIST_ENT      inact_timer;            /* inactivity timer                             */
+    UINT16              inact_timeout;          /* inactivity timeout in ms                     */
+
+    UINT8               link_deact_reason;      /* reason of LLCP link deactivated              */
+
+    BUFFER_Q            sig_xmit_q;             /* tx signaling PDU queue                       */
+
+    /* runtime configuration parameters */
+    UINT16              local_link_miu;         /* Maximum Information Unit                     */
+    UINT8               local_opt;              /* Option parameter                             */
+    UINT8               local_wt;               /* Response Waiting Time Index                  */
+    UINT16              local_lto;              /* Local Link Timeout                           */
+    UINT16              inact_timeout_init;     /* Inactivity Timeout as initiator role         */
+    UINT16              inact_timeout_target;   /* Inactivity Timeout as target role            */
+    UINT16              symm_delay;             /* Delay SYMM response                          */
+    UINT16              data_link_timeout;      /* data link conneciton timeout                 */
+    UINT16              delay_first_pdu_timeout;/* delay timeout to send first PDU as initiator */
+
+} tLLCP_LCB;
+
+/*
+** LLCP Application's registration control block on service access point (SAP)
+*/
+
+typedef struct
+{
+    UINT8               link_type;              /* logical link and/or data link                */
+    UINT8               *p_service_name;        /* GKI buffer containing service name           */
+    tLLCP_APP_CBACK     *p_app_cback;           /* application's callback pointer               */
+
+    BUFFER_Q            ui_xmit_q;              /* UI PDU queue for transmitting                */
+    BUFFER_Q            ui_rx_q;                /* UI PDU queue for receiving                   */
+    BOOLEAN             is_ui_tx_congested;     /* TRUE if transmitting UI PDU is congested     */
+
+} tLLCP_APP_CB;
+
+/*
+** LLCP data link connection states
+*/
+enum
+{
+    LLCP_DLC_STATE_IDLE,            /* initial state                                    */
+    LLCP_DLC_STATE_W4_REMOTE_RESP,  /* waiting for connection confirm from peer         */
+    LLCP_DLC_STATE_W4_LOCAL_RESP,   /* waiting for connection confirm from upper layer  */
+    LLCP_DLC_STATE_CONNECTED,       /* data link connection has been established        */
+    LLCP_DLC_STATE_W4_REMOTE_DM,    /* waiting for disconnection confirm from peer      */
+    LLCP_DLC_STATE_MAX
+};
+typedef UINT8 tLLCP_DLC_STATE;
+
+/*
+** LLCP data link connection events
+*/
+enum
+{
+    LLCP_DLC_EVENT_API_CONNECT_REQ,      /* connection request from upper layer  */
+    LLCP_DLC_EVENT_API_CONNECT_CFM,      /* connection confirm from upper layer  */
+    LLCP_DLC_EVENT_API_CONNECT_REJECT,   /* connection reject from upper layer   */
+    LLCP_DLC_EVENT_PEER_CONNECT_IND,     /* connection request from peer         */
+    LLCP_DLC_EVENT_PEER_CONNECT_CFM,     /* connection confirm from peer         */
+
+    LLCP_DLC_EVENT_API_DATA_REQ,         /* data packet from upper layer         */
+    LLCP_DLC_EVENT_PEER_DATA_IND,        /* data packet from peer                */
+
+    LLCP_DLC_EVENT_API_DISCONNECT_REQ,   /* disconnect request from upper layer  */
+    LLCP_DLC_EVENT_PEER_DISCONNECT_IND,  /* disconnect request from peer         */
+    LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, /* disconnect response from peer        */
+
+    LLCP_DLC_EVENT_FRAME_ERROR,          /* received erroneous frame from peer   */
+    LLCP_DLC_EVENT_LINK_ERROR,           /* llcp link has been deactivated       */
+
+    LLCP_DLC_EVENT_TIMEOUT               /* timeout event                        */
+};
+typedef UINT8 tLLCP_DLC_EVENT;
+
+/*
+** LLCP data link connection control block
+*/
+
+#define LLCP_DATA_LINK_FLAG_PENDING_DISC     0x01 /* send DISC when tx queue is empty       */
+#define LLCP_DATA_LINK_FLAG_PENDING_RR_RNR   0x02 /* send RR/RNR with valid sequence        */
+#define LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE   0x04 /* notify upper later when tx complete    */
+
+
+typedef struct
+{
+    tLLCP_DLC_STATE         state;              /* data link connection state               */
+    UINT8                   flags;              /* specific action flags                    */
+    tLLCP_APP_CB            *p_app_cb;          /* pointer of application registration      */
+    TIMER_LIST_ENT          timer;              /* timer for connection complete            */
+
+    UINT8                   local_sap;          /* SAP of local end point                   */
+    UINT16                  local_miu;          /* MIU of local SAP                         */
+    UINT8                   local_rw;           /* RW of local SAP                          */
+    BOOLEAN                 local_busy;         /* TRUE if local SAP is busy                */
+
+    UINT8                   remote_sap;         /* SAP of remote end point                  */
+    UINT16                  remote_miu;         /* MIU of remote SAP                        */
+    UINT8                   remote_rw;          /* RW of remote SAP                         */
+    BOOLEAN                 remote_busy;        /* TRUE if remote SAP is busy               */
+
+    UINT8                   next_tx_seq;        /* V(S), send state variable                */
+    UINT8                   rcvd_ack_seq;       /* V(SA), send ack state variable           */
+    UINT8                   next_rx_seq;        /* V(R), receive state variable             */
+    UINT8                   sent_ack_seq;       /* V(RA), receive ack state variable        */
+
+    BUFFER_Q                i_xmit_q;           /* tx queue of I PDU                        */
+    BOOLEAN                 is_tx_congested;    /* TRUE if tx I PDU is congested            */
+
+    BUFFER_Q                i_rx_q;             /* rx queue of I PDU                        */
+    BOOLEAN                 is_rx_congested;    /* TRUE if rx I PDU is congested            */
+    UINT8                   num_rx_i_pdu;       /* number of I PDU in rx queue              */
+    UINT8                   rx_congest_threshold; /* dynamic congest threshold for rx I PDU */
+
+} tLLCP_DLCB;
+
+/*
+** LLCP service discovery control block
+*/
+
+typedef struct
+{
+    UINT8           tid;        /* transaction ID                           */
+    tLLCP_SDP_CBACK *p_cback;   /* callback function for service discovery  */
+} tLLCP_SDP_TRANSAC;
+
+typedef struct
+{
+    UINT8               next_tid;                       /* next TID to use         */
+    tLLCP_SDP_TRANSAC   transac[LLCP_MAX_SDP_TRANSAC];  /* active SDP transactions */
+    BT_HDR              *p_snl;                         /* buffer for SNL PDU      */
+} tLLCP_SDP_CB;
+
+
+/*
+** LLCP control block
+*/
+
+typedef struct
+{
+    UINT8           trace_level;                    /* LLCP trace level                             */
+
+    tLLCP_SDP_CB    sdp_cb;                         /* SDP control block                            */
+    tLLCP_LCB       lcb;                            /* LLCP link control block                      */
+    tLLCP_APP_CB    wks_cb[LLCP_MAX_WKS];           /* Application's registration for well-known services */
+    tLLCP_APP_CB    server_cb[LLCP_MAX_SERVER];     /* Application's registration for SDP services  */
+    tLLCP_APP_CB    client_cb[LLCP_MAX_CLIENT];     /* Application's registration for client        */
+    tLLCP_DLCB      dlcb[LLCP_MAX_DATA_LINK];       /* Data link connection control block           */
+
+    UINT8           max_num_ll_tx_buff;             /* max number of tx UI PDU in queue             */
+    UINT8           max_num_tx_buff;                /* max number of tx UI/I PDU in queue           */
+
+    UINT8           num_logical_data_link;          /* number of logical data link                  */
+    UINT8           num_data_link_connection;       /* number of established data link connection   */
+
+    /* these two thresholds (number of tx UI PDU) are dynamically adjusted based on number of logical links */
+    UINT8           ll_tx_congest_start;            /* congest start threshold for each logical link*/
+    UINT8           ll_tx_congest_end;              /* congest end threshold for each logical link  */
+
+    UINT8           total_tx_ui_pdu;                /* total number of tx UI PDU in all of ui_xmit_q*/
+    UINT8           total_tx_i_pdu;                 /* total number of tx I PDU in all of i_xmit_q  */
+    BOOLEAN         overall_tx_congested;           /* TRUE if tx link is congested                 */
+
+    /* start point of uncongested status notification is in round robin */
+    UINT8           ll_tx_uncongest_ntf_start_sap;  /* next start of logical data link              */
+    UINT8           dl_tx_uncongest_ntf_start_idx;  /* next start of data link connection           */
+
+    /*
+    ** when overall rx link congestion starts, RNR is sent to remote end point of data link connection
+    ** while rx link is congested, UI PDU is discarded.
+    */
+    UINT8           num_rx_buff;                    /* reserved number of rx UI/I PDU in queue      */
+    UINT8           overall_rx_congest_start;       /* threshold of overall rx congestion start     */
+    UINT8           overall_rx_congest_end;         /* threshold of overall rx congestion end       */
+    UINT8           max_num_ll_rx_buff;             /* max number of rx UI PDU in queue             */
+
+    /*
+    ** threshold (number of rx UI PDU) is dynamically adjusted based on number of logical links
+    ** when number of rx UI PDU is more than ll_rx_congest_start, the oldest UI PDU is discarded
+    */
+    UINT8           ll_rx_congest_start;            /* rx congest start threshold for each logical link */
+
+    UINT8           total_rx_ui_pdu;                /* total number of rx UI PDU in all of ui_rx_q  */
+    UINT8           total_rx_i_pdu;                 /* total number of rx I PDU in all of i_rx_q    */
+    BOOLEAN         overall_rx_congested;           /* TRUE if overall rx link is congested         */
+
+    tLLCP_DTA_CBACK *p_dta_cback;                   /* callback to notify DTA when respoding SNL    */
+    BOOLEAN         dta_snl_resp;                   /* TRUE if need to notify DTA when respoding SNL*/
+} tLLCP_CB;
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+
+typedef struct {
+    UINT8  version;
+    UINT16 wks;
+} tLLCP_TEST_PARAMS;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+** LLCP global data
+*/
+
+#if (!defined LLCP_DYNAMIC_MEMORY) || (LLCP_DYNAMIC_MEMORY == FALSE)
+LLCP_API extern tLLCP_CB  llcp_cb;
+#else
+LLCP_API extern tLLCP_CB *llcp_cb_ptr;
+#define llcp_cb (*llcp_cb_ptr)
+#endif
+
+/*
+** Functions provided by llcp_main.c
+*/
+void llcp_init (void);
+void llcp_cleanup (void);
+void llcp_process_timeout (TIMER_LIST_ENT *p_tle);
+
+/*
+** Functions provided by llcp_link.c
+*/
+tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config);
+void llcp_link_process_link_timeout (void);
+void llcp_link_deactivate (UINT8 reason);
+
+void llcp_link_check_send_data (void);
+void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+
+/*
+**  Functions provided by llcp_util.c
+*/
+void         llcp_util_adjust_ll_congestion (void);
+void         llcp_util_adjust_dl_rx_congestion (void);
+void         llcp_util_check_rx_congested_status (void);
+BOOLEAN      llcp_util_parse_link_params (UINT16 length, UINT8 *p_bytes);
+tLLCP_STATUS llcp_util_send_ui (UINT8 ssap, UINT8 dsap, tLLCP_APP_CB *p_app_cb, BT_HDR *p_msg);
+void         llcp_util_send_disc (UINT8 dsap, UINT8 ssap);
+tLLCP_DLCB  *llcp_util_allocate_data_link (UINT8 reg_sap, UINT8 remote_sap);
+void         llcp_util_deallocate_data_link (tLLCP_DLCB *p_dlcb);
+tLLCP_STATUS llcp_util_send_connect (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params);
+tLLCP_STATUS llcp_util_parse_connect (UINT8 *p_bytes, UINT16 length, tLLCP_CONNECTION_PARAMS *p_params);
+tLLCP_STATUS llcp_util_send_cc (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params);
+tLLCP_STATUS llcp_util_parse_cc (UINT8 *p_bytes, UINT16 length, UINT16 *p_miu, UINT8 *p_rw);
+void         llcp_util_send_dm (UINT8 dsap, UINT8 ssap, UINT8 reason);
+void         llcp_util_build_info_pdu (tLLCP_DLCB *p_dlcb, BT_HDR *p_msg);
+tLLCP_STATUS llcp_util_send_frmr (tLLCP_DLCB *p_dlcb, UINT8 flags, UINT8 ptype, UINT8 sequence);
+void         llcp_util_send_rr_rnr (tLLCP_DLCB *p_dlcb);
+tLLCP_APP_CB *llcp_util_get_app_cb (UINT8 sap);
+/*
+** Functions provided by llcp_dlc.c
+*/
+tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+tLLCP_DLCB  *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap);
+void         llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb);
+void         llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg);
+void         llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data);
+void         llcp_dlc_check_to_send_rr_rnr (void);
+BOOLEAN      llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb);
+BT_HDR      *llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb);
+UINT16       llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb);
+
+/*
+** Functions provided by llcp_sdp.c
+*/
+void         llcp_sdp_proc_data (tLLCP_SAP_CBACK_DATA *p_data);
+tLLCP_STATUS llcp_sdp_send_sdreq (UINT8 tid, char *p_name);
+UINT8        llcp_sdp_get_sap_by_name (char *p_name, UINT8 length);
+tLLCP_STATUS llcp_sdp_proc_snl (UINT16 sdu_length, UINT8 *p);
+void         llcp_sdp_check_send_snl (void);
+void         llcp_sdp_proc_deactivation (void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/nfc/int/nfc_int.h b/src/nfc/int/nfc_int.h
new file mode 100644
index 0000000..e9180e6
--- /dev/null
+++ b/src/nfc/int/nfc_int.h
@@ -0,0 +1,279 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  this file contains the main NFC Upper Layer internal definitions and
+ *  functions.
+ *
+ ******************************************************************************/
+
+#ifndef NFC_INT_H_
+#define NFC_INT_H_
+
+#include "nfc_target.h"
+#include "gki.h"
+#include "nci_defs.h"
+#include "nfc_api.h"
+#include "btu_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************************************************************
+** Internal NFC constants and definitions
+****************************************************************************/
+
+/****************************************************************************
+** NFC_TASK definitions
+****************************************************************************/
+
+/* NFC_TASK event masks */
+#define NFC_TASK_EVT_TRANSPORT_READY        EVENT_MASK (APPL_EVT_0)
+
+/* NFC Timer events */
+#define NFC_TTYPE_NCI_WAIT_RSP              0
+#define NFC_TTYPE_WAIT_2_DEACTIVATE         1
+
+#define NFC_TTYPE_LLCP_LINK_MANAGER         100
+#define NFC_TTYPE_LLCP_LINK_INACT           101
+#define NFC_TTYPE_LLCP_DATA_LINK            102
+#define NFC_TTYPE_LLCP_DELAY_FIRST_PDU      103
+#define NFC_TTYPE_RW_T1T_RESPONSE           104
+#define NFC_TTYPE_RW_T2T_RESPONSE           105
+#define NFC_TTYPE_RW_T3T_RESPONSE           106
+#define NFC_TTYPE_RW_T4T_RESPONSE           107
+#define NFC_TTYPE_RW_I93_RESPONSE           108
+#define NFC_TTYPE_CE_T4T_UPDATE             109
+#define NFC_TTYPE_VS_BASE                   200
+
+
+/* NFC Task event messages */
+
+enum
+{
+    NFC_STATE_NONE,                 /* not start up yet                         */
+    NFC_STATE_W4_HAL_OPEN,          /* waiting for HAL_NFC_OPEN_CPLT_EVT        */
+    NFC_STATE_CORE_INIT,            /* sending CORE_RESET and CORE_INIT         */
+    NFC_STATE_W4_POST_INIT_CPLT,    /* waiting for HAL_NFC_POST_INIT_CPLT_EVT   */
+    NFC_STATE_IDLE,                 /* normal operation (discovery state)       */
+    NFC_STATE_OPEN,                 /* NFC link is activated                    */
+    NFC_STATE_CLOSING,              /* de-activating                            */
+    NFC_STATE_W4_HAL_CLOSE,         /* waiting for HAL_NFC_POST_INIT_CPLT_EVT   */
+    NFC_STATE_NFCC_POWER_OFF_SLEEP  /* NFCC is power-off sleep mode             */
+};
+typedef UINT8 tNFC_STATE;
+
+/* NFC control block flags */
+#define NFC_FL_DEACTIVATING             0x0001  /* NFC_Deactivate () is called and the NCI cmd is not sent   */
+#define NFC_FL_RESTARTING               0x0002  /* restarting NFCC after PowerOffSleep          */
+#define NFC_FL_POWER_OFF_SLEEP          0x0004  /* enterning power off sleep mode               */
+#define NFC_FL_POWER_CYCLE_NFCC         0x0008  /* Power cycle NFCC                             */
+#define NFC_FL_CONTROL_REQUESTED        0x0010  /* HAL requested control on NCI command window  */
+#define NFC_FL_CONTROL_GRANTED          0x0020  /* NCI command window is on the HAL side        */
+#define NFC_FL_DISCOVER_PENDING         0x0040  /* NCI command window is on the HAL side        */
+
+#define NFC_PEND_CONN_ID               0xFE
+#define NFC_CONN_ID_INT_MASK           0xF0
+#define NFC_CONN_ID_ID_MASK            NCI_CID_MASK
+#define NFC_CONN_NO_FC                 0xFF /* set num_buff to this for no flow control */
+#define NFC_NCI_CONN_NO_FC             0xFF
+
+#if (NFC_RW_ONLY == FALSE)
+/* only allow the entries that the NFCC can support */
+#define NFC_CHECK_MAX_CONN()    {if (max > nfc_cb.max_conn) max = nfc_cb.max_conn;}
+#else
+#define NFC_CHECK_MAX_CONN()
+#endif
+
+typedef struct
+{
+    tNFC_CONN_CBACK *p_cback;   /* the callback function to receive the data        */
+    BUFFER_Q    tx_q;           /* transmit queue                                   */
+    BUFFER_Q    rx_q;           /* receive queue                                    */
+    UINT8       id;             /* NFCEE ID or RF Discovery ID or NFC_TEST_ID       */
+    UINT8       act_protocol;   /* the active protocol on this logical connection   */
+    UINT8       conn_id;        /* the connection id assigned by NFCC for this conn */
+    UINT8       buff_size;      /* the max buffer size for this connection.     .   */
+    UINT8       num_buff;       /* num of buffers left to send on this connection   */
+    UINT8       init_credits;   /* initial num of buffer credits                    */
+} tNFC_CONN_CB;
+
+/* This data type is for NFC task to send a NCI VS command to NCIT task */
+typedef struct
+{
+    BT_HDR          bt_hdr;     /* the NCI command          */
+    tNFC_VS_CBACK   *p_cback;   /* the callback function to receive RSP   */
+} tNFC_NCI_VS_MSG;
+
+/* This data type is for HAL event */
+typedef struct
+{
+    BT_HDR          hdr;
+    UINT8           hal_evt;    /* HAL event code  */
+    UINT8           status;     /* tHAL_NFC_STATUS */
+} tNFC_HAL_EVT_MSG;
+
+#define NFC_RECEIVE_MSGS_OFFSET     (10) /* callback function pointer(8; use 8 to be safe + NFC_SAVED_CMD_SIZE(2) */
+
+/* NFCC power state change pending callback */
+typedef void (tNFC_PWR_ST_CBACK) (void);
+#define NFC_SAVED_HDR_SIZE          (2)
+/* data Reassembly error (in BT_HDR.layer_specific) */
+#define NFC_RAS_TOO_BIG             0x08
+#define NFC_RAS_FRAGMENTED          0x01
+
+/* NCI command buffer contains a VSC (in BT_HDR.layer_specific) */
+#define NFC_WAIT_RSP_VSC            0x01
+
+/* NFC control blocks */
+typedef struct
+{
+    UINT16              flags;                      /* NFC control block flags - NFC_FL_* */
+    tNFC_CONN_CB        conn_cb[NCI_MAX_CONN_CBS];
+    UINT8               conn_id[NFC_MAX_CONN_ID+1]; /* index: conn_id; conn_id[]: index(1 based) to conn_cb[] */
+    tNFC_DISCOVER_CBACK *p_discv_cback;
+    tNFC_RESPONSE_CBACK *p_resp_cback;
+    tNFC_TEST_CBACK     *p_test_cback;
+    tNFC_VS_CBACK       *p_vs_cb[NFC_NUM_VS_CBACKS];/* Register for vendor specific events  */
+
+#if (NFC_RW_ONLY == FALSE)
+    /* NFCC information at init rsp */
+    UINT32              nci_features;               /* the NCI features supported by NFCC */
+    UINT16              max_ce_table;               /* the max routing table size       */
+    UINT8               max_conn;                   /* the num of connections supported by NFCC */
+#endif
+    UINT8               nci_ctrl_size;              /* Max Control Packet Payload Size */
+
+    const tNCI_DISCOVER_MAPS  *p_disc_maps;         /* NCI RF Discovery interface mapping */
+    UINT8               vs_interface[NFC_NFCC_MAX_NUM_VS_INTERFACE];  /* the NCI VS interfaces of NFCC    */
+    UINT16              nci_interfaces;             /* the NCI interfaces of NFCC       */
+    UINT8               num_disc_maps;              /* number of RF Discovery interface mappings */
+    void               *p_disc_pending;            /* the parameters associated with pending NFC_DiscoveryStart */
+
+    /* NFC_TASK timer management */
+    TIMER_LIST_Q        timer_queue;                /* 1-sec timer event queue */
+    TIMER_LIST_Q        quick_timer_queue;
+
+    TIMER_LIST_ENT      deactivate_timer;           /* Timer to wait for deactivation */
+
+    tNFC_STATE          nfc_state;
+    UINT8               trace_level;
+    UINT8               last_hdr[NFC_SAVED_HDR_SIZE];/* part of last NCI command header */
+    UINT8               last_cmd[NFC_SAVED_CMD_SIZE];/* part of last NCI command payload */
+    void                *p_vsc_cback;       /* the callback function for last VSC command */
+    BUFFER_Q            nci_cmd_xmit_q;     /* NCI command queue */
+    TIMER_LIST_ENT      nci_wait_rsp_timer; /* Timer for waiting for nci command response */
+    UINT16              nci_wait_rsp_tout;  /* NCI command timeout (in ms) */
+    UINT8               nci_wait_rsp;       /* layer_specific for last NCI message */
+
+    UINT8               nci_cmd_window;     /* Number of commands the controller can accecpt without waiting for response */
+
+    BT_HDR              *p_nci_init_rsp;    /* holding INIT_RSP until receiving HAL_NFC_POST_INIT_CPLT_EVT */
+    tHAL_NFC_ENTRY      *p_hal;
+
+} tNFC_CB;
+
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+
+/* Global NFC data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+NFC_API extern tNFC_CB  nfc_cb;
+#else
+NFC_API extern tNFC_CB *nfc_cb_ptr;
+#define nfc_cb (*nfc_cb_ptr)
+#endif
+
+/****************************************************************************
+** Internal nfc functions
+****************************************************************************/
+
+NFC_API extern void nfc_init(void);
+
+/* from nfc_utils.c */
+NFC_API extern tNFC_CONN_CB * nfc_alloc_conn_cb ( tNFC_CONN_CBACK *p_cback);
+NFC_API extern tNFC_CONN_CB * nfc_find_conn_cb_by_conn_id (UINT8 conn_id);
+NFC_API extern tNFC_CONN_CB * nfc_find_conn_cb_by_handle (UINT8 target_handle);
+NFC_API extern void nfc_set_conn_id (tNFC_CONN_CB * p_cb, UINT8 conn_id);
+NFC_API extern void nfc_free_conn_cb (tNFC_CONN_CB *p_cb);
+NFC_API extern void nfc_reset_all_conn_cbs (void);
+NFC_API extern void nfc_data_event (tNFC_CONN_CB * p_cb);
+
+void nfc_ncif_send (BT_HDR *p_buf, BOOLEAN is_cmd);
+extern UINT8 nfc_ncif_send_data (tNFC_CONN_CB *p_cb, BT_HDR *p_data);
+NFC_API extern void nfc_ncif_cmd_timeout (void);
+NFC_API extern void nfc_wait_2_deactivate_timeout (void);
+
+NFC_API extern BOOLEAN nfc_ncif_process_event (BT_HDR *p_msg);
+NFC_API extern void nfc_ncif_check_cmd_queue (BT_HDR *p_buf);
+NFC_API extern void nfc_ncif_send_cmd (BT_HDR *p_buf);
+NFC_API extern void nfc_ncif_proc_discover_ntf (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_rf_management_status (tNFC_DISCOVER_EVT event, UINT8 status);
+NFC_API extern void nfc_ncif_set_config_status (UINT8 *p, UINT8 len);
+NFC_API extern void nfc_ncif_event_status (tNFC_RESPONSE_EVT event, UINT8 status);
+NFC_API extern void nfc_ncif_error_status (UINT8 conn_id, UINT8 status);
+NFC_API extern void nfc_ncif_proc_credits(UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_activate (UINT8 *p, UINT8 len);
+NFC_API extern void nfc_ncif_proc_deactivate (UINT8 status, UINT8 deact_type, BOOLEAN is_ntf);
+#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
+NFC_API extern void nfc_ncif_proc_ee_action (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_ee_discover_req (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_get_routing (UINT8 *p, UINT8 len);
+#endif
+NFC_API extern void nfc_ncif_proc_conn_create_rsp (UINT8 *p, UINT16 plen, UINT8 dest_type);
+NFC_API extern void nfc_ncif_report_conn_close_evt (UINT8 conn_id, tNFC_STATUS status);
+NFC_API extern void nfc_ncif_proc_t3t_polling_ntf (UINT8 *p, UINT16 plen);
+NFC_API extern void nfc_ncif_proc_reset_rsp (UINT8 *p, BOOLEAN is_ntf);
+NFC_API extern void nfc_ncif_proc_init_rsp (BT_HDR *p_msg);
+NFC_API extern void nfc_ncif_proc_get_config_rsp (BT_HDR *p_msg);
+NFC_API extern void nfc_ncif_proc_data (BT_HDR *p_msg);
+
+#if (NFC_RW_ONLY == FALSE)
+NFC_API extern void nfc_ncif_proc_rf_field_ntf (UINT8 rf_status);
+#else
+#define nfc_ncif_proc_rf_field_ntf(rf_status)
+#endif
+
+/* From nfc_task.c */
+NFC_API extern UINT32 nfc_task (UINT32 param);
+void nfc_task_shutdown_nfcc (void);
+
+/* From nfc_main.c */
+void nfc_enabled (tNFC_STATUS nfc_status, BT_HDR *p_init_rsp_msg);
+void nfc_set_state (tNFC_STATE nfc_state);
+void nfc_main_flush_cmd_queue (void);
+void nfc_gen_cleanup (void);
+void nfc_main_handle_hal_evt (tNFC_HAL_EVT_MSG *p_msg);
+
+/* Timer functions */
+void nfc_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+UINT32 nfc_remaining_time (TIMER_LIST_ENT *p_tle);
+void nfc_stop_timer (TIMER_LIST_ENT *p_tle);
+
+void nfc_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
+void nfc_stop_quick_timer (TIMER_LIST_ENT *p_tle);
+void nfc_process_quick_timer_evt (void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_INT_H_ */
diff --git a/src/nfc/int/rw_int.h b/src/nfc/int/rw_int.h
new file mode 100644
index 0000000..a1edb7b
--- /dev/null
+++ b/src/nfc/int/rw_int.h
@@ -0,0 +1,634 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Near Field Communication (NFC) Reader/Writer mode
+ *  related internal function / definitions.
+ *
+ ******************************************************************************/
+
+#ifndef RW_INT_H_
+#define RW_INT_H_
+
+#include "tags_defs.h"
+#include "tags_int.h"
+#include "rw_api.h"
+
+/* Proprietary definitions for HR0 and HR1 */
+#define RW_T1T_HR0_HI_NIB                       0xF0    /* HI NIB Tag                                               */
+#define RW_T1T_IS_JEWEL64                       0x20    /* Jewel 64 Tag                                             */
+#define RW_T1T_IS_JEWEL                         0x00    /* Jewel Tag                                                */
+#define RW_T1T_IS_TOPAZ                         0x10    /* TOPAZ Tag                                                */
+#define RW_T1T_IS_TOPAZ96                       0x11    /* TOPAZ96 Tag                                              */
+#define RW_T1T_IS_TOPAZ512                      0x12    /* TOPAZ512 Tag                                             */
+#define RW_T1T_HR1_MIN                          0x49    /* Supports dynamic commands on static tag if HR1 > 0x49    */
+
+#define RW_T1T_MAX_MEM_TLVS                     0x05    /* Maximum supported Memory control TLVS in the tag         */
+#define RW_T1T_MAX_LOCK_TLVS                    0x05    /* Maximum supported Lock control TLVS in the tag           */
+#define RW_T1T_MAX_LOCK_BYTES                   0x1E    /* Maximum supported dynamic lock bytes                     */
+
+/* State of the Tag as interpreted by RW */
+#define RW_T1_TAG_ATTRB_UNKNOWN                 0x00    /* TAG State is unknown to RW                               */
+#define RW_T1_TAG_ATTRB_INITIALIZED             0x01    /* TAG is in INITIALIZED state                              */
+#define RW_T1_TAG_ATTRB_INITIALIZED_NDEF        0x02    /* TAG is in INITIALIZED state and has NDEF tlv with len=0  */
+#define RW_T1_TAG_ATTRB_READ_ONLY               0x03    /* TAG is in READ ONLY state                                */
+#define RW_T1_TAG_ATTRB_READ_WRITE              0x04    /* TAG is in READ WRITE state                               */
+
+#define RW_T1T_LOCK_NOT_UPDATED                 0x00    /* Lock not yet set as part of SET TAG RO op                */
+#define RW_T1T_LOCK_UPDATE_INITIATED            0x01    /* Sent command to set the Lock bytes                       */
+#define RW_T1T_LOCK_UPDATED                     0x02    /* Lock bytes are set                                       */
+typedef UINT8 tRW_T1T_LOCK_STATUS;
+
+/* States */
+#define RW_T1T_STATE_NOT_ACTIVATED              0x00    /* Tag not activated and or response not received for RID   */
+#define RW_T1T_STATE_IDLE                       0x01    /* T1 Tag activated and ready to perform rw operation on Tag*/
+#define RW_T1T_STATE_READ                       0x02    /* waiting rsp for read command sent to tag                 */
+#define RW_T1T_STATE_WRITE                      0x03    /* waiting rsp for write command sent to tag                */
+#define RW_T1T_STATE_TLV_DETECT                 0x04    /* performing TLV detection procedure                       */
+#define RW_T1T_STATE_READ_NDEF                  0x05    /* performing read NDEF procedure                           */
+#define RW_T1T_STATE_WRITE_NDEF                 0x06    /* performing update NDEF procedure                         */
+#define RW_T1T_STATE_SET_TAG_RO                 0x07    /* Setting Tag as read only tag                             */
+#define RW_T1T_STATE_CHECK_PRESENCE             0x08    /* Check if Tag is still present                            */
+#define RW_T1T_STATE_FORMAT_TAG                 0x09    /* Format T1 Tag                                            */
+
+/* Sub states */
+#define RW_T1T_SUBSTATE_NONE                    0x00    /* Default substate                                         */
+
+/* Sub states in RW_T1T_STATE_TLV_DETECT state */
+#define RW_T1T_SUBSTATE_WAIT_TLV_DETECT         0x01    /* waiting for the detection of a tlv in a tag              */
+#define RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN 0x02    /* waiting for finding the len field is 1 or 3 bytes long   */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0      0x03    /* waiting for extracting len field value                   */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1      0x04    /* waiting for extracting len field value                   */
+#define RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE     0x05    /* waiting for extracting value field in the TLV            */
+#define RW_T1T_SUBSTATE_WAIT_READ_LOCKS         0x06    /* waiting for reading dynamic locks in the TLV             */
+
+/* Sub states in RW_T1T_STATE_WRITE_NDEF state */
+#define RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK    0x07    /* waiting for response of reading a block that will be partially updated */
+#define RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF    0x08    /* waiting for response of invalidating NDEF Msg                          */
+#define RW_T1T_SUBSTATE_WAIT_NDEF_WRITE         0x09    /* waiting for response of writing a part of NDEF Msg                     */
+#define RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED       0x0A    /* waiting for response of writing last part of NDEF Msg                  */
+#define RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF      0x0B    /* waiting for response of validating NDEF Msg                            */
+
+/* Sub states in RW_T1T_STATE_SET_TAG_RO state */
+#define RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO      0x0C    /* waiting for response of setting CC-RWA to read only      */
+#define RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS   0x0D    /* waiting for response of setting all static lock bits     */
+#define RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS  0x0E    /* waiting for response of setting all dynamic lock bits    */
+
+/* Sub states in RW_T1T_STATE_FORMAT_TAG state */
+#define RW_T1T_SUBSTATE_WAIT_SET_CC             0x0F    /* waiting for response to format/set capability container  */
+#define RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF      0x10    /* waiting for response to format/set NULL NDEF             */
+
+
+typedef struct
+{
+    UINT16  offset;                                     /* Offset of the lock byte in the Tag                   */
+    UINT8   num_bits;                                   /* Number of lock bits in the lock byte                 */
+    UINT8   bytes_locked_per_bit;                       /* No. of tag bytes gets locked by a bit in this byte   */
+} tRW_T1T_LOCK_INFO;
+
+typedef struct
+{
+    UINT16  offset;                                     /* Reserved bytes offset taken from Memory control TLV  */
+    UINT8   num_bytes;                                  /* Number of reserved bytes as per the TLV              */
+}tRW_T1T_RES_INFO;
+
+typedef struct
+{
+    UINT8               tlv_index;                      /* Index of Lock control tlv that points to this address*/
+    UINT8               byte_index;                     /* Index of Lock byte pointed by the TLV                */
+    UINT8               lock_byte;                      /* Value in the lock byte                               */
+    tRW_T1T_LOCK_STATUS lock_status;                    /* Indicates if it is modifed to set tag as Read only   */
+    BOOLEAN             b_lock_read;                    /* Is the lock byte is already read from tag            */
+} tRW_T1T_LOCK;
+
+typedef struct
+{
+    UINT8               addr;                           /* ADD/ADD8/ADDS field value                            */
+    UINT8               op_code;                        /* Command sent                                         */
+    UINT8               rsp_len;                        /* expected length of the response                      */
+    UINT8               pend_retx_rsp;                  /* Number of pending rsps to retransmission on prev cmd */
+} tRW_T1T_PREV_CMD_RSP_INFO;
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+#define T1T_BUFFER_SIZE             T1T_STATIC_SIZE     /* Buffer 0-E block, for easier tlv operation           */
+#else
+#define T1T_BUFFER_SIZE             T1T_UID_LEN         /* Buffer UID                                           */
+#endif
+
+/* RW Type 1 Tag control blocks */
+typedef struct
+{
+    UINT8               hr[T1T_HR_LEN];                     /* Header ROM byte 0 - 0x1y,Header ROM byte 1 - 0x00    */
+    UINT8               mem[T1T_SEGMENT_SIZE];              /* Tag contents of block 0 or from block 0-E            */
+    tT1T_CMD_RSP_INFO   *p_cmd_rsp_info;                    /* Pointer to Command rsp info of last sent command     */
+    UINT8               state;                              /* Current state of RW module                           */
+    UINT8               tag_attribute;                      /* Present state of the Tag as interpreted by RW        */
+    BT_HDR              *p_cur_cmd_buf;                     /* Buffer to hold cur sent command for retransmission   */
+    UINT8               addr;                               /* ADD/ADD8/ADDS value                                  */
+    tRW_T1T_PREV_CMD_RSP_INFO prev_cmd_rsp_info;            /* Information about previous sent command if retx      */
+    TIMER_LIST_ENT      timer;                              /* timer to set timelimit for the response to command   */
+    BOOLEAN             b_update;                           /* Tag header updated                                   */
+    BOOLEAN             b_rseg;                             /* Segment 0 read from tag                              */
+    BOOLEAN             b_hard_lock;                        /* Hard lock the tag as part of config tag to Read only */
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+    UINT8               segment;                            /* Current Tag segment                                  */
+    UINT8               substate;                           /* Current substate of RW module                        */
+    UINT16              work_offset;                        /* Working byte offset                                  */
+    UINT8               ndef_first_block[T1T_BLOCK_SIZE];   /* Buffer for ndef first block                          */
+    UINT8               ndef_final_block[T1T_BLOCK_SIZE];   /* Buffer for ndef last block                           */
+    UINT8               *p_ndef_buffer;                     /* Buffer to store ndef message                         */
+    UINT16              new_ndef_msg_len;                   /* Lenght of new updating NDEF Message                  */
+    UINT8               block_read;                         /* Last read Block                                      */
+    UINT8               write_byte;                         /* Index of last written byte                           */
+    UINT8               tlv_detect;                         /* TLV type under detection                             */
+    UINT16              ndef_msg_offset;                    /* The offset on Tag where first NDEF message is present*/
+    UINT16              ndef_msg_len;                       /* Lenght of NDEF Message                               */
+    UINT16              max_ndef_msg_len;                   /* Maximum size of NDEF that can be written on the tag  */
+    UINT16              ndef_header_offset;                 /* The offset on Tag where first NDEF tlv is present    */
+    UINT8               ndef_block_written;                 /* Last block where NDEF bytes are written              */
+    UINT8               num_ndef_finalblock;                /* Block number where NDEF's last byte will be present  */
+    UINT8               num_lock_tlvs;                      /* Number of lcok tlvs detected in the tag              */
+    tRW_T1T_LOCK_INFO   lock_tlv[RW_T1T_MAX_LOCK_TLVS];     /* Information retrieved from lock control tlv          */
+    UINT8               num_lockbytes;                      /* Number of dynamic lock bytes present in the tag      */
+    tRW_T1T_LOCK        lockbyte[RW_T1T_MAX_LOCK_BYTES];    /* Dynamic Lock byte information                        */
+    UINT8               num_mem_tlvs;                       /* Number of memory tlvs detected in the tag            */
+    tRW_T1T_RES_INFO    mem_tlv[RW_T1T_MAX_MEM_TLVS];       /* Information retrieved from mem tlv                   */
+    UINT8               attr_seg;                           /* Tag segment for which attributes are prepared        */
+    UINT8               lock_attr_seg;                      /* Tag segment for which lock attributes are prepared   */
+    UINT8               attr[T1T_BLOCKS_PER_SEGMENT];       /* byte information - Reserved/lock/otp or data         */
+    UINT8               lock_attr[T1T_BLOCKS_PER_SEGMENT];  /* byte information - read only or read write           */
+#endif
+} tRW_T1T_CB;
+
+/* Mifare Ultalight/ Ultralight Family blank tag version block settings */
+#define T2T_MIFARE_VERSION_BLOCK                        0x04    /* Block where version number of the tag is stored */
+#define T2T_MIFARE_ULTRALIGHT_VER_NO                    0xFFFF  /* Blank Ultralight tag - Block 4 (byte 0, byte 1) */
+#define T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO             0x0200  /* Blank Ultralight family tag - Block 4 (byte 0, byte 1) */
+
+/* Infineon my-d move / my-d blank tag uid block settings */
+#define T2T_INFINEON_VERSION_BLOCK                      0x00
+#define T2T_INFINEON_MYD_MOVE_LEAN                      0x0570
+#define T2T_INFINEON_MYD_MOVE                           0x0530
+
+#define T2T_BRCM_VERSION_BLOCK                          0x00
+#define T2T_BRCM_STATIC_MEM                             0x2E01
+#define T2T_BRCM_DYNAMIC_MEM                            0x2E02
+
+/* CC2 value on MiFare ULC tag */
+#define T2T_MIFARE_ULC_TMS                              0x12
+/* Possible corrupt cc2 value range on MiFare ULC tags */
+#define T2T_INVALID_CC_TMS_VAL0                         0x10
+#define T2T_INVALID_CC_TMS_VAL1                         0x1F
+
+#define T2T_NDEF_NOT_DETECTED                           0x00
+#define T2T_NDEF_DETECTED                               0x01
+#define T2T_NDEF_READ                                   0x02
+
+#define T2T_MAX_NDEF_OFFSET                             128     /* Max offset of an NDEF message in a T2 tag */
+#define T2T_MAX_RESERVED_BYTES_IN_TAG                   0x64
+#define T2T_MAX_LOCK_BYTES_IN_TAG                       0x64
+
+#define RW_T2T_MAX_MEM_TLVS                             0x05    /* Maximum supported Memory control TLVS in the tag         */
+#define RW_T2T_MAX_LOCK_TLVS                            0x05    /* Maximum supported Lock control TLVS in the tag           */
+#define RW_T2T_MAX_LOCK_BYTES                           0x1E    /* Maximum supported dynamic lock bytes                     */
+#define RW_T2T_SEGMENT_BYTES                            128
+#define RW_T2T_SEGMENT_SIZE                             16
+
+#define RW_T2T_LOCK_NOT_UPDATED                         0x00    /* Lock not yet set as part of SET TAG RO op                */
+#define RW_T2T_LOCK_UPDATE_INITIATED                    0x01    /* Sent command to set the Lock bytes                       */
+#define RW_T2T_LOCK_UPDATED                             0x02    /* Lock bytes are set                                       */
+typedef UINT8 tRW_T2T_LOCK_STATUS;
+
+
+/* States */
+#define RW_T2T_STATE_NOT_ACTIVATED                      0x00    /* Tag not activated                                        */
+#define RW_T2T_STATE_IDLE                               0x01    /* T1 Tag activated and ready to perform rw operation on Tag*/
+#define RW_T2T_STATE_READ                               0x02    /* waiting response for read command sent to tag            */
+#define RW_T2T_STATE_WRITE                              0x03    /* waiting response for write command sent to tag           */
+#define RW_T2T_STATE_SELECT_SECTOR                      0x04    /* Waiting response for sector select command               */
+#define RW_T2T_STATE_DETECT_TLV                         0x05    /* Detecting Lock/Memory/NDEF/Proprietary TLV in the Tag    */
+#define RW_T2T_STATE_READ_NDEF                          0x06    /* Performing NDEF Read procedure                           */
+#define RW_T2T_STATE_WRITE_NDEF                         0x07    /* Performing NDEF Write procedure                          */
+#define RW_T2T_STATE_SET_TAG_RO                         0x08    /* Setting Tag as Read only tag                             */
+#define RW_T2T_STATE_CHECK_PRESENCE                     0x09    /* Check if Tag is still present                            */
+#define RW_T2T_STATE_FORMAT_TAG                         0x0A    /* Format the tag                                           */
+
+/* rw_t2t_read/rw_t2t_write takes care of sector change if the block to read/write is in a different sector
+ * Next Substate should be assigned to control variable 'substate' before calling these function for State Machine to
+ * move back to the particular substate after Sector change is completed and read/write command is sent on new sector       */
+
+/* Sub states */
+#define RW_T2T_SUBSTATE_NONE                            0x00
+
+/* Sub states in RW_T2T_STATE_SELECT_SECTOR state */
+#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT      0x01    /* waiting for response of sector select CMD 1              */
+#define RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR              0x02    /* waiting for response of sector select CMD 2              */
+
+/* Sub states in RW_T1T_STATE_DETECT_XXX state */
+#define RW_T2T_SUBSTATE_WAIT_READ_CC                    0x03    /* waiting for the detection of a tlv in a tag              */
+#define RW_T2T_SUBSTATE_WAIT_TLV_DETECT                 0x04    /* waiting for the detection of a tlv in a tag              */
+#define RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN         0x05    /* waiting for finding the len field is 1 or 3 bytes long   */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0              0x06    /* waiting for extracting len field value                   */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1              0x07    /* waiting for extracting len field value                   */
+#define RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE             0x08    /* waiting for extracting value field in the TLV            */
+#define RW_T2T_SUBSTATE_WAIT_READ_LOCKS                 0x09    /* waiting for reading dynamic locks in the TLV             */
+
+/* Sub states in RW_T2T_STATE_WRITE_NDEF state */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK      0x0A    /* waiting for rsp to reading the block where NDEF starts   */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK       0x0B    /* waiting for rsp to reading block where new NDEF Msg ends */
+#define RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK        0x0C    /* waiting for rsp to reading block where Trm tlv gets added*/
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK       0x0D    /* waiting for rsp to reading block where nxt NDEF write    */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK      0x0E    /* waiting for rsp to writting NDEF block                   */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK      0x0F    /* waiting for rsp to last NDEF block write cmd             */
+#define RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK        0x10    /* waiting for rsp to reading NDEF len field block          */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK       0x11    /* waiting for rsp of updating first NDEF len field block   */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK  0x12    /* waiting for rsp of updating next NDEF len field block    */
+#define RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT       0x13    /* waiting for rsp to writing to Terminator tlv             */
+
+/* Sub states in RW_T2T_STATE_FORMAT_TAG state */
+#define RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO          0x14
+#define RW_T2T_SUBSTATE_WAIT_SET_CC                     0x15    /* waiting for response to format/set capability container  */
+#define RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV               0x16
+#define RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF              0x17    /* waiting for response to format/set NULL NDEF             */
+
+/* Sub states in RW_T2T_STATE_SET_TAG_RO state */
+#define RW_T2T_SUBSTATE_WAIT_SET_CC_RO                  0x19    /* waiting for response to set CC3 to RO                    */
+#define RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK   0x1A    /* waiting for response to read dynamic lock bytes block    */
+#define RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS          0x1B    /* waiting for response to set dynamic lock bits            */
+#define RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS           0x1C    /* waiting for response to set static lock bits             */
+
+typedef struct
+{
+    UINT16              offset;                             /* Offset of the lock byte in the Tag                       */
+    UINT8               num_bits;                           /* Number of lock bits in the lock byte                     */
+    UINT8               bytes_locked_per_bit;               /* No. of tag bytes gets locked by a bit in this byte       */
+} tRW_T2T_LOCK_INFO;
+
+typedef struct
+{
+    UINT16  offset;                                         /* Reserved bytes offset taken from Memory control TLV      */
+    UINT8   num_bytes;                                      /* Number of reserved bytes as per the TLV                  */
+}tRW_T2T_RES_INFO;
+
+typedef struct
+{
+    UINT8               tlv_index;                          /* Index of Lock control tlv that points to this address    */
+    UINT8               byte_index;                         /* Index of Lock byte pointed by the TLV                    */
+    UINT8               lock_byte;                          /* Value in the lock byte                                   */
+    tRW_T2T_LOCK_STATUS lock_status;                        /* Indicates if it is modifed to set tag as Read only       */
+    BOOLEAN             b_lock_read;                        /* Is the lock byte is already read from tag                */
+} tRW_T2T_LOCK;
+
+/* RW Type 2 Tag control block */
+typedef struct
+{
+    UINT8               state;                              /* Reader/writer state                                          */
+    UINT8               substate;                           /* Reader/write substate in NDEF write state                    */
+    UINT8               prev_substate;                      /* Substate of the tag before moving to different sector        */
+    UINT8               sector;                             /* Sector number that is selected                               */
+    UINT8               select_sector;                      /* Sector number that is expected to get selected               */
+    UINT8               tag_hdr[T2T_READ_DATA_LEN];         /* T2T Header blocks                                            */
+    UINT8               tag_data[T2T_READ_DATA_LEN];        /* T2T Block 4 - 7 data                                         */
+    UINT8               ndef_status;                        /* The current status of NDEF Write operation                   */
+    UINT16              block_read;                         /* Read block                                                   */
+    UINT16              block_written;                      /* Written block                                                */
+    tT2T_CMD_RSP_INFO   *p_cmd_rsp_info;                    /* Pointer to Command rsp info of last sent command             */
+    BT_HDR              *p_cur_cmd_buf;                     /* Copy of current command, for retx/send after sector change   */
+    BT_HDR              *p_sec_cmd_buf;                     /* Copy of command, to send after sector change                 */
+    TIMER_LIST_ENT      t2_timer;                           /* timeout for each API call                                    */
+    BOOLEAN             b_read_hdr;                         /* Tag header read from tag                                     */
+    BOOLEAN             b_read_data;                        /* Tag data block read from tag                                 */
+    BOOLEAN             b_hard_lock;                        /* Hard lock the tag as part of config tag to Read only         */
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+    UINT8               found_tlv;                          /* The Tlv found while searching a particular TLV               */
+    UINT8               tlv_detect;                         /* TLV type under detection                                     */
+    UINT8               num_lock_tlvs;                      /* Number of lcok tlvs detected in the tag                      */
+    UINT8               attr_seg;                           /* Tag segment for which attributes are prepared                */
+    UINT8               lock_attr_seg;                      /* Tag segment for which lock attributes are prepared           */
+    UINT8               segment;                            /* Current operating segment                                    */
+    UINT8               ndef_final_block[T2T_BLOCK_SIZE];   /* Buffer for ndef last block                                   */
+    UINT8               num_mem_tlvs;                       /* Number of memory tlvs detected in the tag                    */
+    UINT8               num_lockbytes;                      /* Number of dynamic lock bytes present in the tag              */
+    UINT8               attr[RW_T2T_SEGMENT_SIZE];          /* byte information - Reserved/lock/otp or data                 */
+    UINT8               lock_attr[RW_T2T_SEGMENT_SIZE];     /* byte information - read only or read write                   */
+    UINT8               tlv_value[3];                       /* Read value field of TLV                                      */
+    UINT8               ndef_first_block[T2T_BLOCK_LEN];    /* NDEF TLV Header block                                        */
+    UINT8               ndef_read_block[T2T_BLOCK_LEN];     /* Buffer to hold read before write block                       */
+    UINT8               ndef_last_block[T2T_BLOCK_LEN];     /* Terminator TLV block after NDEF Write operation              */
+    UINT8               terminator_tlv_block[T2T_BLOCK_LEN];/* Terminator TLV Block                                         */
+    UINT16              ndef_last_block_num;                /* Block where last byte of updating ndef message will exist    */
+    UINT16              ndef_read_block_num;                /* Block read during NDEF Write to avoid overwritting res bytes */
+    UINT16              bytes_count;                        /* No. of bytes remaining to collect during tlv detect          */
+    UINT16              terminator_byte_index;              /* The offset of the tag where terminator tlv may be added      */
+    UINT16              work_offset;                        /* Working byte offset                                          */
+    UINT16              ndef_header_offset;
+    UINT16              ndef_msg_offset;                    /* Offset on Tag where first NDEF message is present            */
+    UINT16              ndef_msg_len;                       /* Lenght of NDEF Message                                       */
+    UINT16              max_ndef_msg_len;                   /* Maximum size of NDEF that can be written on the tag          */
+    UINT16              new_ndef_msg_len;                   /* Lenght of new updating NDEF Message                          */
+    UINT16              ndef_write_block;
+    UINT16              prop_msg_len;                       /* Proprietary tlv length                                       */
+    UINT8               *p_new_ndef_buffer;                 /* Pointer to updating NDEF Message                             */
+    UINT8               *p_ndef_buffer;                     /* Pointer to NDEF Message                                      */
+    tRW_T2T_LOCK_INFO   lock_tlv[RW_T2T_MAX_LOCK_TLVS];     /* Information retrieved from lock control tlv                  */
+    tRW_T2T_LOCK        lockbyte[RW_T2T_MAX_LOCK_BYTES];    /* Dynamic Lock byte information                                */
+    tRW_T2T_RES_INFO    mem_tlv[RW_T2T_MAX_MEM_TLVS];       /* Information retrieved from mem tlv                           */
+#endif
+} tRW_T2T_CB;
+
+/* Type 3 Tag control block */
+typedef UINT8 tRW_T3T_RW_STATE;
+
+typedef struct
+{
+    tNFC_STATUS         status;
+    UINT8               version;        /* Ver: peer version */
+    UINT8               nbr;            /* NBr: number of blocks that can be read using one Check command */
+    UINT8               nbw;            /* Nbw: number of blocks that can be written using one Update command */
+    UINT16              nmaxb;          /* Nmaxb: maximum number of blocks available for NDEF data */
+    UINT8               writef;         /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
+    UINT8               rwflag;         /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+    UINT32              ln;             /* Ln: actual size of stored NDEF data (in bytes) */
+} tRW_T3T_DETECT;
+
+/* RW_T3T control block flags */
+#define RW_T3T_FL_IS_FINAL_NDEF_SEGMENT         0x01    /* The final command for completing the NDEF read/write */
+#define RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP    0x02    /* Waiting for POLL response for presence check */
+#define RW_T3T_FL_W4_GET_SC_POLL_RSP            0x04    /* Waiting for POLL response for RW_T3tGetSystemCodes */
+#define RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP       0x08    /* Waiting for POLL response for RW_T3tDetectNDef */
+#define RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP   0x10    /* Waiting for POLL response for RW_T3tFormat */
+
+typedef struct
+{
+    UINT32              cur_tout;               /* Current command timeout */
+    tRW_T3T_RW_STATE    rw_state;               /* Reader/writer state */
+    UINT8               rw_substate;
+    UINT8               cur_cmd;                /* Current command being executed */
+    BT_HDR              *p_cur_cmd_buf;         /* Copy of current command, for retransmission */
+    TIMER_LIST_ENT      timer;                  /* timeout for waiting for response */
+    TIMER_LIST_ENT      poll_timer;             /* timeout for waiting for response */
+
+    tRW_T3T_DETECT      ndef_attrib;            /* T3T NDEF attribute information */
+
+    UINT32              ndef_msg_len;           /* Length of ndef message to send */
+    UINT32              ndef_msg_bytes_sent;    /* Length of ndef message sent so far */
+    UINT8               *ndef_msg;              /* Buffer for outgoing NDEF message */
+    UINT32              ndef_rx_readlen;        /* Number of bytes read in current CHECK command */
+    UINT32              ndef_rx_offset;         /* Length of ndef message read so far */
+
+    UINT8               num_system_codes;       /* System codes detected */
+    UINT16              system_codes[T3T_MAX_SYSTEM_CODES];
+
+    UINT8               peer_nfcid2[NCI_NFCID2_LEN];
+    UINT8               cur_poll_rc;            /* RC used in current POLL command */
+
+    UINT8               flags;                  /* Flags see RW_T3T_FL_* */
+} tRW_T3T_CB;
+
+
+/*
+**  Type 4 Tag
+*/
+
+/* Max data size using a single ReadBinary. 2 bytes are for status bytes */
+#define RW_T4T_MAX_DATA_PER_READ           (NFC_RW_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_DATA_HDR_SIZE - T4T_RSP_STATUS_WORDS_SIZE)
+
+/* Max data size using a single UpdateBinary. 6 bytes are for CLA, INS, P1, P2, Lc */
+#define RW_T4T_MAX_DATA_PER_WRITE          (NFC_RW_POOL_BUF_SIZE - BT_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - T4T_CMD_MAX_HDR_SIZE)
+
+
+
+/* Mandatory NDEF file control */
+typedef struct
+{
+    UINT16              file_id;        /* File Identifier          */
+    UINT16              max_file_size;  /* Max NDEF file size       */
+    UINT8               read_access;    /* read access condition    */
+    UINT8               write_access;   /* write access condition   */
+} tRW_T4T_NDEF_FC;
+
+/* Capability Container */
+typedef struct
+{
+    UINT16              cclen;      /* the size of this capability container        */
+    UINT8               version;    /* the mapping specification version            */
+    UINT16              max_le;     /* the max data size by a single ReadBinary     */
+    UINT16              max_lc;     /* the max data size by a single UpdateBinary   */
+    tRW_T4T_NDEF_FC     ndef_fc;    /* Mandatory NDEF file control                  */
+} tRW_T4T_CC;
+
+typedef UINT8 tRW_T4T_RW_STATE;
+typedef UINT8 tRW_T4T_RW_SUBSTATE;
+
+/* Type 4 Tag Control Block */
+typedef struct
+{
+    tRW_T4T_RW_STATE    state;              /* main state                       */
+    tRW_T4T_RW_SUBSTATE sub_state;          /* sub state                        */
+    UINT8               version;            /* currently effective version      */
+    TIMER_LIST_ENT      timer;              /* timeout for each API call        */
+
+    UINT16              ndef_length;        /* length of NDEF data              */
+    UINT8              *p_update_data;      /* pointer of data to update        */
+    UINT16              rw_length;          /* remaining bytes to read/write    */
+    UINT16              rw_offset;          /* remaining offset to read/write   */
+    BT_HDR             *p_data_to_free;     /* GKI buffet to delete after done  */
+
+    tRW_T4T_CC          cc_file;            /* Capability Container File        */
+
+#define RW_T4T_NDEF_STATUS_NDEF_DETECTED    0x01    /* NDEF has been detected   */
+#define RW_T4T_NDEF_STATUS_NDEF_READ_ONLY   0x02    /* NDEF file is read-only   */
+
+    UINT8               ndef_status;        /* bitmap for NDEF status           */
+
+    UINT16              max_read_size;      /* max reading size per a command   */
+    UINT16              max_update_size;    /* max updating size per a command  */
+} tRW_T4T_CB;
+
+/* RW retransmission statistics */
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+typedef struct
+{
+    UINT32              start_tick;         /* System tick count at activation */
+    UINT32              bytes_sent;         /* Total bytes sent since activation */
+    UINT32              bytes_received;     /* Total bytes received since activation */
+    UINT32              num_ops;            /* Number of operations since activation */
+    UINT32              num_retries;        /* Number of retranmissions since activation */
+    UINT32              num_crc;            /* Number of crc failures */
+    UINT32              num_trans_err;      /* Number of transmission error notifications */
+    UINT32              num_fail;           /* Number of aborts (failures after retries) */
+} tRW_STATS;
+#endif  /* RW_STATS_INCLUDED */
+
+/* ISO 15693 RW Control Block */
+typedef UINT8 tRW_I93_RW_STATE;
+typedef UINT8 tRW_I93_RW_SUBSTATE;
+
+#define RW_I93_FLAG_READ_ONLY           0x01    /* tag is read-only                        */
+#define RW_I93_FLAG_READ_MULTI_BLOCK    0x02    /* tag supports read multi block           */
+#define RW_I93_FLAG_RESET_DSFID         0x04    /* need to reset DSFID for formatting      */
+#define RW_I93_FLAG_RESET_AFI           0x08    /* need to reset AFI for formatting        */
+
+#define RW_I93_TLV_DETECT_STATE_TYPE      0x01  /* searching for type                      */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_1  0x02  /* searching for the first byte of length  */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_2  0x03  /* searching for the second byte of length */
+#define RW_I93_TLV_DETECT_STATE_LENGTH_3  0x04  /* searching for the third byte of length  */
+#define RW_I93_TLV_DETECT_STATE_VALUE     0x05  /* reading value field                     */
+
+enum
+{
+    RW_I93_ICODE_SLI,                   /* ICODE SLI, SLIX                  */
+    RW_I93_ICODE_SLI_S,                 /* ICODE SLI-S, SLIX-S              */
+    RW_I93_ICODE_SLI_L,                 /* ICODE SLI-L, SLIX-L              */
+    RW_I93_TAG_IT_HF_I_PLUS_INLAY,      /* Tag-it HF-I Plus Inlay           */
+    RW_I93_TAG_IT_HF_I_PLUS_CHIP,       /* Tag-it HF-I Plus Chip            */
+    RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY,  /* Tag-it HF-I Standard Chip/Inlyas */
+    RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY,  /* Tag-it HF-I Pro Chip/Inlyas      */
+    RW_I93_UNKNOWN_PRODUCT              /* Unknwon product version          */
+};
+
+typedef struct
+{
+    tRW_I93_RW_STATE    state;                  /* main state                       */
+    tRW_I93_RW_SUBSTATE sub_state;              /* sub state                        */
+    TIMER_LIST_ENT      timer;                  /* timeout for each sent command    */
+    UINT8               sent_cmd;               /* last sent command                */
+
+    UINT8               info_flags;             /* information flags                */
+    UINT8               uid[I93_UID_BYTE_LEN];  /* UID of currently activated       */
+    UINT8               dsfid;                  /* DSFID if I93_INFO_FLAG_DSFID     */
+    UINT8               afi;                    /* AFI if I93_INFO_FLAG_AFI         */
+    UINT8               block_size;             /* block size of tag, in bytes      */
+    UINT16              num_block;              /* number of blocks in tag          */
+    UINT8               ic_reference;           /* IC Reference of tag              */
+    UINT8               product_version;        /* tag product version              */
+
+    UINT8               intl_flags;             /* flags for internal information   */
+
+    UINT8               tlv_detect_state;       /* TLV detecting state              */
+    UINT8               tlv_type;               /* currently detected type          */
+    UINT16              tlv_length;             /* currently detected length        */
+
+    UINT16              ndef_tlv_start_offset;  /* offset of first byte of NDEF TLV */
+    UINT16              ndef_tlv_last_offset;   /* offset of last byte of NDEF TLV  */
+    UINT16              max_ndef_length;        /* max NDEF length the tag contains */
+    UINT16              ndef_length;            /* length of NDEF data              */
+
+    UINT8              *p_update_data;          /* pointer of data to update        */
+    UINT16              rw_length;              /* bytes to read/write              */
+    UINT16              rw_offset;              /* offset to read/write             */
+} tRW_I93_CB;
+
+/* RW memory control blocks */
+typedef union
+{
+    tRW_T1T_CB          t1t;
+    tRW_T2T_CB          t2t;
+    tRW_T3T_CB          t3t;
+    tRW_T4T_CB          t4t;
+    tRW_I93_CB          i93;
+} tRW_TCB;
+
+/* RW control blocks */
+typedef struct
+{
+    tRW_TCB             tcb;
+    tRW_CBACK           *p_cback;
+    UINT32              cur_retry;          /* Retry count for the current operation */
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    tRW_STATS           stats;
+#endif  /* RW_STATS_INCLUDED */
+    UINT8               trace_level;
+} tRW_CB;
+
+
+/*****************************************************************************
+**  EXTERNAL FUNCTION DECLARATIONS
+*****************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global NFC data */
+#if NFC_DYNAMIC_MEMORY == FALSE
+NFC_API extern tRW_CB  rw_cb;
+#else
+NFC_API extern tRW_CB *rw_cb_ptr;
+#define rw_cb (*rw_cb_ptr)
+#endif
+
+/* from .c */
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+extern tRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status);
+extern tRW_EVENT rw_t1t_info_to_event (const tT1T_CMD_RSP_INFO * p_info);
+#else
+#define rw_t1t_handle_rsp(p, a, b, c)       t1t_info_to_evt (p)
+#define rw_t1t_info_to_event(p)             t1t_info_to_evt (p)
+#endif
+
+extern void rw_init (void);
+extern tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN]);
+extern tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat);
+extern tNFC_STATUS rw_t1t_send_static_cmd (UINT8 opcode, UINT8 add, UINT8 dat);
+extern void rw_t1t_process_timeout (TIMER_LIST_ENT *p_tle);
+extern void rw_t1t_handle_op_complete (void);
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+extern tRW_EVENT rw_t2t_info_to_event (const tT2T_CMD_RSP_INFO *p_info);
+extern void rw_t2t_handle_rsp (UINT8 *p_data);
+#else
+#define rw_t2t_info_to_event(p)             t2t_info_to_evt (p)
+#define rw_t2t_handle_rsp(p)
+#endif
+
+extern tNFC_STATUS rw_t2t_sector_change (UINT8 sector);
+extern tNFC_STATUS rw_t2t_read (UINT16 block);
+extern tNFC_STATUS rw_t2t_write (UINT16 block, UINT8 *p_write_data);
+extern void rw_t2t_process_timeout (TIMER_LIST_ENT *p_tle);
+extern tNFC_STATUS rw_t2t_select (void);
+void rw_t2t_handle_op_complete (void);
+
+extern void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle);
+extern tNFC_STATUS rw_t3t_select (UINT8 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update);
+void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+
+extern tNFC_STATUS rw_t4t_select (void);
+extern void rw_t4t_process_timeout (TIMER_LIST_ENT *p_tle);
+
+extern tNFC_STATUS rw_i93_select (void);
+extern void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+/* Internal fcns for statistics (from rw_main.c) */
+void rw_main_reset_stats (void);
+void rw_main_update_tx_stats (UINT32 bytes_tx, BOOLEAN is_retry);
+void rw_main_update_rx_stats (UINT32 bytes_rx);
+void rw_main_update_crc_error_stats (void);
+void rw_main_update_trans_error_stats (void);
+void rw_main_update_fail_stats (void);
+void rw_main_log_stats (void);
+#endif  /* RW_STATS_INCLUDED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RW_INT_H_ */
diff --git a/src/nfc/int/tags_int.h b/src/nfc/int/tags_int.h
new file mode 100644
index 0000000..4a6cf98
--- /dev/null
+++ b/src/nfc/int/tags_int.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the common data types shared by Reader/Writer mode
+ *  and Card Emulation.
+ *
+ ******************************************************************************/
+
+#ifndef TAGS_INT_H
+#define TAGS_INT_H
+
+/******************************************************************************
+// T1T command and response definitions
+******************************************************************************/
+
+typedef struct
+{
+    UINT8   opcode;
+    UINT8   cmd_len;
+    UINT8   uid_offset;
+    UINT8   rsp_len;
+} tT1T_CMD_RSP_INFO;
+
+typedef struct
+{
+    UINT8   tag_model;
+    UINT8   tms;
+    UINT8   b_dynamic;
+    UINT8   lock_tlv[3];
+    UINT8   mem_tlv[3];
+} tT1T_INIT_TAG;
+
+typedef struct
+{
+    UINT8   manufacturer_id;
+    BOOLEAN b_multi_version;
+    UINT8   version_block;
+    UINT16  version_no;
+    UINT16  version_bmask;
+    UINT8   b_calc_cc;
+    UINT8   tms;
+    BOOLEAN b_otp;
+    UINT8   default_lock_blpb;
+} tT2T_INIT_TAG;
+
+typedef struct
+{
+    UINT8   opcode;
+    UINT8   cmd_len;
+    UINT8   rsp_len;
+    UINT8   nack_rsp_len;
+} tT2T_CMD_RSP_INFO;
+
+extern const UINT8 t4t_v10_ndef_tag_aid[];  /* V1.0 Type 4 Tag Applicaiton ID */
+extern const UINT8 t4t_v20_ndef_tag_aid[];  /* V2.0 Type 4 Tag Applicaiton ID */
+
+extern const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[];
+extern const tT1T_INIT_TAG t1t_init_content[];
+extern const tT1T_CMD_RSP_INFO * t1t_cmd_to_rsp_info (UINT8 opcode);
+extern const tT1T_INIT_TAG * t1t_tag_init_data (UINT8 tag_model);
+extern UINT8 t1t_info_to_evt (const tT1T_CMD_RSP_INFO * p_info);
+
+extern const tT2T_INIT_TAG * t2t_tag_init_data (UINT8 manufacturer_id, BOOLEAN b_valid_ver, UINT16 version_no);
+extern const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[];
+extern const tT2T_CMD_RSP_INFO * t2t_cmd_to_rsp_info (UINT8 opcode);
+extern UINT8 t2t_info_to_evt (const tT2T_CMD_RSP_INFO * p_info);
+
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+extern const char * t1t_info_to_str (const tT1T_CMD_RSP_INFO * p_info);
+extern const char * t2t_info_to_str (const tT2T_CMD_RSP_INFO * p_info);
+#else
+#define t1t_info_to_str(x) ""
+#define t2t_info_to_str(x) ""
+#endif
+extern int tags_pow (int x, int y);
+extern unsigned int tags_log2 (register unsigned int x);
+
+
+#endif /* TAGS_INT_H */
diff --git a/src/nfc/llcp/llcp_api.c b/src/nfc/llcp/llcp_api.c
new file mode 100644
index 0000000..1764a1c
--- /dev/null
+++ b/src/nfc/llcp/llcp_api.c
@@ -0,0 +1,1626 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP API code
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+
+tLLCP_TEST_PARAMS llcp_test_params =
+{
+    LLCP_VERSION_VALUE,
+    0,                             /* not override */
+};
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTestParams
+**
+** Description      Set test parameters for LLCP
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_SetTestParams (UINT8 version, UINT16 wks)
+{
+    LLCP_TRACE_API2 ("LLCP_SetTestParams () version:0x%02X, wks:0x%04X",
+                     version, wks);
+
+    if (version != 0xFF)
+        llcp_test_params.version = version;
+
+    if (wks != 0xFFFF)
+        llcp_test_params.wks = wks;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterDtaCback
+**
+** Description      Register callback function for LLCP DTA testing
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_RegisterDtaCback (tLLCP_DTA_CBACK *p_dta_cback)
+{
+    LLCP_TRACE_API0 ("LLCP_RegisterDtaCback ()");
+
+    llcp_cb.p_dta_cback = p_dta_cback;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetConfig
+**
+** Description      Set configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_SetConfig (UINT16 link_miu,
+                     UINT8  opt,
+                     UINT8  wt,
+                     UINT16 link_timeout,
+                     UINT16 inact_timeout_init,
+                     UINT16 inact_timeout_target,
+                     UINT16 symm_delay,
+                     UINT16 data_link_timeout,
+                     UINT16 delay_first_pdu_timeout)
+{
+    LLCP_TRACE_API4 ("LLCP_SetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+                     link_miu, opt, wt, link_timeout);
+    LLCP_TRACE_API4 ("                 inact_timeout (init:%d,target:%d), symm_delay:%d, data_link_timeout:%d",
+                     inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
+    LLCP_TRACE_API1 ("                 delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
+
+    if (link_miu < LLCP_DEFAULT_MIU)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be smaller than LLCP_DEFAULT_MIU (%d)",
+                            LLCP_DEFAULT_MIU);
+        link_miu = LLCP_DEFAULT_MIU;
+    }
+    else if (link_miu > LLCP_MAX_MIU)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MAX_MIU (%d)",
+                            LLCP_MAX_MIU);
+        link_miu = LLCP_MAX_MIU;
+    }
+
+    /* if Link MIU is bigger than GKI buffer */
+    if (link_miu > LLCP_MIU)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MIU (%d)",
+                            LLCP_MIU);
+        llcp_cb.lcb.local_link_miu = LLCP_MIU;
+    }
+    else
+        llcp_cb.lcb.local_link_miu = link_miu;
+
+    llcp_cb.lcb.local_opt = opt;
+    llcp_cb.lcb.local_wt  = wt;
+
+    if (link_timeout < LLCP_LTO_UNIT)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be smaller than LLCP_LTO_UNIT (%d ms)",
+                            LLCP_LTO_UNIT);
+        llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS;
+    }
+    else if (link_timeout > LLCP_MAX_LTO_IN_MS)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be bigger than LLCP_MAX_LTO_IN_MS (%d ms)",
+                            LLCP_MAX_LTO_IN_MS);
+        llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS;
+    }
+    else
+        llcp_cb.lcb.local_lto = link_timeout;
+
+    llcp_cb.lcb.inact_timeout_init   = inact_timeout_init;
+    llcp_cb.lcb.inact_timeout_target = inact_timeout_target;
+    llcp_cb.lcb.symm_delay           = symm_delay;
+    llcp_cb.lcb.data_link_timeout    = data_link_timeout;
+    llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetConfig
+**
+** Description      Get configuration parameters for LLCP
+**                  - Local Link MIU
+**                  - Option parameter
+**                  - Response Waiting Time Index
+**                  - Local Link Timeout
+**                  - Inactivity Timeout as initiator role
+**                  - Inactivity Timeout as target role
+**                  - Delay SYMM response
+**                  - Data link connection timeout
+**                  - Delay timeout to send first PDU as initiator
+**
+** Returns          void
+**
+*******************************************************************************/
+void LLCP_GetConfig (UINT16 *p_link_miu,
+                     UINT8  *p_opt,
+                     UINT8  *p_wt,
+                     UINT16 *p_link_timeout,
+                     UINT16 *p_inact_timeout_init,
+                     UINT16 *p_inact_timeout_target,
+                     UINT16 *p_symm_delay,
+                     UINT16 *p_data_link_timeout,
+                     UINT16 *p_delay_first_pdu_timeout)
+{
+    *p_link_miu             = llcp_cb.lcb.local_link_miu;
+    *p_opt                  = llcp_cb.lcb.local_opt;
+    *p_wt                   = llcp_cb.lcb.local_wt;
+    *p_link_timeout         = llcp_cb.lcb.local_lto;
+    *p_inact_timeout_init   = llcp_cb.lcb.inact_timeout_init;
+    *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target;
+    *p_symm_delay           = llcp_cb.lcb.symm_delay;
+    *p_data_link_timeout    = llcp_cb.lcb.data_link_timeout;
+    *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout;
+
+    LLCP_TRACE_API4 ("LLCP_GetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
+                     *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
+    LLCP_TRACE_API4 ("                 inact_timeout (init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
+                     *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
+    LLCP_TRACE_API1 ("                 delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetDiscoveryConfig
+**
+** Description      Returns discovery config for ISO 18092 MAC link activation
+**                  This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
+**                  or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
+**
+**                  wt:Waiting time 0 - 8, only for listen
+**                  p_gen_bytes: pointer to store LLCP magic number and paramters
+**                  p_gen_bytes_len: length of buffer for gen bytes as input
+**                                   (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
+**                                   actual gen bytes size as output
+**
+**                  Restrictions on the use of ISO 18092
+**                  1. The DID features shall not be used.
+**                  2. the NAD features shall not be used.
+**                  3. Frame waiting time extentions (WTX) shall not be used.
+**
+** Returns          None
+**
+*******************************************************************************/
+void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
+                              UINT8 *p_gen_bytes,
+                              UINT8 *p_gen_bytes_len)
+{
+    UINT8      *p = p_gen_bytes;
+
+    LLCP_TRACE_API0 ("LLCP_GetDiscoveryConfig ()");
+
+    if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_GetDiscoveryConfig (): GenBytes length shall not be smaller than LLCP_MIN_GEN_BYTES (%d)",
+                            LLCP_MIN_GEN_BYTES);
+        *p_gen_bytes_len = 0;
+        return;
+    }
+
+    *p_wt = llcp_cb.lcb.local_wt;
+
+    UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE0);
+    UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE1);
+    UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE2);
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+    UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
+    UINT8_TO_BE_STREAM (p, llcp_test_params.version);
+
+    UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+    UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
+
+    UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
+    if (llcp_test_params.wks == 0)  /* not override */
+    {
+        UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
+    }
+    else
+    {
+        UINT16_TO_BE_STREAM (p, llcp_test_params.wks);
+    }
+#else
+    UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
+    UINT8_TO_BE_STREAM (p, LLCP_VERSION_VALUE);
+
+    UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+    UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
+
+    UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
+    UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
+#endif
+
+    UINT8_TO_BE_STREAM (p, LLCP_LTO_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_LTO_LEN);
+    UINT8_TO_BE_STREAM (p, (llcp_cb.lcb.local_lto/LLCP_LTO_UNIT));
+
+    UINT8_TO_BE_STREAM (p, LLCP_OPT_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_OPT_LEN);
+    UINT8_TO_BE_STREAM (p, llcp_cb.lcb.local_opt);
+
+    *p_gen_bytes_len = (UINT8) (p - p_gen_bytes);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ActivateLink
+**
+** Description      This function will activate LLCP link with LR, WT and Gen Bytes
+**                  in activation NTF from NFCC.
+**
+**                  LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
+**                  callback function if successful.
+**                  Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
+                                tLLCP_LINK_CBACK     *p_link_cback)
+{
+    LLCP_TRACE_API1 ("LLCP_ActivateLink () link_state = %d", llcp_cb.lcb.link_state);
+
+    if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
+        &&(p_link_cback)  )
+    {
+        llcp_cb.lcb.p_link_cback = p_link_cback;
+        return (llcp_link_activate (&config));
+    }
+    else
+        return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_DeactivateLink
+**
+** Description      Deactivate LLCP link
+**
+**                  LLCP_LINK_DEACTIVATED_EVT will be returned through callback
+**                  when LLCP link is deactivated. Then NFC link may be deactivated.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DeactivateLink (void)
+{
+    LLCP_TRACE_API1 ("LLCP_DeactivateLink () link_state = %d", llcp_cb.lcb.link_state);
+
+    if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
+    {
+        llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
+        return LLCP_STATUS_SUCCESS;
+    }
+    else
+        return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterServer
+**
+** Description      Register server and callback function
+**
+**                  reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
+**                            Advertized by SDP (0x10 - 0x1F)
+**                            LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**                  p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
+**
+** Returns          SAP between 0x02 and 0x1F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+UINT8 LLCP_RegisterServer (UINT8           reg_sap,
+                           UINT8           link_type,
+                           char            *p_service_name,
+                           tLLCP_APP_CBACK *p_app_cback)
+{
+    UINT8  sap;
+    UINT16 length;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_API3 ("LLCP_RegisterServer (): SAP:0x%x, link_type:0x%x, ServiceName:<%s>",
+                     reg_sap, link_type, ((p_service_name == NULL) ? "" : p_service_name));
+
+    if (!p_app_cback)
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Callback must be provided");
+        return LLCP_INVALID_SAP;
+    }
+    else if (  ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
+             &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)  )
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): link type (0x%x) must be specified", link_type);
+        return LLCP_INVALID_SAP;
+    }
+
+    if (reg_sap == LLCP_INVALID_SAP)
+    {
+        /* allocate a SAP between 0x10 and 0x1F */
+        for (sap = 0; sap <= LLCP_MAX_SERVER; sap++)
+        {
+            if (llcp_cb.server_cb[sap].p_app_cback == NULL)
+            {
+                p_app_cb = &llcp_cb.server_cb[sap];
+                reg_sap  = LLCP_LOWER_BOUND_SDP_SAP + sap;
+                break;
+            }
+        }
+
+        if (reg_sap == LLCP_INVALID_SAP)
+        {
+            LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): out of resource");
+            return LLCP_INVALID_SAP;
+        }
+    }
+    else if (reg_sap == LLCP_SAP_LM)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is for link manager", reg_sap);
+        return LLCP_INVALID_SAP;
+    }
+    else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
+    {
+        if (reg_sap >= LLCP_MAX_WKS)
+        {
+            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
+            return LLCP_INVALID_SAP;
+        }
+        else if (llcp_cb.wks_cb[reg_sap].p_app_cback)
+        {
+            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
+            return LLCP_INVALID_SAP;
+        }
+        else
+        {
+            p_app_cb = &llcp_cb.wks_cb[reg_sap];
+        }
+    }
+    else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP)
+    {
+        if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER)
+        {
+            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
+            return LLCP_INVALID_SAP;
+        }
+        else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP].p_app_cback)
+        {
+            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
+            return LLCP_INVALID_SAP;
+        }
+        else
+        {
+            p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP];
+        }
+    }
+    else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP)
+    {
+        LLCP_TRACE_ERROR2 ("LLCP_RegisterServer (): SAP (0x%x) must be less than 0x%x",
+                            reg_sap, LLCP_LOWER_BOUND_LOCAL_SAP);
+        return LLCP_INVALID_SAP;
+    }
+
+    memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
+
+    if (p_service_name)
+    {
+        length = (UINT8) strlen (p_service_name);
+        if (length > LLCP_MAX_SN_LEN)
+        {
+            LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): Service Name (%d bytes) is too long", length);
+            return LLCP_INVALID_SAP;
+        }
+
+        p_app_cb->p_service_name = (UINT8 *) GKI_getbuf ((UINT16) (length + 1));
+        if (p_app_cb->p_service_name == NULL)
+        {
+            LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
+            return LLCP_INVALID_SAP;
+        }
+
+        BCM_STRNCPY_S ((char *) p_app_cb->p_service_name, length + 1, (char *) p_service_name, length + 1);
+        p_app_cb->p_service_name[length] = 0;
+    }
+    else
+        p_app_cb->p_service_name = NULL;
+
+    p_app_cb->p_app_cback = p_app_cback;
+    p_app_cb->link_type   = link_type;
+
+    if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
+    {
+        llcp_cb.lcb.wks |= (1 << reg_sap);
+    }
+
+    LLCP_TRACE_DEBUG1 ("LLCP_RegisterServer (): Registered SAP = 0x%02X", reg_sap);
+
+    if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+    {
+        llcp_cb.num_logical_data_link++;
+        llcp_util_adjust_ll_congestion ();
+    }
+
+    return reg_sap;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_RegisterClient
+**
+** Description      Register client and callback function
+**
+**                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
+**                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
+**
+** Returns          SAP between 0x20 and 0x3F, if success
+**                  LLCP_INVALID_SAP, otherwise
+**
+*******************************************************************************/
+UINT8 LLCP_RegisterClient (UINT8           link_type,
+                           tLLCP_APP_CBACK *p_app_cback)
+{
+    UINT8 reg_sap = LLCP_INVALID_SAP;
+    UINT8 sap;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_API1 ("LLCP_RegisterClient (): link_type = 0x%x", link_type);
+
+    if (!p_app_cback)
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): Callback must be provided");
+        return LLCP_INVALID_SAP;
+    }
+    else if (  ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
+             &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)  )
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_RegisterClient (): link type (0x%x) must be specified", link_type);
+        return LLCP_INVALID_SAP;
+    }
+
+    /* allocate a SAP between 0x20 and 0x3F */
+    for (sap = 0; sap <= LLCP_MAX_CLIENT; sap++)
+    {
+        if (llcp_cb.client_cb[sap].p_app_cback == NULL)
+        {
+            p_app_cb = &llcp_cb.client_cb[sap];
+            memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
+            reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
+            break;
+        }
+    }
+
+    if (reg_sap == LLCP_INVALID_SAP)
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): out of resource");
+        return LLCP_INVALID_SAP;
+    }
+
+    p_app_cb->p_app_cback    = p_app_cback;
+    p_app_cb->p_service_name = NULL;
+    p_app_cb->link_type      = link_type;
+
+    LLCP_TRACE_DEBUG1 ("LLCP_RegisterClient (): Registered SAP = 0x%02X", reg_sap);
+
+    if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+    {
+        llcp_cb.num_logical_data_link++;
+        llcp_util_adjust_ll_congestion ();
+    }
+
+    return reg_sap;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_Deregister
+**
+** Description      Deregister server or client
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_Deregister (UINT8 local_sap)
+{
+    UINT8 idx;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_API1 ("LLCP_Deregister () SAP:0x%x", local_sap);
+
+    p_app_cb = llcp_util_get_app_cb (local_sap);
+
+    if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL))
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_Deregister (): SAP (0x%x) is not registered", local_sap);
+        return LLCP_STATUS_FAIL;
+    }
+
+    if (p_app_cb->p_service_name)
+        GKI_freebuf (p_app_cb->p_service_name);
+
+    /* update WKS bit map */
+    if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+    {
+        llcp_cb.lcb.wks &= ~ (1 << local_sap);
+    }
+
+    /* discard any received UI PDU on this SAP */
+    LLCP_FlushLogicalLinkRxData (local_sap);
+    llcp_cb.total_rx_ui_pdu = 0;
+
+    /* deallocate any data link connection on this SAP */
+    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+    {
+        if (  (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
+            &&(llcp_cb.dlcb[idx].local_sap == local_sap)  )
+        {
+            llcp_util_deallocate_data_link (&llcp_cb.dlcb[idx]);
+        }
+    }
+
+    p_app_cb->p_app_cback = NULL;
+
+    /* discard any pending tx UI PDU from this SAP */
+    while (p_app_cb->ui_xmit_q.p_first)
+    {
+        GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
+        llcp_cb.total_tx_ui_pdu--;
+    }
+
+    if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+    {
+        llcp_cb.num_logical_data_link--;
+        llcp_util_adjust_ll_congestion ();
+    }
+
+    /* check rx congestion status */
+    llcp_util_check_rx_congested_status ();
+
+    return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_IsLogicalLinkCongested
+**
+** Description      Check if logical link is congested
+**
+**
+** Returns          TRUE if congested
+**
+*******************************************************************************/
+BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
+                                     UINT8 num_pending_ui_pdu,
+                                     UINT8 total_pending_ui_pdu,
+                                     UINT8 total_pending_i_pdu)
+{
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_API4 ("LLCP_IsLogicalLinkCongested () Local SAP:0x%x, pending = (%d, %d, %d)",
+                     local_sap, num_pending_ui_pdu, total_pending_ui_pdu, total_pending_i_pdu);
+
+    p_app_cb = llcp_util_get_app_cb (local_sap);
+
+    if (  (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
+        ||(p_app_cb == NULL)
+        ||(p_app_cb->p_app_cback == NULL)
+        ||((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
+        ||(p_app_cb->is_ui_tx_congested)  )
+    {
+        return (TRUE);
+    }
+    else if (  (num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
+             ||(total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)
+             ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)  )
+    {
+        /* set flag so LLCP can notify uncongested status later */
+        p_app_cb->is_ui_tx_congested = TRUE;
+
+        return (TRUE);
+    }
+    return (FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SendUI
+**
+** Description      Send connnectionless data to DSAP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if logical link is congested
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SendUI (UINT8   ssap,
+                          UINT8   dsap,
+                          BT_HDR *p_buf)
+{
+    tLLCP_STATUS status = LLCP_STATUS_FAIL;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_API2 ("LLCP_SendUI () SSAP=0x%x, DSAP=0x%x", ssap, dsap);
+
+    p_app_cb = llcp_util_get_app_cb (ssap);
+
+    if (  (p_app_cb == NULL)
+        ||(p_app_cb->p_app_cback == NULL)  )
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SendUI (): SSAP (0x%x) is not registered", ssap);
+    }
+    else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_SendUI (): Logical link on SSAP (0x%x) is not enabled", ssap);
+    }
+    else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_SendUI (): LLCP link is not activated");
+    }
+    else if (  (llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN)
+             ||(llcp_cb.lcb.peer_opt & LLCP_LSC_1)  )
+    {
+        if (p_buf->len <= llcp_cb.lcb.peer_miu)
+        {
+            if (p_buf->offset >= LLCP_MIN_OFFSET)
+            {
+                status = llcp_util_send_ui (ssap, dsap, p_app_cb, p_buf);
+            }
+            else
+            {
+                LLCP_TRACE_ERROR2 ("LLCP_SendUI (): offset (%d) must be %d at least",
+                                    p_buf->offset, LLCP_MIN_OFFSET );
+            }
+        }
+        else
+        {
+            LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Data length shall not be bigger than peer's link MIU");
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Peer doesn't support connectionless link");
+    }
+
+    if (status == LLCP_STATUS_FAIL)
+    {
+        GKI_freebuf (p_buf);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadLogicalLinkData
+**
+** Description      Read information of UI PDU for local SAP
+**
+**                  - Remote SAP who sent UI PDU is returned.
+**                  - Information of UI PDU up to max_data_len is copied into p_data.
+**                  - Information of next UI PDU is not concatenated.
+**                  - Recommended max_data_len is link MIU of local device
+**
+** Returns          TRUE if more information of UI PDU or more UI PDU in queue
+**
+*******************************************************************************/
+BOOLEAN LLCP_ReadLogicalLinkData (UINT8  local_sap,
+                                  UINT32 max_data_len,
+                                  UINT8  *p_remote_sap,
+                                  UINT32 *p_data_len,
+                                  UINT8  *p_data)
+{
+    tLLCP_APP_CB *p_app_cb;
+    BT_HDR       *p_buf;
+    UINT8        *p_ui_pdu;
+    UINT16       pdu_hdr, ui_pdu_length;
+
+    LLCP_TRACE_API1 ("LLCP_ReadLogicalLinkData () Local SAP:0x%x", local_sap);
+
+    *p_data_len = 0;
+
+    p_app_cb = llcp_util_get_app_cb (local_sap);
+
+    /* if application is registered */
+    if ((p_app_cb) && (p_app_cb->p_app_cback))
+    {
+        /* if any UI PDU in rx queue */
+        if (p_app_cb->ui_rx_q.p_first)
+        {
+            p_buf    = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
+            p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+            /* get length of UI PDU */
+            BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
+
+            /* get remote SAP from LLCP header */
+            BE_STREAM_TO_UINT16 (pdu_hdr, p_ui_pdu);
+            *p_remote_sap = LLCP_GET_SSAP (pdu_hdr);
+
+            /* layer_specific has the offset to read within UI PDU */
+            p_ui_pdu += p_buf->layer_specific;
+
+            /* copy data up to max_data_len */
+            if (max_data_len >= (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific))
+            {
+                /* copy information without LLCP header */
+                *p_data_len = (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
+
+                /* move to next UI PDU if any */
+                p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next UI PDU */
+                p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+                p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+            }
+            else
+            {
+                *p_data_len = max_data_len;
+
+                /* update offset to read from remaining UI PDU next time */
+                p_buf->layer_specific += max_data_len;
+            }
+
+            memcpy (p_data, p_ui_pdu, *p_data_len);
+
+            /* if read all of UI PDU */
+            if (p_buf->len == 0)
+            {
+                GKI_dequeue (&p_app_cb->ui_rx_q);
+                GKI_freebuf (p_buf);
+
+                /* decrease number of received UI PDU in in all of ui_rx_q and check rx congestion status */
+                llcp_cb.total_rx_ui_pdu--;
+                llcp_util_check_rx_congested_status ();
+            }
+        }
+
+        /* if there is more UI PDU in rx queue */
+        if (p_app_cb->ui_rx_q.p_first)
+        {
+            return (TRUE);
+        }
+        else
+        {
+            return (FALSE);
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_ReadLogicalLinkData (): Unregistered SAP:0x%x", local_sap);
+
+        return (FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushLogicalLinkRxData
+**
+** Description      Discard received data in logical data link of local SAP
+**
+**
+** Returns          length of data flushed
+**
+*******************************************************************************/
+UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap)
+{
+    BT_HDR       *p_buf;
+    UINT32       flushed_length = 0;
+    tLLCP_APP_CB *p_app_cb;
+    UINT8        *p_ui_pdu;
+    UINT16       ui_pdu_length;
+
+    LLCP_TRACE_API1 ("LLCP_FlushLogicalLinkRxData () Local SAP:0x%x", local_sap);
+
+    p_app_cb = llcp_util_get_app_cb (local_sap);
+
+    /* if application is registered */
+    if ((p_app_cb) && (p_app_cb->p_app_cback))
+    {
+        /* if any UI PDU in rx queue */
+        while (p_app_cb->ui_rx_q.p_first)
+        {
+            p_buf    = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
+            p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+            /* get length of UI PDU */
+            BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
+
+            flushed_length += (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
+
+            /* move to next UI PDU if any */
+            p_buf->layer_specific = 0;  /* offset */
+            p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+            p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+
+            /* if read all of UI PDU */
+            if (p_buf->len == 0)
+            {
+                GKI_dequeue (&p_app_cb->ui_rx_q);
+                GKI_freebuf (p_buf);
+                llcp_cb.total_rx_ui_pdu--;
+            }
+        }
+
+        /* number of received UI PDU is decreased so check rx congestion status */
+        llcp_util_check_rx_congested_status ();
+    }
+    else
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_FlushLogicalLinkRxData (): Unregistered SAP:0x%x", local_sap);
+    }
+
+    return (flushed_length);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReq
+**
+** Description      Create data link connection between registered SAP and DSAP
+**                  in peer LLCP,
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectReq (UINT8                    reg_sap,
+                              UINT8                    dsap,
+                              tLLCP_CONNECTION_PARAMS *p_params)
+{
+    tLLCP_DLCB   *p_dlcb;
+    tLLCP_STATUS status;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
+
+    if (  (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
+        &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)  )
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
+        return LLCP_STATUS_FAIL;
+    }
+
+    p_app_cb = llcp_util_get_app_cb (reg_sap);
+
+    /* if application is registered */
+    if (  (p_app_cb == NULL)
+        ||(p_app_cb->p_app_cback == NULL)  )
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
+        return LLCP_STATUS_FAIL;
+    }
+
+    if (dsap == LLCP_SAP_LM)
+    {
+        LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
+        return LLCP_STATUS_FAIL;
+    }
+
+    if (dsap == LLCP_SAP_SDP)
+    {
+        if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
+        {
+            LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
+                               strlen (p_params->sn));
+            return LLCP_STATUS_FAIL;
+        }
+    }
+
+    if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
+        return LLCP_STATUS_FAIL;
+    }
+
+    /* check if any pending connection request on this reg_sap */
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
+    if (p_dlcb)
+    {
+        /*
+        ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
+        ** if there is multiple pending connection request on the same local SAP.
+        */
+        LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
+        return LLCP_STATUS_FAIL;
+    }
+
+    p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
+
+    if (p_dlcb)
+    {
+        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
+        if (status != LLCP_STATUS_SUCCESS)
+        {
+            LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
+            llcp_util_deallocate_data_link (p_dlcb);
+            return LLCP_STATUS_FAIL;
+        }
+    }
+    else
+    {
+        return LLCP_STATUS_FAIL;
+    }
+
+    return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectCfm
+**
+** Description      Accept connection request from peer LLCP
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectCfm (UINT8                    local_sap,
+                              UINT8                    remote_sap,
+                              tLLCP_CONNECTION_PARAMS *p_params)
+{
+    tLLCP_STATUS  status;
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
+                     local_sap, remote_sap);
+
+    if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
+        return LLCP_STATUS_FAIL;
+    }
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
+        status = LLCP_STATUS_FAIL;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ConnectReject
+**
+** Description      Reject connection request from peer LLCP
+**
+**                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
+**                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_FAIL, otherwise
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
+                                 UINT8 remote_sap,
+                                 UINT8 reason)
+{
+    tLLCP_STATUS  status;
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
+                     local_sap, remote_sap, reason);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
+        llcp_util_deallocate_data_link (p_dlcb);
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
+        status = LLCP_STATUS_FAIL;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_IsDataLinkCongested
+**
+** Description      Check if data link connection is congested
+**
+**
+** Returns          TRUE if congested
+**
+*******************************************************************************/
+BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
+                                  UINT8 remote_sap,
+                                  UINT8 num_pending_i_pdu,
+                                  UINT8 total_pending_ui_pdu,
+                                  UINT8 total_pending_i_pdu)
+{
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
+                     local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        if (  (p_dlcb->is_tx_congested)
+            ||(p_dlcb->remote_busy)  )
+        {
+            return (TRUE);
+        }
+        else if (  (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
+                 ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)  )
+        {
+            /* set flag so LLCP can notify uncongested status later */
+            p_dlcb->is_tx_congested = TRUE;
+            return (TRUE);
+        }
+        return (FALSE);
+    }
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SendData
+**
+** Description      Send connection-oriented data
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**                  LLCP_STATUS_CONGESTED if data link is congested
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SendData (UINT8   local_sap,
+                            UINT8   remote_sap,
+                            BT_HDR *p_buf)
+{
+    tLLCP_STATUS  status = LLCP_STATUS_FAIL;
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
+                     local_sap, remote_sap);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        if (p_dlcb->remote_miu >= p_buf->len)
+        {
+            if (p_buf->offset >= LLCP_MIN_OFFSET)
+            {
+                status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
+            }
+            else
+            {
+                LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
+                                    p_buf->offset, LLCP_MIN_OFFSET );
+            }
+        }
+        else
+        {
+            LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
+                                p_buf->len, p_dlcb->remote_miu);
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
+    }
+
+    if (status == LLCP_STATUS_FAIL)
+    {
+        GKI_freebuf (p_buf);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_ReadDataLinkData
+**
+** Description      Read information of I PDU for data link connection
+**
+**                  - Information of I PDU up to max_data_len is copied into p_data.
+**                  - Information of next I PDU is not concatenated.
+**                  - Recommended max_data_len is data link connection MIU of local
+**                    end point
+**
+** Returns          TRUE if more data in queue
+**
+*******************************************************************************/
+BOOLEAN LLCP_ReadDataLinkData (UINT8  local_sap,
+                               UINT8  remote_sap,
+                               UINT32 max_data_len,
+                               UINT32 *p_data_len,
+                               UINT8  *p_data)
+{
+    tLLCP_DLCB *p_dlcb;
+    BT_HDR     *p_buf;
+    UINT8      *p_i_pdu;
+    UINT16     i_pdu_length;
+
+    LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
+                      local_sap, remote_sap);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    *p_data_len = 0;
+    if (p_dlcb)
+    {
+        /* if any I PDU in rx queue */
+        if (p_dlcb->i_rx_q.p_first)
+        {
+            p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
+            p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+            /* get length of I PDU */
+            BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
+
+            /* layer_specific has the offset to read within I PDU */
+            p_i_pdu += p_buf->layer_specific;
+
+            /* copy data up to max_data_len */
+            if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
+            {
+                /* copy information */
+                *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
+
+                /* move to next I PDU if any */
+                p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next I PDU */
+                p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+                p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+            }
+            else
+            {
+                *p_data_len = max_data_len;
+
+                /* update offset to read from remaining I PDU next time */
+                p_buf->layer_specific += max_data_len;
+            }
+
+            memcpy (p_data, p_i_pdu, *p_data_len);
+
+            if (p_buf->layer_specific == 0)
+            {
+                p_dlcb->num_rx_i_pdu--;
+            }
+
+            /* if read all of I PDU */
+            if (p_buf->len == 0)
+            {
+                GKI_dequeue (&p_dlcb->i_rx_q);
+                GKI_freebuf (p_buf);
+
+                /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
+                llcp_cb.total_rx_i_pdu--;
+                llcp_util_check_rx_congested_status ();
+            }
+        }
+
+        /* if getting out of rx congestion */
+        if (  (!p_dlcb->local_busy)
+            &&(p_dlcb->is_rx_congested)
+            &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)  )
+        {
+            /* send RR */
+            p_dlcb->is_rx_congested = FALSE;
+            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+        }
+
+        /* if there is more I PDU in rx queue */
+        if (p_dlcb->i_rx_q.p_first)
+        {
+            return (TRUE);
+        }
+        else
+        {
+            return (FALSE);
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
+
+        return (FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_FlushDataLinkRxData
+**
+** Description      Discard received data in data link connection
+**
+**
+** Returns          length of rx data flushed
+**
+*******************************************************************************/
+UINT32 LLCP_FlushDataLinkRxData (UINT8  local_sap,
+                                 UINT8  remote_sap)
+{
+    tLLCP_DLCB *p_dlcb;
+    BT_HDR     *p_buf;
+    UINT32     flushed_length = 0;
+    UINT8      *p_i_pdu;
+    UINT16     i_pdu_length;
+
+    LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
+                      local_sap, remote_sap);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        /* if any I PDU in rx queue */
+        while (p_dlcb->i_rx_q.p_first)
+        {
+            p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
+            p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
+
+            /* get length of I PDU */
+            BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
+
+            flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
+
+            /* move to next I PDU if any */
+            p_buf->layer_specific = 0;  /* offset */
+            p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+            p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
+
+            /* if read all of I PDU */
+            if (p_buf->len == 0)
+            {
+                GKI_dequeue (&p_dlcb->i_rx_q);
+                GKI_freebuf (p_buf);
+                llcp_cb.total_rx_i_pdu--;
+            }
+        }
+
+        p_dlcb->num_rx_i_pdu = 0;
+
+        /* if getting out of rx congestion */
+        if (  (!p_dlcb->local_busy)
+            &&(p_dlcb->is_rx_congested)  )
+        {
+            /* send RR */
+            p_dlcb->is_rx_congested = FALSE;
+            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+        }
+
+        /* number of received I PDU is decreased so check rx congestion status */
+        llcp_util_check_rx_congested_status ();
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
+    }
+
+    return (flushed_length);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_DisconnectReq
+**
+** Description      Disconnect data link
+**                  discard any pending data if flush is set to TRUE
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
+                                 UINT8 remote_sap,
+                                 BOOLEAN flush)
+{
+    tLLCP_STATUS  status;
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
+                     local_sap, remote_sap, flush);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
+        status = LLCP_STATUS_FAIL;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTxCompleteNtf
+**
+** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
+**                  when Tx queue is empty and all PDU is acked.
+**                  This is one time event, so upper layer shall call this function
+**                  again to get next LLCP_SERVICE_TX_COMPLETE.
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8   local_sap,
+                                    UINT8   remote_sap)
+{
+    tLLCP_STATUS  status;
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
+                      local_sap, remote_sap);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        /* set flag to notify upper later when tx complete */
+        p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
+        status = LLCP_STATUS_SUCCESS;
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
+        status = LLCP_STATUS_FAIL;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetLocalBusyStatus
+**
+** Description      Set local busy status
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8   local_sap,
+                                      UINT8   remote_sap,
+                                      BOOLEAN is_busy)
+{
+    tLLCP_STATUS  status;
+    tLLCP_DLCB   *p_dlcb;
+
+    LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
+                      local_sap, is_busy);
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
+
+    if (p_dlcb)
+    {
+        if (p_dlcb->local_busy != is_busy)
+        {
+            p_dlcb->local_busy = is_busy;
+
+            /* send RR or RNR with valid sequence */
+            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+
+            if (is_busy == FALSE)
+            {
+                if (p_dlcb->i_rx_q.count)
+                {
+                    llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
+                }
+            }
+        }
+        status = LLCP_STATUS_SUCCESS;
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
+        status = LLCP_STATUS_FAIL;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteWKS
+**
+** Description      Return well-known service bitmap of connected device
+**
+**
+** Returns          WKS bitmap if success
+**
+*******************************************************************************/
+UINT16 LLCP_GetRemoteWKS (void)
+{
+    LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
+                     (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
+
+    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+        return (llcp_cb.lcb.peer_wks);
+    else
+        return (0);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetRemoteLSC
+**
+** Description      Return link service class of connected device
+**
+**
+** Returns          link service class
+**
+*******************************************************************************/
+UINT8 LLCP_GetRemoteLSC (void)
+{
+    LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
+                     (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+                     ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
+
+    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+        return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
+    else
+        return (LLCP_LSC_UNKNOWN);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_GetLinkMIU
+**
+** Description      Return local and remote link MIU
+**
+**
+** Returns          None
+**
+*******************************************************************************/
+LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
+                               UINT16 *p_remote_link_miu)
+{
+    LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
+
+    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+    {
+        *p_local_link_miu  = llcp_cb.lcb.local_link_miu;
+        *p_remote_link_miu = llcp_cb.lcb.effective_miu;
+    }
+    else
+    {
+        *p_local_link_miu  = 0;
+        *p_remote_link_miu = 0;
+    }
+
+    LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
+                       *p_local_link_miu, *p_remote_link_miu);
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_DiscoverService
+**
+** Description      Return SAP of service name in connected device through callback
+**
+**
+** Returns          LLCP_STATUS_SUCCESS if success
+**
+*******************************************************************************/
+tLLCP_STATUS LLCP_DiscoverService (char            *p_name,
+                                   tLLCP_SDP_CBACK *p_cback,
+                                   UINT8           *p_tid)
+{
+    tLLCP_STATUS  status;
+    UINT8         i;
+
+    LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
+                      p_name);
+
+    if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
+        return LLCP_STATUS_FAIL;
+    }
+
+    if (!p_cback)
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
+        return LLCP_STATUS_FAIL;
+    }
+
+    /* if peer version is less than V1.1 then SNL is not supported */
+    if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
+    {
+        LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
+        return LLCP_STATUS_FAIL;
+    }
+
+    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
+    {
+        if (!llcp_cb.sdp_cb.transac[i].p_cback)
+        {
+            llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
+            llcp_cb.sdp_cb.next_tid++;
+            llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
+
+            status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
+
+            if (status == LLCP_STATUS_FAIL)
+            {
+                llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+            }
+
+            *p_tid = llcp_cb.sdp_cb.transac[i].tid;
+            return (status);
+        }
+    }
+
+    LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
+
+    return LLCP_STATUS_FAIL;
+}
+
diff --git a/src/nfc/llcp/llcp_dlc.c b/src/nfc/llcp/llcp_dlc.c
new file mode 100644
index 0000000..ee9eb6c
--- /dev/null
+++ b/src/nfc/llcp/llcp_dlc.c
@@ -0,0 +1,1475 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP Data Link Connection Management
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state);
+static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event);
+#endif
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_execute
+**
+** Description      This function executes the state machine for data link connection.
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+    tLLCP_STATUS status;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %s, evt: %s",
+                        p_dlcb->local_sap,
+                        llcp_dlsm_get_state_name (p_dlcb->state),
+                        llcp_dlsm_get_event_name (event));
+#else
+    LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %d, evt: %d", p_dlcb->local_sap, p_dlcb->state, event);
+#endif
+
+    switch (p_dlcb->state)
+    {
+    case LLCP_DLC_STATE_IDLE:
+        status = llcp_dlsm_idle (p_dlcb, event, p_data);
+        break;
+
+    case LLCP_DLC_STATE_W4_REMOTE_RESP:
+        status = llcp_dlsm_w4_remote_resp (p_dlcb, event, p_data);
+        break;
+
+    case LLCP_DLC_STATE_W4_LOCAL_RESP:
+        status = llcp_dlsm_w4_local_resp (p_dlcb, event, p_data);
+        break;
+
+    case LLCP_DLC_STATE_CONNECTED:
+        status = llcp_dlsm_connected (p_dlcb, event, p_data);
+        break;
+
+    case LLCP_DLC_STATE_W4_REMOTE_DM:
+        status = llcp_dlsm_w4_remote_dm (p_dlcb, event, p_data);
+        break;
+
+    default:
+        status = LLCP_STATUS_FAIL;
+        break;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_idle
+**
+** Description      Data link connection is in idle state
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+    tLLCP_STATUS            status = LLCP_STATUS_SUCCESS;
+    tLLCP_SAP_CBACK_DATA    data;
+    tLLCP_CONNECTION_PARAMS *p_params;
+
+    switch (event)
+    {
+    case LLCP_DLC_EVENT_API_CONNECT_REQ:
+
+        /* upper layer requests to create data link connection */
+        p_params = (tLLCP_CONNECTION_PARAMS *)p_data;
+
+        status = llcp_util_send_connect (p_dlcb, p_params);
+
+        if (status == LLCP_STATUS_SUCCESS)
+        {
+            p_dlcb->local_miu = p_params->miu;
+            p_dlcb->local_rw  = p_params->rw;
+
+            /* wait for response from peer device */
+            p_dlcb->state     = LLCP_DLC_STATE_W4_REMOTE_RESP;
+
+            nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+                                   (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        }
+        break;
+
+    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
+
+        /* peer device requests to create data link connection */
+        p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
+
+        if (p_params->miu > llcp_cb.lcb.peer_miu)
+        {
+            LLCP_TRACE_WARNING0 ("llcp_dlsm_idle (): Peer sent data link MIU bigger than peer's link MIU");
+            p_params->miu = llcp_cb.lcb.peer_miu;
+        }
+
+        data.connect_ind.event          = LLCP_SAP_EVT_CONNECT_IND;
+        data.connect_ind.remote_sap     = p_dlcb->remote_sap;
+        data.connect_ind.local_sap      = p_dlcb->local_sap;
+        data.connect_ind.miu            = p_params->miu;
+        data.connect_ind.rw             = p_params->rw;
+        data.connect_ind.p_service_name = p_params->sn;
+        data.connect_ind.server_sap     = p_dlcb->local_sap;
+
+        p_dlcb->remote_miu = p_params->miu;
+        p_dlcb->remote_rw  = p_params->rw;
+
+        LLCP_TRACE_DEBUG2 ("llcp_dlsm_idle (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
+
+        /* wait for response from upper layer */
+        p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
+
+        nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+                               (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        break;
+
+    default:
+        LLCP_TRACE_ERROR0 ("llcp_dlsm_idle (): Unexpected event");
+        status = LLCP_STATUS_FAIL;
+        break;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_w4_remote_resp
+**
+** Description      data link connection is waiting for connection confirm from peer
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+    tLLCP_STATUS            status = LLCP_STATUS_SUCCESS;
+    tLLCP_SAP_CBACK_DATA    data;
+    tLLCP_CONNECTION_PARAMS *p_params;
+
+    switch (event)
+    {
+    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
+
+        /* peer device accepted data link connection */
+        nfc_stop_quick_timer (&p_dlcb->timer);
+
+        p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
+
+        /* data link MIU must be up to link MIU */
+        if (p_params->miu > llcp_cb.lcb.peer_miu)
+        {
+            LLCP_TRACE_WARNING0 ("llcp_dlsm_w4_remote_resp (): Peer sent data link MIU bigger than peer's link MIU");
+            p_params->miu = llcp_cb.lcb.peer_miu;
+        }
+
+        p_dlcb->remote_miu = p_params->miu;
+        p_dlcb->remote_rw  = p_params->rw;
+
+        LLCP_TRACE_DEBUG2 ("llcp_dlsm_w4_remote_resp (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
+
+        p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
+        llcp_util_adjust_dl_rx_congestion ();
+
+        data.connect_resp.event          = LLCP_SAP_EVT_CONNECT_RESP;
+        data.connect_resp.remote_sap     = p_dlcb->remote_sap;
+        data.connect_resp.local_sap      = p_dlcb->local_sap;
+        data.connect_resp.miu            = p_params->miu;
+        data.connect_resp.rw             = p_params->rw;
+
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        if (llcp_cb.overall_rx_congested)
+        {
+            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+        }
+        break;
+
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+    case LLCP_DLC_EVENT_TIMEOUT:
+
+        /* peer device rejected connection or didn't respond */
+        data.disconnect_resp.event       = LLCP_SAP_EVT_DISCONNECT_RESP;
+        data.disconnect_resp.local_sap   = p_dlcb->local_sap;
+        data.disconnect_resp.remote_sap  = p_dlcb->remote_sap;
+        data.disconnect_resp.reason      = *((UINT8*) p_data);
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        /* stop timer, flush any pending data in queue and deallocate control block */
+        llcp_util_deallocate_data_link (p_dlcb);
+
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+        /* received bad frame or link is deactivated */
+        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
+        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
+        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    default:
+        LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_resp (): Unexpected event");
+        status = LLCP_STATUS_FAIL;
+        break;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_w4_local_resp
+**
+** Description      data link connection is waiting for connection confirm from application
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+    tLLCP_STATUS             status = LLCP_STATUS_SUCCESS;
+    tLLCP_CONNECTION_PARAMS *p_params;
+    tLLCP_SAP_CBACK_DATA     data;
+    UINT8                    reason;
+
+    switch (event)
+    {
+    case LLCP_DLC_EVENT_API_CONNECT_CFM:
+
+        /* upper layer accepted data link connection */
+        nfc_stop_quick_timer (&p_dlcb->timer);
+
+        p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
+
+        p_dlcb->local_miu = p_params->miu;
+        p_dlcb->local_rw  = p_params->rw;
+
+        p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
+
+        if (llcp_cb.overall_rx_congested)
+        {
+            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+        }
+
+        status = llcp_util_send_cc (p_dlcb, p_params);
+
+        if (status == LLCP_STATUS_SUCCESS)
+        {
+            llcp_util_adjust_dl_rx_congestion ();
+        }
+        else
+        {
+            data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
+            data.disconnect_ind.local_sap   = p_dlcb->local_sap;
+            data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
+            (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+            llcp_util_deallocate_data_link (p_dlcb);
+        }
+        break;
+
+    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
+    case LLCP_DLC_EVENT_TIMEOUT:
+
+        if (event == LLCP_DLC_EVENT_TIMEOUT)
+            reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
+        else
+            reason = *((UINT8*) p_data);
+
+        /* upper layer rejected connection or didn't respond */
+        llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, reason);
+
+        /* stop timer, flush any pending data in queue and deallocate control block */
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+        /* received bad frame or link is deactivated */
+        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
+        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
+        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    default:
+        LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_local_resp (): Unexpected event");
+        status = LLCP_STATUS_FAIL;
+        break;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_connected
+**
+** Description      data link connection is connected
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+    BOOLEAN              flush;
+    tLLCP_STATUS         status = LLCP_STATUS_SUCCESS;
+    tLLCP_SAP_CBACK_DATA data;
+
+    switch (event)
+    {
+    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
+
+        /* upper layer requests to disconnect */
+        flush = *(BOOLEAN*) (p_data);
+
+        /*
+        ** if upper layer asks to discard any pending data
+        ** or there is no pending data/ack to send and it is not waiting for ack
+        */
+        if (  (flush)
+            ||(  (p_dlcb->i_xmit_q.count == 0)
+               &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
+               &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )  )
+        {
+            /* wait for disconnect response */
+            p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
+
+            llcp_util_send_disc (p_dlcb->remote_sap, p_dlcb->local_sap );
+
+            nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
+                                   (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        }
+        else
+        {
+            /* set flag to send DISC when tx queue is empty */
+            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
+        }
+        break;
+
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+
+        /* peer device requests to disconnect */
+
+        /* send disconnect response and notify upper layer */
+        llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
+
+        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
+        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
+        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    case LLCP_DLC_EVENT_API_DATA_REQ:
+
+        /* upper layer requests to send data */
+
+        /* if peer device can receive data */
+        if (p_dlcb->remote_rw)
+        {
+            /* enqueue data and check if data can be sent */
+            GKI_enqueue (&p_dlcb->i_xmit_q, p_data);
+            llcp_cb.total_tx_i_pdu++;
+
+            llcp_link_check_send_data ();
+
+            if (  (p_dlcb->is_tx_congested)
+                ||(llcp_cb.overall_tx_congested)
+                ||(p_dlcb->remote_busy)
+                ||(p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)  ) /*if enough data to send next round */
+            {
+                LLCP_TRACE_DEBUG3 ("llcp_dlsm_connected (): Data link (SSAP:DSAP=0x%X:0x%X) congested: xmit_q.count=%d",
+                                    p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
+
+                /* set congested here so overall congestion check routine will not report event again */
+                p_dlcb->is_tx_congested = TRUE;
+                status = LLCP_STATUS_CONGESTED;
+            }
+        }
+        else
+        {
+            LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Remote RW is zero: discard data");
+            /* buffer will be freed when returned to API function */
+            status = LLCP_STATUS_FAIL;
+        }
+        break;
+
+    case LLCP_DLC_EVENT_PEER_DATA_IND:
+        /* peer device sends data so notify upper layer to read data from data link connection */
+
+        data.data_ind.event         = LLCP_SAP_EVT_DATA_IND;
+        data.data_ind.local_sap     = p_dlcb->local_sap;
+        data.data_ind.link_type     = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+        data.data_ind.remote_sap    = p_dlcb->remote_sap;
+
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+        break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+        /* received bad frame or link is deactivated */
+        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
+        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
+        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    default:
+        LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Unexpected event");
+        status = LLCP_STATUS_FAIL;
+        break;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_w4_remote_dm
+**
+** Description      data link connection is waiting for disconnection confirm from peer
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
+{
+    tLLCP_STATUS         status = LLCP_STATUS_SUCCESS;
+    tLLCP_SAP_CBACK_DATA data;
+
+    switch (event)
+    {
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+    case LLCP_DLC_EVENT_TIMEOUT:
+
+        /* peer device sends disconnect response or didn't responde */
+        data.disconnect_resp.event       = LLCP_SAP_EVT_DISCONNECT_RESP;
+        data.disconnect_resp.local_sap   = p_dlcb->local_sap;
+        data.disconnect_resp.remote_sap  = p_dlcb->remote_sap;
+        data.disconnect_resp.reason      = LLCP_SAP_DM_REASON_RESP_DISC;
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+    case LLCP_DLC_EVENT_LINK_ERROR:
+
+        /* received bad frame or link is deactivated */
+        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
+        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
+        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
+        (*p_dlcb->p_app_cb->p_app_cback) (&data);
+
+        llcp_util_deallocate_data_link (p_dlcb);
+        llcp_util_adjust_dl_rx_congestion ();
+        break;
+
+    case LLCP_DLC_EVENT_PEER_DATA_IND:
+        break;
+
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+        /* it's race condition, send disconnect response and wait for DM */
+        llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
+        break;
+
+    default:
+        LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_dm (): Unexpected event");
+        status = LLCP_STATUS_FAIL;
+        break;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_find_dlcb_by_local_sap
+**
+** Description      Find tLLCP_DLCB by local SAP and remote SAP
+**                  if remote_sap is LLCP_INVALID_SAP, it will return a DLCB which
+**                  is waiting for CC from peer.
+**
+** Returns          tLLCP_DLCB *
+**
+*******************************************************************************/
+tLLCP_DLCB *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap)
+{
+    int i;
+
+    for (i = 0; i < LLCP_MAX_DATA_LINK; i++)
+    {
+        if (  (llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE)
+            &&(llcp_cb.dlcb[i].local_sap == local_sap)  )
+        {
+            if ((remote_sap == LLCP_INVALID_SAP) && (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP))
+            {
+                /* Remote SAP has not been finalized because we are watiing for CC */
+                return (&llcp_cb.dlcb[i]);
+            }
+            else if (llcp_cb.dlcb[i].remote_sap == remote_sap)
+            {
+                return (&llcp_cb.dlcb[i]);
+            }
+        }
+    }
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_flush_q
+**
+** Description      Free buffers in tx and rx queue in data link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb)
+{
+    if (p_dlcb)
+    {
+        LLCP_TRACE_DEBUG1 ("llcp_dlc_flush_q (): local SAP:0x%02X", p_dlcb->local_sap);
+
+        /* Release any held buffers */
+        while (p_dlcb->i_xmit_q.p_first)
+        {
+            GKI_freebuf (GKI_dequeue (&p_dlcb->i_xmit_q));
+            llcp_cb.total_tx_i_pdu--;
+        }
+
+        /* discard any received I PDU on data link  including in AGF */
+        LLCP_FlushDataLinkRxData (p_dlcb->local_sap, p_dlcb->remote_sap);
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("llcp_dlc_flush_q (): p_dlcb is NULL");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_connect_pdu
+**
+** Description      Process CONNECT PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_connect_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+    tLLCP_DLCB   *p_dlcb;
+    tLLCP_STATUS  status;
+    tLLCP_APP_CB *p_app_cb;
+
+    tLLCP_CONNECTION_PARAMS  params;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_connect_pdu ()");
+
+    p_app_cb = llcp_util_get_app_cb (dsap);
+
+    if (  (p_app_cb == NULL)
+        ||(p_app_cb->p_app_cback == NULL)
+        ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)  )
+    {
+        LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered SAP:0x%x", dsap);
+        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
+        return;
+    }
+
+    /* parse CONNECT PDU and get connection parameters */
+    if (llcp_util_parse_connect (p_data, length, &params) != LLCP_STATUS_SUCCESS)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Bad format CONNECT");
+        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
+        return;
+    }
+
+    /* if this is connection by service name */
+    if (dsap == LLCP_SAP_SDP)
+    {
+        /* find registered SAP with service name */
+        if (strlen (params.sn))
+            dsap = llcp_sdp_get_sap_by_name (params.sn, (UINT8) strlen (params.sn));
+        else
+        {
+            llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
+            return;
+        }
+        if (dsap == LLCP_SAP_SDP)
+        {
+            LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
+
+            llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
+            return;
+        }
+        else if (dsap == 0)
+        {
+            LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s", params.sn);
+
+            llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
+            return;
+        }
+    }
+
+    /* check if any data link */
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+    if (p_dlcb)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Data link is aleady established");
+        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
+    }
+    else
+    {
+        /* allocate data link connection control block and notify upper layer through state machine */
+        p_dlcb = llcp_util_allocate_data_link (dsap, ssap);
+
+        if (p_dlcb)
+        {
+            status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
+            if (status != LLCP_STATUS_SUCCESS)
+            {
+                LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
+                llcp_util_deallocate_data_link (p_dlcb);
+            }
+        }
+        else
+        {
+            LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
+            llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_disc_pdu
+**
+** Description      Process DISC PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+    tLLCP_DLCB *p_dlcb;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+    if (p_dlcb)
+    {
+        if (length > 0)
+        {
+            LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
+
+            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        }
+        else
+        {
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_cc_pdu
+**
+** Description      Process CC PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+    tLLCP_DLCB              *p_dlcb;
+    tLLCP_CONNECTION_PARAMS  params;
+    tLLCP_STATUS             status;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
+
+    /* find a DLCB waiting for CC on this local SAP */
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
+    if (p_dlcb)
+    {
+        /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
+        p_dlcb->remote_sap = ssap;
+
+        if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
+        {
+            status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
+            if (status != LLCP_STATUS_SUCCESS)
+            {
+                LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
+                llcp_util_deallocate_data_link (p_dlcb);
+            }
+        }
+        else
+        {
+            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_dm_pdu
+**
+** Description      Process DM PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+    tLLCP_DLCB *p_dlcb;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
+
+    if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
+    }
+    else
+    {
+        if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
+        {
+            /* local device initiated disconnecting */
+            p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+        }
+        else
+        {
+            /* peer device rejected connection with any reason */
+            /* find a DLCB waiting for CC on this local SAP    */
+            p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
+        }
+
+        if (p_dlcb)
+        {
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
+        }
+        else
+        {
+            LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_i_pdu
+**
+** Description      Process I PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
+{
+    UINT8      *p, *p_dst, send_seq, rcv_seq, error_flags;
+    UINT16      info_len, available_bytes;
+    tLLCP_DLCB *p_dlcb;
+    BOOLEAN     appended;
+    BT_HDR     *p_last_buf;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+
+    if (p_dlcb)
+    {
+        error_flags = 0;
+
+        if (p_msg)
+        {
+            i_pdu_length = p_msg->len;
+            p_i_pdu = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        }
+
+        info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
+
+        if (info_len > p_dlcb->local_miu)
+        {
+            LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
+                                p_dlcb->local_miu, info_len);
+
+            error_flags |= LLCP_FRMR_I_ERROR_FLAG;
+        }
+
+        /* get sequence numbers */
+        p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
+
+        send_seq = LLCP_GET_NS (*p);
+        rcv_seq  = LLCP_GET_NR (*p);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+        LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                            send_seq, rcv_seq,
+                            p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+                            p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+
+        /* if send sequence number, N(S) is not expected one, V(R) */
+        if (p_dlcb->next_rx_seq != send_seq)
+        {
+            LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
+                                send_seq, p_dlcb->next_rx_seq);
+
+            error_flags |= LLCP_FRMR_S_ERROR_FLAG;
+        }
+        else
+        {
+            /* if peer device sends more than our receiving window size */
+            if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
+            {
+                LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
+                                    send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
+
+                error_flags |= LLCP_FRMR_S_ERROR_FLAG;
+            }
+        }
+
+        /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
+        if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
+            != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
+        {
+            error_flags |= LLCP_FRMR_R_ERROR_FLAG;
+            LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
+                                rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
+        }
+
+        /* if any error is found */
+        if (error_flags)
+        {
+            llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        }
+        else
+        {
+            /* update local sequence variables */
+            p_dlcb->next_rx_seq  = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
+            p_dlcb->rcvd_ack_seq = rcv_seq;
+
+            appended = FALSE;
+
+            /* get last buffer in rx queue */
+            p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
+
+            if (p_last_buf)
+            {
+                /* get max length to append at the end of buffer */
+                available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
+
+                /* if new UI PDU with length can be attached at the end of buffer */
+                if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
+                {
+                    p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
+
+                    /* add length of information in I PDU */
+                    UINT16_TO_BE_STREAM (p_dst, info_len);
+
+                    /* copy information of I PDU */
+                    p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+
+                    memcpy (p_dst, p, info_len);
+
+                    p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
+
+                    if (p_msg)
+                    {
+                        GKI_freebuf (p_msg);
+                        p_msg = NULL;
+                    }
+
+                    appended = TRUE;
+                }
+            }
+
+            /* if it is not available to append */
+            if (!appended)
+            {
+                /* if it's not from AGF PDU */
+                if (p_msg)
+                {
+                    /* add length of information in front of information */
+                    p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+                    UINT16_TO_BE_STREAM (p, info_len);
+
+                    p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+                    p_msg->len    -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
+                    p_msg->layer_specific = 0;
+                }
+                else
+                {
+                    p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+                    if (p_msg)
+                    {
+                        p_dst = (UINT8*) (p_msg + 1);
+
+                        /* add length of information in front of information */
+                        UINT16_TO_BE_STREAM (p_dst, info_len);
+
+                        p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+                        memcpy (p_dst, p, info_len);
+
+                        p_msg->offset = 0;
+                        p_msg->len    = LLCP_PDU_AGF_LEN_SIZE + info_len;
+                        p_msg->layer_specific = 0;
+                    }
+                    else
+                    {
+                        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
+                    }
+                }
+
+                /* insert I PDU in rx queue */
+                if (p_msg)
+                {
+                    GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
+                    p_msg = NULL;
+                    llcp_cb.total_rx_i_pdu++;
+
+                    llcp_util_check_rx_congested_status ();
+                }
+            }
+
+            p_dlcb->num_rx_i_pdu++;
+
+            if (  (!p_dlcb->local_busy)
+                &&(p_dlcb->num_rx_i_pdu == 1)  )
+            {
+                /* notify rx data is available so upper layer reads data until queue is empty */
+                llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
+            }
+
+            if (  (!p_dlcb->is_rx_congested)
+                &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)  )
+            {
+                LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
+                                    p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
+
+                /* send RNR */
+                p_dlcb->is_rx_congested = TRUE;
+                p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+            }
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
+    }
+
+    if (p_msg)
+    {
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_rr_rnr_pdu
+**
+** Description      Process RR or RNR PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+    UINT8      rcv_seq, error_flags;
+    tLLCP_DLCB *p_dlcb;
+    BOOLEAN     flush = TRUE;
+    tLLCP_SAP_CBACK_DATA cback_data;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
+
+    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+    if (p_dlcb != NULL)
+    {
+        error_flags = 0;
+
+        rcv_seq = LLCP_GET_NR (*p_data);
+
+        if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
+        {
+            error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
+        }
+
+        /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
+        if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
+            != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
+        {
+            error_flags |= LLCP_FRMR_R_ERROR_FLAG;
+            LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
+                                rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
+        }
+
+        if (error_flags)
+        {
+            llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        }
+        else
+        {
+            p_dlcb->rcvd_ack_seq = rcv_seq;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+            LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                                rcv_seq,
+                                p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+                                p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+
+            if (ptype == LLCP_PDU_RNR_TYPE)
+            {
+                /* if upper layer hasn't get congestion started notification */
+                if (  (!p_dlcb->remote_busy)
+                    &&(!p_dlcb->is_tx_congested)  )
+                {
+                    LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
+                                          p_dlcb->local_sap, p_dlcb->remote_sap,
+                                          p_dlcb->i_xmit_q.count);
+
+                    cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
+                    cback_data.congest.local_sap    = p_dlcb->local_sap;
+                    cback_data.congest.remote_sap   = p_dlcb->remote_sap;
+                    cback_data.congest.is_congested = TRUE;
+                    cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+                    (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
+                }
+                p_dlcb->remote_busy = TRUE;
+            }
+            else
+            {
+                /* if upper layer hasn't get congestion ended notification and data link is not congested */
+                if (  (p_dlcb->remote_busy)
+                    &&(!p_dlcb->is_tx_congested)  )
+                {
+                    LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
+                                          p_dlcb->local_sap, p_dlcb->remote_sap,
+                                          p_dlcb->i_xmit_q.count);
+
+                    cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
+                    cback_data.congest.local_sap    = p_dlcb->local_sap;
+                    cback_data.congest.remote_sap   = p_dlcb->remote_sap;
+                    cback_data.congest.is_congested = FALSE;
+                    cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+                    (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
+                }
+                p_dlcb->remote_busy = FALSE;
+            }
+
+            /* check flag to send DISC when tx queue is empty */
+            if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
+            {
+                /* if no pending data and all PDU is acked */
+                if (  (p_dlcb->i_xmit_q.count == 0)
+                    &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
+                    &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
+                {
+                    p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+                    llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+                }
+            }
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_proc_rx_pdu
+**
+** Description      Process PDU for data link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
+{
+    tLLCP_DLCB *p_dlcb;
+
+    LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
+                        dsap, ptype, ssap);
+
+    if (dsap == LLCP_SAP_LM)
+    {
+        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
+        return;
+    }
+
+    switch (ptype)
+    {
+    case LLCP_PDU_CONNECT_TYPE:
+        llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
+        break;
+
+    case LLCP_PDU_DISC_TYPE:
+        llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
+        break;
+
+    case LLCP_PDU_CC_TYPE:
+        llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
+        break;
+
+    case LLCP_PDU_DM_TYPE:
+        llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
+        break;
+
+    case LLCP_PDU_FRMR_TYPE:
+        p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+        if (p_dlcb)
+        {
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        }
+        break;
+
+    case LLCP_PDU_RR_TYPE:
+    case LLCP_PDU_RNR_TYPE:
+        llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
+        break;
+
+    default:
+        LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
+
+        p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
+        if (p_dlcb)
+        {
+            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        }
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_check_to_send_rr_rnr
+**
+** Description      Send RR or RNR if necessary
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_dlc_check_to_send_rr_rnr (void)
+{
+    UINT8   idx;
+    BOOLEAN flush = TRUE;
+
+    LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
+
+    /*
+    ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
+    ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
+    ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
+    **
+    ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
+    ** V(R).
+    */
+    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+    {
+        if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+        {
+            llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
+
+            /* check flag to send DISC when tx queue is empty */
+            if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
+            {
+                /* if no pending data and all PDU is acked */
+                if (  (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
+                    &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
+                    &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)  )
+                {
+                    llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+                    llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+                }
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_is_rw_open
+**
+** Description      check if receive window is open in remote
+**
+** Returns          TRUE if remote can receive more data
+**
+*******************************************************************************/
+BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
+{
+    if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
+    {
+        return TRUE;
+    }
+    else
+    {
+        LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
+                           p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_get_next_pdu
+**
+** Description      Get a PDU from tx queue of data link
+**
+** Returns          BT_HDR*
+**
+*******************************************************************************/
+BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
+{
+    BT_HDR *p_msg = NULL;
+    BOOLEAN flush = TRUE;
+    tLLCP_SAP_CBACK_DATA data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    UINT8   send_seq = p_dlcb->next_tx_seq;
+#endif
+
+    /* if there is data to send and remote device can receive it */
+    if (  (p_dlcb->i_xmit_q.count)
+        &&(!p_dlcb->remote_busy)
+        &&(llcp_dlc_is_rw_open (p_dlcb))  )
+    {
+        p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
+        llcp_cb.total_tx_i_pdu--;
+
+        if (p_msg->offset >= LLCP_MIN_OFFSET)
+        {
+            /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
+            llcp_util_build_info_pdu (p_dlcb, p_msg);
+
+            p_dlcb->next_tx_seq  = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+            LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                                send_seq, p_dlcb->next_rx_seq,
+                                p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+                                p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+        }
+        else
+        {
+            LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
+                                p_msg->offset, LLCP_MIN_OFFSET );
+            GKI_freebuf (p_msg);
+            p_msg = NULL;
+        }
+    }
+
+    /* if tx queue is empty and all PDU is acknowledged */
+    if (  (p_dlcb->i_xmit_q.count == 0)
+        &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
+        &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
+    {
+        /* check flag to send DISC */
+        if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
+        {
+            p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
+        }
+
+        /* check flag to notify upper layer */
+        if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
+        {
+            p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
+
+            data.tx_complete.event      = LLCP_SAP_EVT_TX_COMPLETE;
+            data.tx_complete.local_sap  = p_dlcb->local_sap;
+            data.tx_complete.remote_sap = p_dlcb->remote_sap;
+
+            (*p_dlcb->p_app_cb->p_app_cback) (&data);
+        }
+    }
+
+    return p_msg;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlc_get_next_pdu_length
+**
+** Description      return length of PDU which is top in tx queue of data link
+**
+** Returns          length of PDU
+**
+*******************************************************************************/
+UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
+{
+    BT_HDR *p_msg;
+
+    /* if there is data to send and remote device can receive it */
+    if (  (p_dlcb->i_xmit_q.count)
+        &&(!p_dlcb->remote_busy)
+        &&(llcp_dlc_is_rw_open (p_dlcb))  )
+    {
+        p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
+
+        return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
+    }
+    return 0;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         llcp_dlsm_get_state_name
+**
+** Description      This function returns the state name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
+{
+    switch (state)
+    {
+    case LLCP_DLC_STATE_IDLE:
+        return ("IDLE");
+    case LLCP_DLC_STATE_W4_REMOTE_RESP:
+        return ("W4_REMOTE_RESP");
+    case LLCP_DLC_STATE_W4_LOCAL_RESP:
+        return ("W4_LOCAL_RESP");
+    case LLCP_DLC_STATE_CONNECTED:
+        return ("CONNECTED");
+    case LLCP_DLC_STATE_W4_REMOTE_DM:
+        return ("W4_REMOTE_DM");
+    default:
+        return ("???? UNKNOWN STATE");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_dlsm_get_event_name
+**
+** Description      This function returns the event name.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
+{
+    switch (event)
+    {
+    case LLCP_DLC_EVENT_API_CONNECT_REQ:
+        return ("API_CONNECT_REQ");
+    case LLCP_DLC_EVENT_API_CONNECT_CFM:
+        return ("API_CONNECT_CFM");
+    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
+        return ("API_CONNECT_REJECT");
+    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
+        return ("PEER_CONNECT_IND");
+    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
+        return ("PEER_CONNECT_CFM");
+
+    case LLCP_DLC_EVENT_API_DATA_REQ:
+        return ("API_DATA_REQ");
+    case LLCP_DLC_EVENT_PEER_DATA_IND:
+        return ("PEER_DATA_IND");
+
+    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
+        return ("API_DISCONNECT_REQ");
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
+        return ("PEER_DISCONNECT_IND");
+    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
+        return ("PEER_DISCONNECT_RESP");
+
+    case LLCP_DLC_EVENT_FRAME_ERROR:
+        return ("FRAME_ERROR");
+    case LLCP_DLC_EVENT_LINK_ERROR:
+        return ("LINK_ERROR");
+
+    case LLCP_DLC_EVENT_TIMEOUT:
+        return ("TIMEOUT");
+
+    default:
+        return ("???? UNKNOWN EVENT");
+    }
+}
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+
diff --git a/src/nfc/llcp/llcp_link.c b/src/nfc/llcp/llcp_link.c
new file mode 100644
index 0000000..7deaeb2
--- /dev/null
+++ b/src/nfc/llcp/llcp_link.c
@@ -0,0 +1,1740 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP Link Management
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+const UINT16 llcp_link_rwt[15] =  /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
+{
+       1, /* WT=0,     302us */
+       1, /* WT=1,     604us */
+       2, /* WT=2,    1208us */
+       3, /* WT=3,     2.4ms */
+       5, /* WT=4,     4.8ms */
+      10, /* WT=5,     9.7ms */
+      20, /* WT=6,    19.3ms */
+      39, /* WT=7,    38.7ms */
+      78, /* WT=8,    77.3ms */
+     155, /* WT=9,   154.6ms */
+     310, /* WT=10,  309.2ms */
+     619, /* WT=11,  618.5ms */
+    1237, /* WT=12, 1237.0ms */
+    2474, /* WT=13, 2474.0ms */
+    4948, /* WT=14, 4948.0ms */
+};
+
+static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes);
+static BOOLEAN llcp_link_version_agreement (void);
+
+static void    llcp_link_send_SYMM (void);
+static void    llcp_link_update_status (BOOLEAN is_activated);
+static void    llcp_link_check_congestion (void);
+static void    llcp_link_check_uncongested (void);
+static void    llcp_link_proc_ui_pdu (UINT8 local_sap, UINT8 remote_sap, UINT16 ui_pdu_length, UINT8 *p_ui_pdu, BT_HDR *p_msg);
+static void    llcp_link_proc_agf_pdu (BT_HDR *p_msg);
+static void    llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg);
+static void    llcp_link_proc_rx_data (BT_HDR *p_msg);
+
+static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length);
+static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_agf);
+static void    llcp_link_send_to_lower (BT_HDR *p_msg);
+
+#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
+extern tLLCP_TEST_PARAMS llcp_test_params;
+#endif
+
+/* debug functions type */
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *llcp_pdu_type (UINT8 ptype);
+#endif
+
+/*******************************************************************************
+**
+** Function         llcp_link_start_inactivity_timer
+**
+** Description      This function start LLCP link inactivity timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_start_inactivity_timer (void)
+{
+    if (  (llcp_cb.lcb.inact_timer.in_use == FALSE)
+        &&(llcp_cb.lcb.inact_timeout > 0)  )
+    {
+        LLCP_TRACE_DEBUG1 ("Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout);
+
+        nfc_start_quick_timer (&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
+                               ((UINT32) llcp_cb.lcb.inact_timeout) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_stop_inactivity_timer
+**
+** Description      This function stop LLCP link inactivity timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_stop_inactivity_timer (void)
+{
+    if (llcp_cb.lcb.inact_timer.in_use)
+    {
+        LLCP_TRACE_DEBUG0 ("Stop inactivity_timer");
+
+        nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_start_link_timer
+**
+** Description      This function starts LLCP link timer (LTO or delay response).
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_start_link_timer (void)
+{
+    if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
+    {
+        /* wait for application layer sending data */
+        nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+                               (((UINT32) llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+    }
+    else
+    {
+        /* wait for data to receive from remote */
+        nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+                               ((UINT32) llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_stop_link_timer
+**
+** Description      This function stop LLCP link timer (LTO or delay response).
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_stop_link_timer (void)
+{
+    nfc_stop_quick_timer (&llcp_cb.lcb.timer);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_activate
+**
+** Description      Activate LLCP link
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config)
+{
+    LLCP_TRACE_DEBUG0 ("llcp_link_activate ()");
+
+    /* At this point, MAC link activation procedure has been successfully completed */
+
+    /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
+    if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE)
+    {
+        LLCP_TRACE_WARNING2 ("llcp_link_activate (): max payload size (%d) must be %d bytes",
+                             p_config->max_payload_size, LLCP_NCI_MAX_PAYL_SIZE);
+    }
+
+    /* Processing the parametes that have been received with the MAC link activation */
+    if (llcp_link_parse_gen_bytes (p_config->gen_bytes_len,
+                                   p_config->p_gen_bytes ) == FALSE)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to parse general bytes");
+        (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_BAD_GEN_BYTES);
+        return LLCP_STATUS_FAIL;
+    }
+
+    /*
+    ** For the Target device, the scaled value of RWT MUST be less than or equal to the
+    ** scaled value of the LLC Link Timeout (LTO).
+    */
+    if ((p_config->is_initiator) && (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto))
+    {
+        LLCP_TRACE_WARNING3 ("llcp_link_activate (): WT (%d, %dms) must be less than or equal to LTO (%dms)",
+                             p_config->waiting_time,
+                             llcp_link_rwt[p_config->waiting_time],
+                             llcp_cb.lcb.peer_lto);
+    }
+
+    /* extend LTO as much as internally required processing time and propagation delays */
+    llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY;
+
+    /* LLCP version number agreement */
+    if (llcp_link_version_agreement () == FALSE)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to agree version");
+        (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_VERSION_FAILED);
+        return LLCP_STATUS_FAIL;
+    }
+
+    llcp_cb.lcb.is_initiator = p_config->is_initiator;
+
+    /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */
+
+    if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu)
+        llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu;
+    else
+        llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu;
+
+    /*
+    ** When entering the normal operation phase, LLCP shall initialize the symmetry
+    ** procedure.
+    */
+    if (llcp_cb.lcb.is_initiator)
+    {
+        LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Initiator");
+
+        llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init;
+        llcp_cb.lcb.symm_state    = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
+
+        if (llcp_cb.lcb.delay_first_pdu_timeout > 0)
+        {
+            /* give a chance to upper layer to send PDU if need */
+            nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU,
+                                   (((UINT32) llcp_cb.lcb.delay_first_pdu_timeout) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        }
+        else
+        {
+            llcp_link_send_SYMM ();
+        }
+    }
+    else
+    {
+        LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Target");
+        llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
+        llcp_cb.lcb.symm_state    = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+
+        /* wait for data to receive from remote */
+        llcp_link_start_link_timer ();
+    }
+
+
+    /*
+    ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set data callback
+    ** because LLCP PDU could be in NCI queue.
+    */
+    llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
+
+    /* LLCP Link Activation completed */
+    (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_COMPLETE_EVT, LLCP_LINK_SUCCESS);
+
+    /* Update link status to service layer */
+    llcp_link_update_status (TRUE);
+
+    NFC_SetStaticRfCback (llcp_link_connection_cback);
+
+    return (LLCP_STATUS_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_deactivate_cleanup
+**
+** Description      Clean up for link deactivation
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_deactivate_cleanup  (UINT8 reason)
+{
+    /* report SDP failure for any pending request */
+    llcp_sdp_proc_deactivation ();
+
+    /* Update link status to service layer */
+    llcp_link_update_status (FALSE);
+
+    /* We had sent out DISC */
+    llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
+
+    llcp_link_stop_link_timer ();
+
+    /* stop inactivity timer */
+    llcp_link_stop_inactivity_timer ();
+
+    /* Let upper layer deactivate local link */
+    (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_DEACTIVATED_EVT, reason);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_process_link_timeout
+**
+** Description      Process timeout events for LTO, SYMM and deactivating
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_process_link_timeout (void)
+{
+    if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+    {
+        if ((llcp_cb.lcb.symm_delay > 0) && (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT))
+        {
+            /* upper layer doesn't have anything to send */
+            LLCP_TRACE_DEBUG0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
+            llcp_link_send_SYMM ();
+
+            /* wait for data to receive from remote */
+            llcp_link_start_link_timer ();
+
+            /* start inactivity timer */
+            if (llcp_cb.num_data_link_connection == 0)
+            {
+                llcp_link_start_inactivity_timer ();
+            }
+        }
+        else
+        {
+            LLCP_TRACE_ERROR0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
+            llcp_link_deactivate (LLCP_LINK_TIMEOUT);
+        }
+    }
+    else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+    {
+        llcp_deactivate_cleanup (llcp_cb.lcb.link_deact_reason);
+
+        NFC_SetStaticRfCback (NULL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_deactivate
+**
+** Description      Deactivate LLCP link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_deactivate (UINT8 reason)
+{
+    UINT8        local_sap, idx;
+    tLLCP_DLCB   *p_dlcb;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_DEBUG1 ("llcp_link_deactivate () reason = 0x%x", reason);
+
+    /* Release any held buffers in signaling PDU queue */
+    while (llcp_cb.lcb.sig_xmit_q.p_first)
+        GKI_freebuf (GKI_dequeue (&llcp_cb.lcb.sig_xmit_q));
+
+    /* Release any held buffers in UI PDU queue */
+    for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++)
+    {
+        p_app_cb = llcp_util_get_app_cb (local_sap);
+
+        if (  (p_app_cb)
+            &&(p_app_cb->p_app_cback)  )
+        {
+            while (p_app_cb->ui_xmit_q.p_first)
+                GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
+
+            p_app_cb->is_ui_tx_congested = FALSE;
+
+            while (p_app_cb->ui_rx_q.p_first)
+                GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
+        }
+    }
+
+    llcp_cb.total_tx_ui_pdu = 0;
+    llcp_cb.total_rx_ui_pdu = 0;
+
+    /* Notify all of data link */
+    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+    {
+        if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
+        {
+            p_dlcb = &(llcp_cb.dlcb[idx]);
+
+            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL);
+        }
+    }
+    llcp_cb.total_tx_i_pdu = 0;
+    llcp_cb.total_rx_i_pdu = 0;
+
+    llcp_cb.overall_tx_congested = FALSE;
+    llcp_cb.overall_rx_congested = FALSE;
+
+    if (  (reason == LLCP_LINK_FRAME_ERROR)
+        ||(reason == LLCP_LINK_LOCAL_INITIATED)  )
+    {
+        /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP */
+        NFC_FlushData (NFC_RF_CONN_ID);
+
+        llcp_util_send_disc (LLCP_SAP_LM, LLCP_SAP_LM);
+
+        /* Wait until DISC is sent to peer */
+        LLCP_TRACE_DEBUG0 ("llcp_link_deactivate (): Wait until DISC is sent to peer");
+
+        llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
+
+        if (llcp_cb.lcb.sig_xmit_q.count == 0)
+        {
+            /* if DISC is sent to NFCC, wait for short period for NFCC to send it to peer */
+            nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+                                   ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+        }
+
+        llcp_cb.lcb.link_deact_reason = reason;
+        return;
+    }
+    else if (  (reason == LLCP_LINK_REMOTE_INITIATED)
+             &&(!llcp_cb.lcb.is_initiator)  )
+    {
+        /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
+        llcp_link_send_SYMM ();
+    }
+    else /*  for link timeout and interface error */
+    {
+        NFC_FlushData (NFC_RF_CONN_ID);
+    }
+
+    llcp_deactivate_cleanup (reason);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_parse_gen_bytes
+**
+** Description      Check LLCP magic number and get parameters in general bytes
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes)
+{
+    UINT8 *p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
+    UINT8 length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
+
+    if (  (gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN)
+        &&(*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0)
+        &&(*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1)
+        &&(*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2)  )
+    {
+        /* in case peer didn't include these */
+        llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
+        llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
+
+        return (llcp_util_parse_link_params (length, p));
+    }
+    else /* if this is not LLCP */
+    {
+        return (FALSE);
+    }
+
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_version_agreement
+**
+** Description      LLCP version number agreement
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN llcp_link_version_agreement (void)
+{
+    UINT8 peer_major_version, peer_minor_version;
+
+    peer_major_version = LLCP_GET_MAJOR_VERSION (llcp_cb.lcb.peer_version);
+    peer_minor_version = LLCP_GET_MINOR_VERSION (llcp_cb.lcb.peer_version);
+
+    if (peer_major_version < LLCP_MIN_MAJOR_VERSION)
+    {
+        LLCP_TRACE_ERROR1("llcp_link_version_agreement(): unsupported peer version number. Peer Major Version:%d", peer_major_version);
+        return FALSE;
+    }
+    else
+    {
+        if (peer_major_version == LLCP_VERSION_MAJOR)
+        {
+            llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
+            if (peer_minor_version >= LLCP_VERSION_MINOR)
+            {
+                llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
+            }
+            else
+            {
+                llcp_cb.lcb.agreed_minor_version = peer_minor_version;
+            }
+        }
+        else if (peer_major_version < LLCP_VERSION_MAJOR)
+        {
+            /* so far we can support backward compatibility */
+            llcp_cb.lcb.agreed_major_version = peer_major_version;
+            llcp_cb.lcb.agreed_minor_version = peer_minor_version;
+        }
+        else
+        {
+            /* let peer (higher major version) decide it */
+            llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
+            llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
+        }
+
+        LLCP_TRACE_DEBUG6 ("local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
+                            LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR,
+                            peer_major_version, peer_minor_version,
+                            llcp_cb.lcb.agreed_major_version, llcp_cb.lcb.agreed_minor_version);
+
+        return (TRUE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_update_status
+**
+** Description      Notify all of service layer client link status change
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_update_status (BOOLEAN is_activated)
+{
+    tLLCP_SAP_CBACK_DATA data;
+    tLLCP_APP_CB *p_app_cb;
+    UINT8 sap;
+
+    data.link_status.event        = LLCP_SAP_EVT_LINK_STATUS;
+    data.link_status.is_activated = is_activated;
+    data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
+
+    /* notify all SAP so they can create connection while link is activated */
+    for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
+    {
+        p_app_cb = llcp_util_get_app_cb (sap);
+
+        if (  (p_app_cb)
+            &&(p_app_cb->p_app_cback)  )
+        {
+            data.link_status.local_sap = sap;
+            p_app_cb->p_app_cback (&data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_check_congestion
+**
+** Description      Check overall congestion status
+**                  Notify to all of upper layer if congested
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_check_congestion (void)
+{
+    tLLCP_SAP_CBACK_DATA data;
+    tLLCP_APP_CB *p_app_cb;
+    UINT8 sap, idx;
+
+    if (llcp_cb.overall_tx_congested)
+    {
+        /* already congested so no need to check again */
+        return;
+    }
+
+    if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)
+    {
+        /* overall buffer usage is high */
+        llcp_cb.overall_tx_congested = TRUE;
+
+        LLCP_TRACE_WARNING2 ("overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
+                              llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
+
+        data.congest.event        = LLCP_SAP_EVT_CONGEST;
+        data.congest.is_congested = TRUE;
+
+        /* notify logical data link congestion status */
+        data.congest.remote_sap = LLCP_INVALID_SAP;
+        data.congest.link_type  = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+
+        for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
+        {
+            p_app_cb = llcp_util_get_app_cb (sap);
+
+            if (  (p_app_cb)
+                &&(p_app_cb->p_app_cback)
+                &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)  )
+            {
+                /* if already congested then no need to notify again */
+                if (!p_app_cb->is_ui_tx_congested)
+                {
+                    p_app_cb->is_ui_tx_congested = TRUE;
+
+                    LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congestion start: count=%d",
+                                          sap, p_app_cb->ui_xmit_q.count);
+
+                    data.congest.local_sap = sap;
+                    p_app_cb->p_app_cback (&data);
+                }
+            }
+        }
+
+        /* notify data link connection congestion status */
+        data.congest.link_type  = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+        for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++ )
+        {
+            if (  (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+                &&(llcp_cb.dlcb[idx].remote_busy == FALSE)
+                &&(llcp_cb.dlcb[idx].is_tx_congested == FALSE)  )
+            {
+                llcp_cb.dlcb[idx].is_tx_congested = TRUE;
+
+                LLCP_TRACE_WARNING3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
+                                      llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
+                                      llcp_cb.dlcb[idx].i_xmit_q.count);
+
+                data.congest.local_sap  = llcp_cb.dlcb[idx].local_sap;
+                data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
+
+                (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_check_uncongested
+**
+** Description      Check overall congestion status, logical data link and
+**                  data link connection congestion status
+**                  Notify to each upper layer if uncongested
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_check_uncongested (void)
+{
+    tLLCP_SAP_CBACK_DATA data;
+    tLLCP_APP_CB *p_app_cb;
+    UINT8 xx, sap, idx;
+
+    if (llcp_cb.overall_tx_congested)
+    {
+        if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <= llcp_cb.max_num_tx_buff / 2)
+        {
+            /* overall congestion is cleared */
+            llcp_cb.overall_tx_congested = FALSE;
+
+            LLCP_TRACE_WARNING2 ("overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
+                                  llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
+        }
+        else
+        {
+            /* wait until more data packets are sent out */
+            return;
+        }
+    }
+
+    data.congest.event        = LLCP_SAP_EVT_CONGEST;
+    data.congest.is_congested = FALSE;
+
+    /* if total number of UI PDU is below threshold */
+    if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff)
+    {
+        /* check and notify logical data link congestion status */
+        data.congest.remote_sap = LLCP_INVALID_SAP;
+        data.congest.link_type  = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+
+        /*
+        ** start point of uncongested status notification is in round robin
+        ** so each logical data link has equal chance of transmitting.
+        */
+        sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
+
+        for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++)
+        {
+            /* no logical data link on LM and SDP */
+            if (sap > LLCP_SAP_SDP)
+            {
+                p_app_cb = llcp_util_get_app_cb (sap);
+
+                if (  (p_app_cb)
+                    &&(p_app_cb->p_app_cback)
+                    &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
+                    &&(p_app_cb->is_ui_tx_congested)
+                    &&(p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end)  )
+                {
+                    /* if it was congested but now tx queue count is below threshold */
+                    p_app_cb->is_ui_tx_congested = FALSE;
+
+                    LLCP_TRACE_DEBUG2 ("Logical link (SAP=0x%X) congestion end: count=%d",
+                                        sap, p_app_cb->ui_xmit_q.count);
+
+                    data.congest.local_sap = sap;
+                    p_app_cb->p_app_cback (&data);
+                }
+            }
+
+            sap = (sap + 1) % LLCP_NUM_SAPS;
+        }
+
+        /* move start point for next logical data link */
+        for (xx = 0; xx < LLCP_NUM_SAPS; xx++)
+        {
+            sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
+
+            if (sap > LLCP_SAP_SDP)
+            {
+                p_app_cb = llcp_util_get_app_cb (sap);
+
+                if (  (p_app_cb)
+                    &&(p_app_cb->p_app_cback)
+                    &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)  )
+                {
+                    llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
+                    break;
+                }
+            }
+        }
+    }
+
+    /* notify data link connection congestion status */
+    data.congest.link_type  = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
+
+    /*
+    ** start point of uncongested status notification is in round robin
+    ** so each data link connection has equal chance of transmitting.
+    */
+    idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
+
+    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
+    {
+        /* if it was congested but now tx queue is below threshold (receiving window) */
+        if (  (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+            &&(llcp_cb.dlcb[idx].is_tx_congested)
+            &&(llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2)  )
+        {
+            llcp_cb.dlcb[idx].is_tx_congested = FALSE;
+
+            if (llcp_cb.dlcb[idx].remote_busy == FALSE)
+            {
+                LLCP_TRACE_DEBUG3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
+                                    llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
+                                    llcp_cb.dlcb[idx].i_xmit_q.count);
+
+                data.congest.local_sap  = llcp_cb.dlcb[idx].local_sap;
+                data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
+
+                (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
+            }
+        }
+        idx = (idx + 1) % LLCP_MAX_DATA_LINK;
+    }
+
+    /* move start point for next data link connection */
+    for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
+    {
+        idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
+        if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+        {
+            llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
+            break;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_send_SYMM
+**
+** Description      Send SYMM PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_send_SYMM (void)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_msg->len    = LLCP_PDU_SYMM_SIZE;
+        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM ));
+
+        llcp_link_send_to_lower (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_check_send_data
+**
+** Description      Send PDU to peer
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_check_send_data (void)
+{
+    BT_HDR *p_pdu;
+
+    /* don't re-enter while processing to prevent out of sequence */
+    if (llcp_cb.lcb.is_sending_data)
+        return;
+    else
+        llcp_cb.lcb.is_sending_data = TRUE;
+
+    /*
+    ** check overall congestion due to high usage of buffer pool
+    ** if congested then notify all of upper layers not to send any more data
+    */
+    llcp_link_check_congestion ();
+
+    if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
+    {
+        LLCP_TRACE_DEBUG0 ("llcp_link_check_send_data () in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
+
+        p_pdu = llcp_link_build_next_pdu (NULL);
+
+        /*
+        ** For data link connection,
+        ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in this transmission.
+        ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's not congested,
+        ** then RR PDU will be sent.
+        ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's congested,
+        ** then RNR PDU will be sent.
+        ** If local busy state has been changed then RR or RNR PDU may be sent.
+        */
+        llcp_dlc_check_to_send_rr_rnr ();
+
+        /* add RR/RNR PDU to be sent if any */
+        p_pdu = llcp_link_build_next_pdu (p_pdu);
+
+        if (p_pdu != NULL)
+        {
+            llcp_link_send_to_lower (p_pdu);
+
+            /* stop inactivity timer */
+            llcp_link_stop_inactivity_timer ();
+
+            /* check congestion status after sending out some data */
+            llcp_link_check_uncongested ();
+        }
+        else
+        {
+            /* There is no data to send, so send SYMM */
+            if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
+            {
+                if (llcp_cb.lcb.symm_delay > 0)
+                {
+                    /* wait for application layer sending data */
+                    llcp_link_start_link_timer ();
+                    llcp_cb.lcb.is_sending_data = FALSE;
+                    return;
+                }
+                else
+                {
+                    llcp_link_send_SYMM ();
+
+                    /* start inactivity timer */
+                    if (llcp_cb.num_data_link_connection == 0)
+                    {
+                        llcp_link_start_inactivity_timer ();
+                    }
+                }
+            }
+            else
+            {
+                llcp_cb.lcb.is_sending_data = FALSE;
+                return;
+            }
+        }
+
+        if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+        {
+            /* wait for short period for NFCC to send DISC */
+            nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
+                                   ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+        }
+        else
+        {
+            /* wait for data to receive from remote */
+            llcp_link_start_link_timer ();
+        }
+    }
+
+    llcp_cb.lcb.is_sending_data = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_ui_pdu
+**
+** Description      Process UI PDU from peer device
+**
+** Returns          None
+**
+*******************************************************************************/
+static void llcp_link_proc_ui_pdu (UINT8  local_sap,
+                                   UINT8  remote_sap,
+                                   UINT16 ui_pdu_length,
+                                   UINT8  *p_ui_pdu,
+                                   BT_HDR *p_msg)
+{
+    BOOLEAN      appended;
+    BT_HDR       *p_last_buf;
+    UINT16       available_bytes;
+    UINT8        *p_dst;
+    tLLCP_APP_CB *p_app_cb;
+    tLLCP_SAP_CBACK_DATA data;
+    tLLCP_DLCB   *p_dlcb;
+
+    p_app_cb = llcp_util_get_app_cb (local_sap);
+        /*if UI PDU sent to SAP with data link connection*/
+    if ((p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap)))
+    {
+        llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
+        llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
+        if (p_msg)
+        {
+            GKI_freebuf (p_msg);
+        }
+        return;
+    }
+
+    /* if application is registered and expecting UI PDU on logical data link */
+    if (  (p_app_cb)
+        &&(p_app_cb->p_app_cback)
+        &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)  )
+    {
+        LLCP_TRACE_DEBUG2 ("llcp_link_proc_ui_pdu () Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
+
+        /* if this is not from AGF PDU */
+        if (p_msg)
+        {
+            ui_pdu_length = p_msg->len; /* including LLCP header */
+            p_ui_pdu      = (UINT8*) (p_msg + 1) + p_msg->offset;
+        }
+
+        appended = FALSE;
+
+        /* get last buffer in rx queue */
+        p_last_buf = (BT_HDR *) GKI_getlast (&p_app_cb->ui_rx_q);
+
+        if (p_last_buf)
+        {
+            /* get max length to append at the end of buffer */
+            available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
+
+            /* if new UI PDU with length can be attached at the end of buffer */
+            if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length)
+            {
+                p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
+
+                /* add length of UI PDU */
+                UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
+
+                /* copy UI PDU with LLCP header */
+                memcpy (p_dst, p_ui_pdu, ui_pdu_length);
+
+                p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+
+                if (p_msg)
+                    GKI_freebuf (p_msg);
+
+                appended = TRUE;
+            }
+        }
+
+        /* if it is not available to append */
+        if (!appended)
+        {
+            /* if it's not from AGF PDU */
+            if (p_msg)
+            {
+                /* add length of PDU in front of UI PDU (reuse room for NCI header) */
+                p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
+                UINT16_TO_BE_STREAM (p_ui_pdu, ui_pdu_length);
+
+                p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
+                p_msg->len    += LLCP_PDU_AGF_LEN_SIZE;
+                p_msg->layer_specific = 0;
+            }
+            else
+            {
+                p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
+
+                if (p_msg)
+                {
+                    p_dst = (UINT8*) (p_msg + 1);
+
+                    /* add length of PDU in front of UI PDU */
+                    UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
+
+                    memcpy (p_dst, p_ui_pdu, ui_pdu_length);
+
+                    p_msg->offset = 0;
+                    p_msg->len    = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
+                    p_msg->layer_specific = 0;
+                }
+                else
+                {
+                    LLCP_TRACE_ERROR0 ("llcp_link_proc_ui_pdu (): out of buffer");
+                }
+            }
+
+            /* insert UI PDU in rx queue */
+            if (p_msg)
+            {
+                GKI_enqueue (&p_app_cb->ui_rx_q, p_msg);
+                llcp_cb.total_rx_ui_pdu++;
+            }
+        }
+
+        if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start)
+        {
+            LLCP_TRACE_WARNING2 ("llcp_link_proc_ui_pdu (): SAP:0x%x, rx link is congested (%d), discard oldest UI PDU",
+                                 local_sap, p_app_cb->ui_rx_q.count);
+
+            GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
+            llcp_cb.total_rx_ui_pdu--;
+        }
+
+        if ((p_app_cb->ui_rx_q.count == 1) && (appended == FALSE))
+        {
+            data.data_ind.event         = LLCP_SAP_EVT_DATA_IND;
+            data.data_ind.local_sap     = local_sap;
+            data.data_ind.remote_sap    = remote_sap;
+            data.data_ind.link_type     = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
+            (*p_app_cb->p_app_cback) (&data);
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR1 ("llcp_link_proc_ui_pdu (): Unregistered SAP:0x%x", local_sap);
+
+        if (p_msg)
+        {
+            GKI_freebuf (p_msg);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_agf_pdu
+**
+** Description      Process AGF PDU from peer device
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_proc_agf_pdu (BT_HDR *p_agf)
+{
+    UINT16 agf_length;
+    UINT8 *p, *p_info, *p_pdu_length;
+    UINT16 pdu_hdr, pdu_length;
+    UINT8  dsap, ptype, ssap;
+
+    p_agf->len    -= LLCP_PDU_HEADER_SIZE;
+    p_agf->offset += LLCP_PDU_HEADER_SIZE;
+
+    /*
+    ** check integrity of AGF PDU and get number of PDUs in AGF PDU
+    */
+    agf_length = p_agf->len;
+    p = (UINT8 *) (p_agf + 1) + p_agf->offset;
+
+    while (agf_length > 0)
+    {
+        if (agf_length > LLCP_PDU_AGF_LEN_SIZE)
+        {
+            BE_STREAM_TO_UINT16 (pdu_length, p);
+            agf_length -= LLCP_PDU_AGF_LEN_SIZE;
+        }
+        else
+        {
+            break;
+        }
+
+        if (pdu_length <= agf_length)
+        {
+            p += pdu_length;
+            agf_length -= pdu_length;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    if (agf_length != 0)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): Received invalid AGF PDU");
+        GKI_freebuf (p_agf);
+        return;
+    }
+
+    /*
+    ** Process PDUs in AGF
+    */
+    agf_length = p_agf->len;
+    p = (UINT8 *) (p_agf + 1) + p_agf->offset;
+
+    while (agf_length > 0)
+    {
+        /* get length of PDU */
+        p_pdu_length = p;
+        BE_STREAM_TO_UINT16 (pdu_length, p);
+        agf_length -= LLCP_PDU_AGF_LEN_SIZE;
+
+        /* get DSAP/PTYPE/SSAP */
+        p_info = p;
+        BE_STREAM_TO_UINT16 (pdu_hdr, p_info );
+
+        dsap  = LLCP_GET_DSAP (pdu_hdr);
+        ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
+        ssap  = LLCP_GET_SSAP (pdu_hdr);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+        LLCP_TRACE_DEBUG4 ("llcp_link_proc_agf_pdu (): Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x in AGF",
+                           dsap, llcp_pdu_type (ptype), ptype, ssap);
+#endif
+
+        if (  (ptype == LLCP_PDU_DISC_TYPE)
+            &&(dsap == LLCP_SAP_LM)
+            &&(ssap == LLCP_SAP_LM)  )
+        {
+            GKI_freebuf (p_agf);
+            llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
+            return;
+        }
+        else if (ptype == LLCP_PDU_SYMM_TYPE)
+        {
+            LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): SYMM PDU exchange shall not be in AGF");
+        }
+        else if (ptype == LLCP_PDU_PAX_TYPE)
+        {
+            LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): PAX PDU exchange shall not be used");
+        }
+        else if (ptype == LLCP_PDU_SNL_TYPE)
+        {
+            llcp_sdp_proc_snl ((UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
+        }
+        else if ((ptype == LLCP_PDU_UI_TYPE) && (pdu_length > LLCP_PDU_HEADER_SIZE))
+        {
+            llcp_link_proc_ui_pdu (dsap, ssap, pdu_length, p, NULL);
+        }
+        else if (ptype == LLCP_PDU_I_TYPE)
+        {
+            llcp_dlc_proc_i_pdu (dsap, ssap, pdu_length, p, NULL);
+        }
+        else /* let data link connection handle PDU */
+        {
+            llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
+        }
+
+        p += pdu_length;
+        agf_length -= pdu_length;
+    }
+
+    GKI_freebuf (p_agf);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_rx_pdu
+**
+** Description      Process received PDU from peer device
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg)
+{
+    BOOLEAN free_buffer = TRUE;
+    UINT8   *p_data;
+
+    switch (ptype)
+    {
+    case LLCP_PDU_PAX_TYPE:
+        LLCP_TRACE_ERROR0 ("llcp_link_proc_rx_pdu (); PAX PDU exchange shall not be used");
+        break;
+
+    case LLCP_PDU_DISC_TYPE:
+        if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM))
+        {
+            llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
+        }
+        else
+        {
+            p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+            llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+        }
+        break;
+
+    case LLCP_PDU_SNL_TYPE:
+        p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+        llcp_sdp_proc_snl ((UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+        break;
+
+    case LLCP_PDU_AGF_TYPE:
+        llcp_link_proc_agf_pdu (p_msg);
+        free_buffer = FALSE;
+        break;
+
+    case LLCP_PDU_UI_TYPE:
+        llcp_link_proc_ui_pdu (dsap, ssap, 0, NULL, p_msg);
+        free_buffer = FALSE;
+        break;
+
+    case LLCP_PDU_I_TYPE:
+        llcp_dlc_proc_i_pdu (dsap, ssap, 0, NULL, p_msg);
+        free_buffer = FALSE;
+        break;
+
+    default:
+        p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
+        llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
+        break;
+    }
+
+    if (free_buffer)
+        GKI_freebuf (p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_proc_rx_data
+**
+** Description      Process received data from NFCC and maintain symmetry state
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_proc_rx_data (BT_HDR *p_msg)
+{
+    UINT8  *p;
+    UINT16  pdu_hdr, info_length = 0;
+    UINT8   dsap, ptype, ssap;
+    BOOLEAN free_buffer = TRUE;
+    BOOLEAN frame_error = FALSE;
+
+    if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT)
+    {
+        llcp_link_stop_link_timer ();
+
+        if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+            &&(llcp_cb.lcb.sig_xmit_q.count == 0)  )
+        {
+            /* this indicates that DISC PDU had been sent out to peer */
+            /* initiator may wait for SYMM PDU */
+            llcp_link_process_link_timeout ();
+        }
+        else
+        {
+            if (p_msg->len < LLCP_PDU_HEADER_SIZE)
+            {
+                LLCP_TRACE_ERROR1 ("Received too small PDU: got %d bytes", p_msg->len);
+                frame_error = TRUE;
+            }
+            else
+            {
+                p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+                BE_STREAM_TO_UINT16 (pdu_hdr, p );
+
+                dsap  = LLCP_GET_DSAP (pdu_hdr);
+                ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
+                ssap  = LLCP_GET_SSAP (pdu_hdr);
+
+                /* get length of information per PDU type */
+                if (  (ptype == LLCP_PDU_I_TYPE)
+                    ||(ptype == LLCP_PDU_RR_TYPE)
+                    ||(ptype == LLCP_PDU_RNR_TYPE)  )
+                {
+                    if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
+                    {
+                        info_length = p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
+                    }
+                    else
+                    {
+                        LLCP_TRACE_ERROR0 ("Received I/RR/RNR PDU without sequence");
+                        frame_error = TRUE;
+                    }
+                }
+                else
+                {
+                    info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
+                }
+
+                /* check if length of information is bigger than link MIU */
+                if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu))
+                {
+                    LLCP_TRACE_ERROR2 ("Received exceeding MIU (%d): got %d bytes SDU",
+                                       llcp_cb.lcb.local_link_miu, info_length);
+
+                    frame_error = TRUE;
+                }
+                else
+                {
+#if (BT_TRACE_VERBOSE == TRUE)
+                    LLCP_TRACE_DEBUG4 ("llcp_link_proc_rx_data (): DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x",
+                                       dsap, llcp_pdu_type (ptype), ptype, ssap);
+#endif
+
+                    if (ptype == LLCP_PDU_SYMM_TYPE)
+                    {
+                        if (info_length > 0)
+                        {
+                            LLCP_TRACE_ERROR1 ("Received extra data (%d bytes) in SYMM PDU", info_length);
+                            frame_error = TRUE;
+                        }
+                    }
+                    else
+                    {
+                        /* received other than SYMM */
+                        llcp_link_stop_inactivity_timer ();
+
+                        llcp_link_proc_rx_pdu (dsap, ptype, ssap, p_msg);
+                        free_buffer = FALSE;
+                    }
+                }
+            }
+
+            llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
+
+            /* check if any pending packet */
+            llcp_link_check_send_data ();
+        }
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("Received PDU in state of SYMM_MUST_XMIT_NEXT");
+    }
+
+    if (free_buffer)
+        GKI_freebuf (p_msg);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_get_next_pdu
+**
+** Description      Get next PDU from link manager or data links w/wo dequeue
+**
+** Returns          pointer of a PDU to send if length_only is FALSE
+**                  NULL otherwise
+**
+*******************************************************************************/
+static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length)
+{
+    BT_HDR *p_msg;
+    int     count, xx;
+    tLLCP_APP_CB *p_app_cb;
+
+    /* processing signalling PDU first */
+    if (llcp_cb.lcb.sig_xmit_q.p_first)
+    {
+        if (length_only)
+        {
+            p_msg = (BT_HDR*) llcp_cb.lcb.sig_xmit_q.p_first;
+            *p_next_pdu_length = p_msg->len;
+            return NULL;
+        }
+        else
+            p_msg = (BT_HDR*) GKI_dequeue (&llcp_cb.lcb.sig_xmit_q);
+
+        return p_msg;
+    }
+    else
+    {
+        /* transmitting logical data link and data link connection equaly */
+        for (xx = 0; xx < 2; xx++)
+        {
+            if (!llcp_cb.lcb.ll_served)
+            {
+                /* Get one from logical link connection */
+                for (count = 0; count < LLCP_NUM_SAPS; count++)
+                {
+                    /* round robin schedule without priority  */
+                    p_app_cb = llcp_util_get_app_cb (llcp_cb.lcb.ll_idx);
+
+                    if (  (p_app_cb)
+                        &&(p_app_cb->p_app_cback)
+                        &&(p_app_cb->ui_xmit_q.count)  )
+                    {
+                        if (length_only)
+                        {
+                            /* don't alternate next data link to return the same length of PDU */
+                            p_msg = (BT_HDR *) p_app_cb->ui_xmit_q.p_first;
+                            *p_next_pdu_length = p_msg->len;
+                            return NULL;
+                        }
+                        else
+                        {
+                            /* check data link connection first in next time */
+                            llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+
+                            p_msg = (BT_HDR*) GKI_dequeue (&p_app_cb->ui_xmit_q);
+                            llcp_cb.total_tx_ui_pdu--;
+
+                            /* this logical link has been served, so start from next logical link next time */
+                            llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
+
+                            return p_msg;
+                        }
+                    }
+                    else
+                    {
+                        /* check next logical link connection */
+                        llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
+                    }
+                }
+
+                /* no data, so check data link connection if not checked yet */
+                llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+            }
+            else
+            {
+                /* Get one from data link connection */
+                for (count = 0; count < LLCP_MAX_DATA_LINK; count++)
+                {
+                    /* round robin schedule without priority  */
+                    if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE)
+                    {
+                        if (length_only)
+                        {
+                            *p_next_pdu_length = llcp_dlc_get_next_pdu_length (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
+
+                            if (*p_next_pdu_length > 0 )
+                            {
+                                /* don't change data link connection to return the same length of PDU */
+                                return NULL;
+                            }
+                            else
+                            {
+                                /* no data, so check next data link connection */
+                                llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+                            }
+                        }
+                        else
+                        {
+                            p_msg = llcp_dlc_get_next_pdu (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
+
+                            /* this data link has been served, so start from next data link next time */
+                            llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+
+                            if (p_msg)
+                            {
+                                /* serve logical data link next time */
+                                llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+                                return p_msg;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        /* check next data link connection */
+                        llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
+                    }
+                }
+
+                /* if all of data link connection doesn't have data to send */
+                if (count >= LLCP_MAX_DATA_LINK)
+                {
+                    llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
+                }
+            }
+        }
+    }
+
+    /* nothing to send */
+    *p_next_pdu_length = 0;
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_build_next_pdu
+**
+** Description      Build a PDU from Link Manager and Data Link
+**                  Perform aggregation procedure if necessary
+**
+** Returns          BT_HDR* if sent any PDU
+**
+*******************************************************************************/
+static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_pdu)
+{
+    BT_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu;
+    UINT8  *p, ptype;
+    UINT16  next_pdu_length, pdu_hdr;
+
+    LLCP_TRACE_DEBUG0 ("llcp_link_build_next_pdu ()");
+
+    /* add any pending SNL PDU into sig_xmit_q for transmitting */
+    llcp_sdp_check_send_snl ();
+
+    if (p_pdu)
+    {
+        /* get PDU type */
+        p = (UINT8 *) (p_pdu + 1) + p_pdu->offset;
+        BE_STREAM_TO_UINT16 (pdu_hdr, p);
+
+        ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
+
+        if (ptype == LLCP_PDU_AGF_TYPE)
+        {
+            /* add more PDU into this AGF PDU */
+            p_agf = p_pdu;
+        }
+        else
+        {
+            p_msg = p_pdu;
+        }
+    }
+    else
+    {
+        /* Get a PDU from link manager or data links */
+        p_msg = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
+
+        if (!p_msg)
+        {
+            return NULL;
+        }
+    }
+
+    /* Get length of next PDU from link manager or data links without dequeue */
+    llcp_link_get_next_pdu (TRUE, &next_pdu_length);
+    while (next_pdu_length > 0)
+    {
+        /* if it's first visit */
+        if (!p_agf)
+        {
+            /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
+            if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
+            {
+                p_agf = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+                if (p_agf)
+                {
+                    p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+                    p = (UINT8 *) (p_agf + 1) + p_agf->offset;
+
+                    UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM ));
+                    UINT16_TO_BE_STREAM (p, p_msg->len);
+                    memcpy(p, (UINT8 *) (p_msg + 1) + p_msg->offset, p_msg->len);
+
+                    p_agf->len      = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
+
+                    GKI_freebuf (p_msg);
+                    p_msg = p_agf;
+                }
+                else
+                {
+                    LLCP_TRACE_ERROR0 ("llcp_link_build_next_pdu (): Out of buffer");
+                    return p_msg;
+                }
+            }
+            else
+            {
+                break;
+            }
+        }
+
+        /* if next PDU fits into MIU, copy the next PDU into AGF */
+        if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
+        {
+            /* Get a next PDU from link manager or data links */
+            p_next_pdu = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
+
+            p = (UINT8 *) (p_agf + 1) + p_agf->offset + p_agf->len;
+
+            UINT16_TO_BE_STREAM (p, p_next_pdu->len);
+            memcpy (p, (UINT8 *) (p_next_pdu + 1) + p_next_pdu->offset, p_next_pdu->len);
+
+            p_agf->len += 2 + p_next_pdu->len;
+
+            GKI_freebuf (p_next_pdu);
+
+            /* Get next PDU length from link manager or data links without dequeue */
+            llcp_link_get_next_pdu (TRUE, &next_pdu_length);
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    if (p_agf)
+        return p_agf;
+    else
+        return p_msg;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_send_to_lower
+**
+** Description      Send PDU to lower layer
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_link_send_to_lower (BT_HDR *p_pdu)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispLLCP (p_pdu, FALSE);
+#endif
+
+    llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
+
+    NFC_SendData (NFC_RF_CONN_ID, p_pdu);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_link_connection_cback
+**
+** Description      processing incoming data
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    if (event == NFC_DATA_CEVT)
+    {
+#if (BT_TRACE_PROTOCOL == TRUE)
+        DispLLCP ((BT_HDR *)p_data->data.p_data, TRUE);
+#endif
+        if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
+        {
+            /* respoding SYMM while LLCP is deactivated but RF link is not deactivated yet */
+            llcp_link_send_SYMM ();
+            GKI_freebuf ((BT_HDR *) p_data->data.p_data);
+        }
+        else
+        {
+            llcp_link_proc_rx_data ((BT_HDR *) p_data->data.p_data);
+        }
+    }
+    else if (event == NFC_ERROR_CEVT)
+    {
+        /* RF interface specific status code */
+        llcp_link_deactivate (*(UINT8*) p_data);
+    }
+    else if (event == NFC_DEACTIVATE_CEVT)
+    {
+        if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
+            &&(!llcp_cb.lcb.is_initiator)  )
+        {
+            /* peer initiates NFC link deactivation before timeout */
+            llcp_link_stop_link_timer ();
+            llcp_link_process_link_timeout ();
+        }
+        else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
+        {
+            llcp_link_deactivate (LLCP_LINK_RF_LINK_LOSS_ERR);
+        }
+        NFC_SetStaticRfCback (NULL);
+    }
+
+    /* LLCP ignores the following events
+
+        NFC_CONN_CREATE_CEVT
+        NFC_CONN_CLOSE_CEVT
+    */
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         llcp_pdu_type
+**
+** Description
+**
+** Returns          string of PDU type
+**
+*******************************************************************************/
+static char *llcp_pdu_type (UINT8 ptype)
+{
+    switch(ptype)
+    {
+    case LLCP_PDU_SYMM_TYPE:
+        return "SYMM";
+    case LLCP_PDU_PAX_TYPE:
+        return "PAX";
+    case LLCP_PDU_AGF_TYPE:
+        return "AGF";
+    case LLCP_PDU_UI_TYPE:
+        return "UI";
+    case LLCP_PDU_CONNECT_TYPE:
+        return "CONNECT";
+    case LLCP_PDU_DISC_TYPE:
+        return "DISC";
+    case LLCP_PDU_CC_TYPE:
+        return "CC";
+    case LLCP_PDU_DM_TYPE:
+        return "DM";
+    case LLCP_PDU_FRMR_TYPE:
+        return "FRMR";
+    case LLCP_PDU_SNL_TYPE:
+        return "SNL";
+    case LLCP_PDU_I_TYPE:
+        return "I";
+    case LLCP_PDU_RR_TYPE:
+        return "RR";
+    case LLCP_PDU_RNR_TYPE:
+        return "RNR";
+
+    default:
+        return "RESERVED";
+    }
+}
+
+#endif
+
diff --git a/src/nfc/llcp/llcp_main.c b/src/nfc/llcp/llcp_main.c
new file mode 100644
index 0000000..540cfc5
--- /dev/null
+++ b/src/nfc/llcp/llcp_main.c
@@ -0,0 +1,190 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the main LLCP entry points
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+#if (LLCP_DYNAMIC_MEMORY == FALSE)
+tLLCP_CB llcp_cb;
+#endif
+
+/*******************************************************************************
+**
+** Function         llcp_init
+**
+** Description      This function is called once at startup to initialize
+**                  all the LLCP structures
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_init (void)
+{
+    UINT32 pool_count;
+
+    memset (&llcp_cb, 0, sizeof (tLLCP_CB));
+
+    llcp_cb.trace_level = LLCP_INITIAL_TRACE_LEVEL;
+
+    LLCP_TRACE_DEBUG0 ("LLCP - llcp_init ()");
+
+    llcp_cb.lcb.local_link_miu = (LLCP_MIU <= LLCP_MAX_MIU ? LLCP_MIU : LLCP_MAX_MIU);
+    llcp_cb.lcb.local_opt      = LLCP_OPT_VALUE;
+    llcp_cb.lcb.local_wt       = LLCP_WAITING_TIME;
+    llcp_cb.lcb.local_lto      = LLCP_LTO_VALUE;
+
+    llcp_cb.lcb.inact_timeout_init   = LLCP_INIT_INACTIVITY_TIMEOUT;
+    llcp_cb.lcb.inact_timeout_target = LLCP_TARGET_INACTIVITY_TIMEOUT;
+    llcp_cb.lcb.symm_delay           = LLCP_DELAY_RESP_TIME;
+    llcp_cb.lcb.data_link_timeout    = LLCP_DATA_LINK_CONNECTION_TOUT;
+    llcp_cb.lcb.delay_first_pdu_timeout = LLCP_DELAY_TIME_TO_SEND_FIRST_PDU;
+
+    llcp_cb.lcb.wks  = LLCP_WKS_MASK_LM;
+
+    /* total number of buffers for LLCP */
+    pool_count = GKI_poolcount (LLCP_POOL_ID);
+
+    /* number of buffers for receiving data */
+    llcp_cb.num_rx_buff = (pool_count * LLCP_RX_BUFF_RATIO) / 100;
+
+    /* rx congestion start/end threshold */
+    llcp_cb.overall_rx_congest_start = (UINT8) ((llcp_cb.num_rx_buff * LLCP_RX_CONGEST_START) / 100);
+    llcp_cb.overall_rx_congest_end   = (UINT8) ((llcp_cb.num_rx_buff * LLCP_RX_CONGEST_END) / 100);
+
+    /* max number of buffers for receiving data on logical data link */
+    llcp_cb.max_num_ll_rx_buff = (UINT8) ((llcp_cb.num_rx_buff * LLCP_LL_RX_BUFF_LIMIT) / 100);
+
+    LLCP_TRACE_DEBUG4 ("num_rx_buff = %d, rx_congest_start = %d, rx_congest_end = %d, max_num_ll_rx_buff = %d",
+                        llcp_cb.num_rx_buff, llcp_cb.overall_rx_congest_start,
+                        llcp_cb.overall_rx_congest_end, llcp_cb.max_num_ll_rx_buff);
+
+    /* max number of buffers for transmitting data */
+    llcp_cb.max_num_tx_buff    = (UINT8) (pool_count - llcp_cb.num_rx_buff);
+
+    /* max number of buffers for transmitting data on logical data link */
+    llcp_cb.max_num_ll_tx_buff = (UINT8) ((llcp_cb.max_num_tx_buff * LLCP_LL_TX_BUFF_LIMIT) / 100);
+
+    LLCP_TRACE_DEBUG2 ("max_num_tx_buff = %d, max_num_ll_tx_buff = %d",
+                        llcp_cb.max_num_tx_buff, llcp_cb.max_num_ll_tx_buff);
+
+    llcp_cb.ll_tx_uncongest_ntf_start_sap = LLCP_SAP_SDP + 1;
+
+    LLCP_RegisterServer (LLCP_SAP_SDP, LLCP_LINK_TYPE_DATA_LINK_CONNECTION, "urn:nfc:sn:sdp", llcp_sdp_proc_data);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_cleanup
+**
+** Description      This function is called once at closing to clean up
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_cleanup (void)
+{
+    UINT8 sap;
+    tLLCP_APP_CB *p_app_cb;
+
+    LLCP_TRACE_DEBUG0 ("LLCP - llcp_cleanup ()");
+
+    for (sap = LLCP_SAP_SDP; sap < LLCP_NUM_SAPS; sap++)
+    {
+        p_app_cb = llcp_util_get_app_cb (sap);
+
+        if (  (p_app_cb)
+            &&(p_app_cb->p_app_cback)  )
+        {
+            LLCP_Deregister (sap);
+        }
+    }
+
+    nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer);
+    nfc_stop_quick_timer (&llcp_cb.lcb.timer);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_process_timeout
+**
+** Description      This function is called when an LLCP-related timeout occurs
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    UINT8 reason;
+
+    LLCP_TRACE_DEBUG1 ("llcp_process_timeout: event=%d", p_tle->event);
+
+    switch (p_tle->event)
+    {
+    case NFC_TTYPE_LLCP_LINK_MANAGER:
+        /* Link timeout or Symm timeout */
+        llcp_link_process_link_timeout ();
+        break;
+
+    case NFC_TTYPE_LLCP_LINK_INACT:
+        /* inactivity timeout */
+        llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
+        break;
+
+    case NFC_TTYPE_LLCP_DATA_LINK:
+        reason = LLCP_SAP_DISCONNECT_REASON_TIMEOUT;
+        llcp_dlsm_execute ((tLLCP_DLCB *) (p_tle->param), LLCP_DLC_EVENT_TIMEOUT, &reason);
+        break;
+
+    case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
+        llcp_link_check_send_data ();
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         LLCP_SetTraceLevel
+**
+** Description      This function sets the trace level for LLCP.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 LLCP_SetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        llcp_cb.trace_level = new_level;
+
+    return (llcp_cb.trace_level);
+}
diff --git a/src/nfc/llcp/llcp_sdp.c b/src/nfc/llcp/llcp_sdp.c
new file mode 100644
index 0000000..6d2c73f
--- /dev/null
+++ b/src/nfc/llcp/llcp_sdp.c
@@ -0,0 +1,484 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP Service Discovery
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "llcp_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_proc_data
+**
+** Description      Do nothing
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_sdp_proc_data (tLLCP_SAP_CBACK_DATA *p_data)
+{
+    /*
+    ** Do nothing
+    ** llcp_sdp_proc_SNL () is called by link layer
+    */
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_check_send_snl
+**
+** Description      Enqueue Service Name Lookup PDU into sig_xmit_q for transmitting
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_sdp_check_send_snl (void)
+{
+    UINT8 *p;
+
+    if (llcp_cb.sdp_cb.p_snl)
+    {
+        LLCP_TRACE_DEBUG0 ("SDP: llcp_sdp_check_send_snl ()");
+
+        llcp_cb.sdp_cb.p_snl->len     += LLCP_PDU_HEADER_SIZE;
+        llcp_cb.sdp_cb.p_snl->offset  -= LLCP_PDU_HEADER_SIZE;
+
+        p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset;
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_SDP, LLCP_PDU_SNL_TYPE, LLCP_SAP_SDP ));
+
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, llcp_cb.sdp_cb.p_snl);
+        llcp_cb.sdp_cb.p_snl = NULL;
+    }
+    else
+    {
+        /* Notify DTA after sending out SNL with SDRES not to send SNLs in AGF PDU */
+        if ((llcp_cb.p_dta_cback) && (llcp_cb.dta_snl_resp))
+        {
+            llcp_cb.dta_snl_resp = FALSE;
+            (*llcp_cb.p_dta_cback) ();
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_add_sdreq
+**
+** Description      Add Service Discovery Request into SNL PDU
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_sdp_add_sdreq (UINT8 tid, char *p_name)
+{
+    UINT8  *p;
+    UINT16 name_len = (UINT16) strlen (p_name);
+
+    p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;
+
+    UINT8_TO_BE_STREAM (p, LLCP_SDREQ_TYPE);
+    UINT8_TO_BE_STREAM (p, (1 + name_len));
+    UINT8_TO_BE_STREAM (p, tid);
+    ARRAY_TO_BE_STREAM (p, p_name, name_len);
+
+    llcp_cb.sdp_cb.p_snl->len += LLCP_SDREQ_MIN_LEN + name_len;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_send_sdreq
+**
+** Description      Send Service Discovery Request
+**
+**
+** Returns          LLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_sdp_send_sdreq (UINT8 tid, char *p_name)
+{
+    tLLCP_STATUS status;
+    UINT16       name_len;
+    UINT16       available_bytes;
+
+    LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdreq (): tid=0x%x, ServiceName=%s", tid, p_name);
+
+    /* if there is no pending SNL */
+    if (!llcp_cb.sdp_cb.p_snl)
+    {
+        llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+        if (llcp_cb.sdp_cb.p_snl)
+        {
+            llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+            llcp_cb.sdp_cb.p_snl->len    = 0;
+        }
+    }
+
+    if (llcp_cb.sdp_cb.p_snl)
+    {
+        available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl)
+                          - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset
+                          - llcp_cb.sdp_cb.p_snl->len;
+
+        name_len = (UINT16) strlen (p_name);
+
+        /* if SDREQ parameter can be added in SNL */
+        if (  (available_bytes >= LLCP_SDREQ_MIN_LEN + name_len)
+            &&(llcp_cb.sdp_cb.p_snl->len + LLCP_SDREQ_MIN_LEN + name_len <= llcp_cb.lcb.effective_miu)  )
+        {
+            llcp_sdp_add_sdreq (tid, p_name);
+            status = LLCP_STATUS_SUCCESS;
+        }
+        else
+        {
+            /* send pending SNL PDU to LM */
+            llcp_sdp_check_send_snl ();
+
+            llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+            if (llcp_cb.sdp_cb.p_snl)
+            {
+                llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+                llcp_cb.sdp_cb.p_snl->len    = 0;
+
+                llcp_sdp_add_sdreq (tid, p_name);
+
+                status = LLCP_STATUS_SUCCESS;
+            }
+            else
+            {
+                status = LLCP_STATUS_FAIL;
+            }
+        }
+    }
+    else
+    {
+        status = LLCP_STATUS_FAIL;
+    }
+
+    /* if LM is waiting for PDUs from upper layer */
+    if (  (status == LLCP_STATUS_SUCCESS)
+        &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)  )
+    {
+        llcp_link_check_send_data ();
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_add_sdres
+**
+** Description      Add Service Discovery Response into SNL PDU
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_sdp_add_sdres (UINT8 tid, UINT8 sap)
+{
+    UINT8  *p;
+
+    p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;
+
+    UINT8_TO_BE_STREAM (p, LLCP_SDRES_TYPE);
+    UINT8_TO_BE_STREAM (p, LLCP_SDRES_LEN);
+    UINT8_TO_BE_STREAM (p, tid);
+    UINT8_TO_BE_STREAM (p, sap);
+
+    llcp_cb.sdp_cb.p_snl->len += 2 + LLCP_SDRES_LEN;   /* type and length */
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_send_sdres
+**
+** Description      Send Service Discovery Response
+**
+**
+** Returns          LLCP_STATUS
+**
+*******************************************************************************/
+static tLLCP_STATUS llcp_sdp_send_sdres (UINT8 tid, UINT8 sap)
+{
+    tLLCP_STATUS status;
+    UINT16       available_bytes;
+
+    LLCP_TRACE_DEBUG2 ("llcp_sdp_send_sdres (): tid=0x%x, SAP=0x%x", tid, sap);
+
+    /* if there is no pending SNL */
+    if (!llcp_cb.sdp_cb.p_snl)
+    {
+        llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+        if (llcp_cb.sdp_cb.p_snl)
+        {
+            llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+            llcp_cb.sdp_cb.p_snl->len    = 0;
+        }
+    }
+
+    if (llcp_cb.sdp_cb.p_snl)
+    {
+        available_bytes = GKI_get_buf_size (llcp_cb.sdp_cb.p_snl)
+                          - BT_HDR_SIZE - llcp_cb.sdp_cb.p_snl->offset
+                          - llcp_cb.sdp_cb.p_snl->len;
+
+        /* if SDRES parameter can be added in SNL */
+        if (  (available_bytes >= 2 + LLCP_SDRES_LEN)
+            &&(llcp_cb.sdp_cb.p_snl->len + 2 + LLCP_SDRES_LEN <= llcp_cb.lcb.effective_miu)  )
+        {
+            llcp_sdp_add_sdres (tid, sap);
+            status = LLCP_STATUS_SUCCESS;
+        }
+        else
+        {
+            /* send pending SNL PDU to LM */
+            llcp_sdp_check_send_snl ();
+
+            llcp_cb.sdp_cb.p_snl = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+            if (llcp_cb.sdp_cb.p_snl)
+            {
+                llcp_cb.sdp_cb.p_snl->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + LLCP_PDU_HEADER_SIZE;
+                llcp_cb.sdp_cb.p_snl->len    = 0;
+
+                llcp_sdp_add_sdres (tid, sap);
+
+                status = LLCP_STATUS_SUCCESS;
+            }
+            else
+            {
+                status = LLCP_STATUS_FAIL;
+            }
+        }
+    }
+    else
+    {
+        status = LLCP_STATUS_FAIL;
+    }
+
+    /* if LM is waiting for PDUs from upper layer */
+    if (  (status == LLCP_STATUS_SUCCESS)
+        &&(llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)  )
+    {
+        llcp_link_check_send_data ();
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_get_sap_by_name
+**
+** Description      Search SAP by service name
+**
+**
+** Returns          SAP if success
+**
+*******************************************************************************/
+UINT8 llcp_sdp_get_sap_by_name (char *p_name, UINT8 length)
+{
+    UINT8        sap;
+    tLLCP_APP_CB *p_app_cb;
+
+    for (sap = LLCP_SAP_SDP; sap <= LLCP_UPPER_BOUND_SDP_SAP; sap++)
+    {
+        p_app_cb = llcp_util_get_app_cb (sap);
+
+        if (  (p_app_cb)
+            &&(p_app_cb->p_app_cback)
+            &&(strlen((char*)p_app_cb->p_service_name) == length)
+            &&(!strncmp((char*)p_app_cb->p_service_name, p_name, length))  )
+        {
+            /* if device is under LLCP DTA testing */
+            if (  (llcp_cb.p_dta_cback)
+                &&(!strncmp((char*)p_app_cb->p_service_name, "urn:nfc:sn:cl-echo-in", length))  )
+            {
+                llcp_cb.dta_snl_resp = TRUE;
+            }
+            return (sap);
+        }
+    }
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_return_sap
+**
+** Description      Report TID and SAP to requester
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+static void llcp_sdp_return_sap (UINT8 tid, UINT8 sap)
+{
+    UINT8 i;
+
+    LLCP_TRACE_DEBUG2 ("llcp_sdp_return_sap (): tid=0x%x, SAP=0x%x", tid, sap);
+
+    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
+    {
+        if (  (llcp_cb.sdp_cb.transac[i].p_cback)
+            &&(llcp_cb.sdp_cb.transac[i].tid == tid)  )
+        {
+            (*llcp_cb.sdp_cb.transac[i].p_cback) (tid, sap);
+
+            llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_proc_deactivation
+**
+** Description      Report SDP failure for any pending request because of deactivation
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_sdp_proc_deactivation (void)
+{
+    UINT8 i;
+
+    LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_deactivation ()");
+
+    for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
+    {
+        if (llcp_cb.sdp_cb.transac[i].p_cback)
+        {
+            (*llcp_cb.sdp_cb.transac[i].p_cback) (llcp_cb.sdp_cb.transac[i].tid, 0x00);
+
+            llcp_cb.sdp_cb.transac[i].p_cback = NULL;
+        }
+    }
+
+    /* free any pending SNL PDU */
+    if (llcp_cb.sdp_cb.p_snl)
+    {
+        GKI_freebuf (llcp_cb.sdp_cb.p_snl);
+        llcp_cb.sdp_cb.p_snl = NULL;
+    }
+
+    llcp_cb.sdp_cb.next_tid = 0;
+    llcp_cb.dta_snl_resp = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_sdp_proc_snl
+**
+** Description      Process SDREQ and SDRES in SNL
+**
+**
+** Returns          LLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_sdp_proc_snl (UINT16 sdu_length, UINT8 *p)
+{
+    UINT8  type, length, tid, sap, *p_value;
+
+    LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl ()");
+
+    if ((llcp_cb.lcb.agreed_major_version < LLCP_MIN_SNL_MAJOR_VERSION)||
+       ((llcp_cb.lcb.agreed_major_version == LLCP_MIN_SNL_MAJOR_VERSION)&&(llcp_cb.lcb.agreed_minor_version < LLCP_MIN_SNL_MINOR_VERSION)))
+    {
+        LLCP_TRACE_DEBUG0 ("llcp_sdp_proc_snl(): version number less than 1.1, SNL not supported.");
+        return LLCP_STATUS_FAIL;
+    }
+    while (sdu_length >= 2) /* at least type and length */
+    {
+        BE_STREAM_TO_UINT8 (type, p);
+        BE_STREAM_TO_UINT8 (length, p);
+
+        switch (type)
+        {
+        case LLCP_SDREQ_TYPE:
+            if (  (length > 1)                /* TID and sevice name */
+                &&(sdu_length >= 2 + length)  ) /* type, length, TID and service name */
+            {
+                p_value = p;
+                BE_STREAM_TO_UINT8 (tid, p_value);
+                sap = llcp_sdp_get_sap_by_name ((char*) p_value, (UINT8) (length - 1));
+                llcp_sdp_send_sdres (tid, sap);
+            }
+            else
+            {
+                LLCP_TRACE_ERROR1 ("llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDREQ_TYPE", length);
+            }
+            break;
+
+        case LLCP_SDRES_TYPE:
+            if (  (length == LLCP_SDRES_LEN)  /* TID and SAP */
+                &&(sdu_length >= 2 + length)  ) /* type, length, TID and SAP */
+            {
+                p_value = p;
+                BE_STREAM_TO_UINT8 (tid, p_value);
+                BE_STREAM_TO_UINT8 (sap, p_value);
+                llcp_sdp_return_sap (tid, sap);
+            }
+            else
+            {
+                LLCP_TRACE_ERROR1 ("llcp_sdp_proc_snl (): bad length (%d) in LLCP_SDRES_TYPE", length);
+            }
+            break;
+
+        default:
+            LLCP_TRACE_WARNING1 ("llcp_sdp_proc_snl (): Unknown type (0x%x) is ignored", type);
+            break;
+        }
+
+        if (sdu_length >= 2 + length)   /* type, length, value */
+        {
+            sdu_length -= 2 + length;
+            p += length;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    if (sdu_length)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_sdp_proc_snl (): Bad format of SNL");
+        return LLCP_STATUS_FAIL;
+    }
+    else
+    {
+        return LLCP_STATUS_SUCCESS;
+    }
+}
diff --git a/src/nfc/llcp/llcp_util.c b/src/nfc/llcp/llcp_util.c
new file mode 100644
index 0000000..b11fbbc
--- /dev/null
+++ b/src/nfc/llcp/llcp_util.c
@@ -0,0 +1,912 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the LLCP utilities
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+#include "llcp_int.h"
+#include "llcp_defs.h"
+#include "nfc_int.h"
+
+/*******************************************************************************
+**
+** Function         llcp_util_parse_link_params
+**
+** Description      Parse LLCP Link parameters
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+BOOLEAN llcp_util_parse_link_params (UINT16 length, UINT8 *p_bytes)
+{
+    UINT8 param_type, param_len, *p = p_bytes;
+
+    while (length)
+    {
+        BE_STREAM_TO_UINT8 (param_type, p);
+        length--;
+
+        switch (param_type)
+        {
+        case LLCP_VERSION_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_version, p);
+            LLCP_TRACE_DEBUG1 ("Peer Version - 0x%02X", llcp_cb.lcb.peer_version);
+            break;
+
+        case LLCP_MIUX_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT16 (llcp_cb.lcb.peer_miu, p);
+            llcp_cb.lcb.peer_miu &= LLCP_MIUX_MASK;
+            llcp_cb.lcb.peer_miu += LLCP_DEFAULT_MIU;
+            LLCP_TRACE_DEBUG1 ("Peer MIU - %d bytes", llcp_cb.lcb.peer_miu);
+            break;
+
+        case LLCP_WKS_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT16 (llcp_cb.lcb.peer_wks, p);
+            LLCP_TRACE_DEBUG1 ("Peer WKS - 0x%04X", llcp_cb.lcb.peer_wks);
+            break;
+
+        case LLCP_LTO_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_lto, p);
+            llcp_cb.lcb.peer_lto *= LLCP_LTO_UNIT;  /* 10ms unit */
+            LLCP_TRACE_DEBUG1 ("Peer LTO - %d ms", llcp_cb.lcb.peer_lto);
+            break;
+
+        case LLCP_OPT_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT8 (llcp_cb.lcb.peer_opt, p);
+            LLCP_TRACE_DEBUG1 ("Peer OPT - 0x%02X", llcp_cb.lcb.peer_opt);
+            break;
+
+        default:
+            LLCP_TRACE_ERROR1 ("llcp_util_parse_link_params (): Unexpected type 0x%x", param_type);
+            BE_STREAM_TO_UINT8 (param_len, p);
+            p += param_len;
+            break;
+        }
+
+        if (length >= param_len + 1)
+            length -= param_len + 1;
+        else
+        {
+            LLCP_TRACE_ERROR0 ("llcp_util_parse_link_params (): Bad LTV's");
+            return (FALSE);
+        }
+    }
+    return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_adjust_ll_congestion
+**
+** Description      adjust tx/rx congestion thresholds on logical link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_adjust_ll_congestion (void)
+{
+    /* buffer quota is allocated equally for each logical data link */
+    if (llcp_cb.num_logical_data_link)
+    {
+        llcp_cb.ll_tx_congest_start = llcp_cb.max_num_ll_tx_buff / llcp_cb.num_logical_data_link;
+        llcp_cb.ll_rx_congest_start = llcp_cb.max_num_ll_rx_buff / llcp_cb.num_logical_data_link;
+    }
+    else
+    {
+        llcp_cb.ll_tx_congest_start = llcp_cb.max_num_ll_tx_buff;
+        llcp_cb.ll_rx_congest_start = llcp_cb.max_num_ll_rx_buff;
+    }
+
+    /* at least one for each logical data link */
+    if (llcp_cb.ll_tx_congest_start == 0)
+    {
+        llcp_cb.ll_tx_congest_start = 1;
+    }
+    if (llcp_cb.ll_rx_congest_start == 0)
+    {
+        llcp_cb.ll_rx_congest_start = 1;
+    }
+
+    if (llcp_cb.ll_tx_congest_start > 1)
+    {
+        llcp_cb.ll_tx_congest_end = 1;
+    }
+    else
+    {
+        llcp_cb.ll_tx_congest_end = 0;
+    }
+
+    LLCP_TRACE_DEBUG4 ("num_logical_data_link=%d, ll_tx_congest_start=%d, ll_tx_congest_end=%d, ll_rx_congest_start=%d",
+                       llcp_cb.num_logical_data_link,
+                       llcp_cb.ll_tx_congest_start,
+                       llcp_cb.ll_tx_congest_end,
+                       llcp_cb.ll_rx_congest_start);
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_adjust_dl_rx_congestion
+**
+** Description      adjust rx congestion thresholds on data link
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_adjust_dl_rx_congestion (void)
+{
+    UINT8 idx, rx_congest_start;
+
+    if (llcp_cb.num_data_link_connection)
+    {
+        rx_congest_start = llcp_cb.num_rx_buff / llcp_cb.num_data_link_connection;
+
+        for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+        {
+            if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+            {
+                if (rx_congest_start > llcp_cb.dlcb[idx].local_rw)
+                {
+                    /*
+                    ** set rx congestion threshold LLCP_DL_MIN_RX_CONGEST at least
+                    ** so, we don't need to flow off too often.
+                    */
+                    if (llcp_cb.dlcb[idx].local_rw + 1 > LLCP_DL_MIN_RX_CONGEST)
+                        llcp_cb.dlcb[idx].rx_congest_threshold = llcp_cb.dlcb[idx].local_rw + 1;
+                    else
+                        llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
+                }
+                else
+                {
+                    llcp_cb.dlcb[idx].rx_congest_threshold = LLCP_DL_MIN_RX_CONGEST;
+                }
+
+                LLCP_TRACE_DEBUG3 ("DLC[%d], local_rw=%d, rx_congest_threshold=%d",
+                                   idx,
+                                   llcp_cb.dlcb[idx].local_rw,
+                                   llcp_cb.dlcb[idx].rx_congest_threshold);
+            }
+        }
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_check_rx_congested_status
+**
+** Description      Update rx congested status
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_check_rx_congested_status (void)
+{
+    UINT8 idx;
+
+    if (llcp_cb.overall_rx_congested)
+    {
+        /* check if rx congestion clear */
+        if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu <= llcp_cb.overall_rx_congest_end)
+        {
+            LLCP_TRACE_DEBUG3 ("llcp_util_check_rx_congested_status (): rx link is uncongested, %d+%d <= %d",
+                                llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
+                                llcp_cb.overall_rx_congest_end);
+
+            llcp_cb.overall_rx_congested = FALSE;
+
+            for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+            {
+                /* set flag to clear local busy status on data link connections */
+                if (  (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+                    &&(llcp_cb.dlcb[idx].is_rx_congested == FALSE)  )
+                {
+                    llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+                }
+            }
+        }
+    }
+    else
+    {
+        /* check if rx link is congested */
+        if (llcp_cb.total_rx_ui_pdu + llcp_cb.total_rx_i_pdu >= llcp_cb.overall_rx_congest_start)
+        {
+            LLCP_TRACE_WARNING3 ("llcp_util_check_rx_congested_status (): rx link is congested, %d+%d >= %d",
+                                  llcp_cb.total_rx_ui_pdu, llcp_cb.total_rx_i_pdu,
+                                  llcp_cb.overall_rx_congest_start);
+
+            llcp_cb.overall_rx_congested = TRUE;
+
+            /* rx link congestion is started, send RNR to remote end point */
+            for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+            {
+                if (  (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
+                    &&(llcp_cb.dlcb[idx].is_rx_congested == FALSE)  )
+                {
+                    llcp_cb.dlcb[idx].flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+                }
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_ui
+**
+** Description      Send UI PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_send_ui (UINT8 ssap, UINT8 dsap, tLLCP_APP_CB *p_app_cb, BT_HDR *p_msg)
+{
+    UINT8        *p;
+    tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
+
+    p_msg->offset -= LLCP_PDU_HEADER_SIZE;
+    p_msg->len    += LLCP_PDU_HEADER_SIZE;
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_UI_TYPE, ssap));
+
+    GKI_enqueue (&p_app_cb->ui_xmit_q, p_msg);
+    llcp_cb.total_tx_ui_pdu++;
+
+    llcp_link_check_send_data ();
+
+    if (  (p_app_cb->is_ui_tx_congested)
+        ||(p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
+        ||(llcp_cb.overall_tx_congested)
+        ||(llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)  )
+    {
+        /* set congested here so overall congestion check routine will not report event again, */
+        /* or notify uncongestion later                                                        */
+        p_app_cb->is_ui_tx_congested = TRUE;
+
+        LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congested: ui_xmit_q.count=%d",
+                              ssap, p_app_cb->ui_xmit_q.count);
+
+        status = LLCP_STATUS_CONGESTED;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_disc
+**
+** Description      Send DISC PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_send_disc (UINT8 dsap, UINT8 ssap)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_msg->len      = LLCP_PDU_DISC_SIZE;
+        p_msg->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_DISC_TYPE, ssap));
+
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+        llcp_link_check_send_data ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_allocate_data_link
+**
+** Description      Allocate tLLCP_DLCB for data link connection
+**
+** Returns          tLLCP_DLCB *
+**
+******************************************************************************/
+tLLCP_DLCB *llcp_util_allocate_data_link (UINT8 reg_sap, UINT8 remote_sap)
+{
+    tLLCP_DLCB *p_dlcb = NULL;
+    int         idx;
+
+    LLCP_TRACE_DEBUG2 ("llcp_util_allocate_data_link (): reg_sap = 0x%x, remote_sap = 0x%x",
+                        reg_sap, remote_sap);
+
+    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
+    {
+        if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_IDLE)
+        {
+            p_dlcb = &(llcp_cb.dlcb[idx]);
+
+            memset (p_dlcb, 0, sizeof (tLLCP_DLCB));
+            break;
+        }
+    }
+
+    if (!p_dlcb)
+    {
+        LLCP_TRACE_ERROR0 ("llcp_util_allocate_data_link (): Out of DLCB");
+    }
+    else
+    {
+        p_dlcb->p_app_cb    = llcp_util_get_app_cb (reg_sap);
+        p_dlcb->local_sap   = reg_sap;
+        p_dlcb->remote_sap  = remote_sap;
+        p_dlcb->timer.param = (TIMER_PARAM_TYPE) p_dlcb;
+
+        /* this is for inactivity timer and congestion control. */
+        llcp_cb.num_data_link_connection++;
+
+        LLCP_TRACE_DEBUG3 ("llcp_util_allocate_data_link (): local_sap = 0x%x, remote_sap = 0x%x, num_data_link_connection = %d",
+                            p_dlcb->local_sap, p_dlcb->remote_sap, llcp_cb.num_data_link_connection);
+    }
+    return p_dlcb;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_deallocate_data_link
+**
+** Description      Deallocate tLLCP_DLCB
+**
+** Returns          void
+**
+******************************************************************************/
+void llcp_util_deallocate_data_link (tLLCP_DLCB *p_dlcb)
+{
+    if (p_dlcb)
+    {
+        LLCP_TRACE_DEBUG1 ("llcp_util_deallocate_data_link (): local_sap = 0x%x", p_dlcb->local_sap);
+
+        if (p_dlcb->state != LLCP_DLC_STATE_IDLE)
+        {
+            nfc_stop_quick_timer (&p_dlcb->timer);
+            llcp_dlc_flush_q (p_dlcb);
+
+            p_dlcb->state = LLCP_DLC_STATE_IDLE;
+
+            if (llcp_cb.num_data_link_connection > 0)
+            {
+                llcp_cb.num_data_link_connection--;
+            }
+
+            LLCP_TRACE_DEBUG1 ("llcp_util_deallocate_data_link (): num_data_link_connection = %d", llcp_cb.num_data_link_connection);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_connect
+**
+** Description      Send CONNECT PDU
+**
+** Returns          tLLCP_STATUS
+**
+******************************************************************************/
+tLLCP_STATUS llcp_util_send_connect (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+    UINT16  miu_len = 0, rw_len = 0, sn_len = 0;
+
+    if (p_params->miu != LLCP_DEFAULT_MIU)
+    {
+        miu_len = 4;    /* TYPE, LEN, 2 bytes MIU */
+    }
+    if (p_params->rw != LLCP_DEFAULT_RW)
+    {
+        rw_len = 3;     /* TYPE, LEN, 1 byte RW */
+        p_params->rw &= 0x0F;   /* only 4 bits  */
+    }
+    if ((strlen (p_params->sn)) && (p_dlcb->remote_sap == LLCP_SAP_SDP))
+    {
+        sn_len = (UINT16) (2 + strlen (p_params->sn));    /* TYPE, LEN, SN */
+    }
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_msg->len    = LLCP_PDU_HEADER_SIZE + miu_len + rw_len + sn_len;
+        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CONNECT_TYPE, p_dlcb->local_sap));
+
+        if (miu_len)
+        {
+            UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+            UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+            UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU);
+        }
+
+        if (rw_len)
+        {
+            UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE);
+            UINT8_TO_BE_STREAM (p, LLCP_RW_LEN);
+            UINT8_TO_BE_STREAM (p, p_params->rw);
+        }
+
+        if (sn_len)
+        {
+            UINT8_TO_BE_STREAM (p, LLCP_SN_TYPE);
+            UINT8_TO_BE_STREAM (p, sn_len - 2);
+            memcpy (p, p_params->sn, sn_len - 2);
+        }
+
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+        llcp_link_check_send_data ();
+
+        return LLCP_STATUS_SUCCESS;
+    }
+
+    return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_parse_connect
+**
+** Description      Parse CONNECT PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_parse_connect (UINT8  *p_bytes, UINT16 length, tLLCP_CONNECTION_PARAMS *p_params)
+{
+    UINT8 param_type, param_len, *p = p_bytes;
+
+    p_params->miu = LLCP_DEFAULT_MIU;
+    p_params->rw  = LLCP_DEFAULT_RW;
+    p_params->sn[0] = 0;
+
+    while (length)
+    {
+        BE_STREAM_TO_UINT8 (param_type, p);
+        length--;
+
+        switch (param_type)
+        {
+        case LLCP_MIUX_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT16 (p_params->miu, p);
+            p_params->miu &= LLCP_MIUX_MASK;
+            p_params->miu += LLCP_DEFAULT_MIU;
+
+            LLCP_TRACE_DEBUG1 ("llcp_util_parse_connect (): LLCP_MIUX_TYPE:%d", p_params->miu);
+            break;
+
+        case LLCP_RW_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT8 (p_params->rw, p);
+            p_params->rw &= 0x0F;
+
+            LLCP_TRACE_DEBUG1 ("llcp_util_parse_connect (): LLCP_RW_TYPE:%d", p_params->rw);
+            break;
+
+        case LLCP_SN_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+
+            if (param_len <= LLCP_MAX_SN_LEN)
+            {
+                memcpy (p_params->sn, p, param_len);
+                p_params->sn[param_len] = 0;
+            }
+            else
+            {
+                memcpy (p_params->sn, p, LLCP_MAX_SN_LEN);
+                p_params->sn[LLCP_MAX_SN_LEN] = 0;
+            }
+            p += param_len;
+
+            LLCP_TRACE_DEBUG1 ("llcp_util_parse_connect (): LLCP_SN_TYPE:<%s>", p_params->sn);
+            break;
+
+        default:
+            LLCP_TRACE_ERROR1 ("llcp_util_parse_connect (): Unexpected type 0x%x", param_type);
+            BE_STREAM_TO_UINT8 (param_len, p);
+            p += param_len;
+            break;
+        }
+
+        /* check remaining lengh */
+        if (length >= param_len + 1)
+        {
+            length -= param_len + 1;
+        }
+        else
+        {
+            LLCP_TRACE_ERROR0 ("llcp_util_parse_connect (): Bad LTV's");
+            return LLCP_STATUS_FAIL;
+        }
+    }
+    return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_cc
+**
+** Description      Send CC PDU
+**
+** Returns          tLLCP_STATUS
+**
+******************************************************************************/
+tLLCP_STATUS llcp_util_send_cc (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+    UINT16  miu_len = 0, rw_len = 0;
+
+    if (p_params->miu != LLCP_DEFAULT_MIU)
+    {
+        miu_len = 4;
+    }
+    if (p_params->rw != LLCP_DEFAULT_RW)
+    {
+        rw_len = 3;
+        p_params->rw &= 0x0F;
+    }
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_msg->len      = LLCP_PDU_HEADER_SIZE + miu_len + rw_len;
+        p_msg->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CC_TYPE, p_dlcb->local_sap));
+
+        if (miu_len)
+        {
+            UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
+            UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
+            UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU);
+        }
+
+        if (rw_len)
+        {
+            UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE);
+            UINT8_TO_BE_STREAM (p, LLCP_RW_LEN);
+            UINT8_TO_BE_STREAM (p, p_params->rw);
+        }
+
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+        llcp_link_check_send_data ();
+
+        return LLCP_STATUS_SUCCESS;
+    }
+
+    return LLCP_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_parse_cc
+**
+** Description      Parse CC PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_parse_cc (UINT8 *p_bytes, UINT16 length, UINT16 *p_miu, UINT8 *p_rw)
+{
+    UINT8 param_type, param_len, *p = p_bytes;
+
+    *p_miu = LLCP_DEFAULT_MIU;
+    *p_rw  = LLCP_DEFAULT_RW;
+
+    while (length)
+    {
+        BE_STREAM_TO_UINT8 (param_type, p);
+        length--;
+
+        switch (param_type)
+        {
+        case LLCP_MIUX_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT16 ((*p_miu), p);
+            (*p_miu) &= LLCP_MIUX_MASK;
+            (*p_miu) += LLCP_DEFAULT_MIU;
+
+            LLCP_TRACE_DEBUG1 ("llcp_util_parse_cc (): LLCP_MIUX_TYPE:%d", *p_miu);
+            break;
+
+        case LLCP_RW_TYPE:
+            BE_STREAM_TO_UINT8 (param_len, p);
+            BE_STREAM_TO_UINT8 ((*p_rw), p);
+            (*p_rw) &= 0x0F;
+
+            LLCP_TRACE_DEBUG1 ("llcp_util_parse_cc (): LLCP_RW_TYPE:%d", *p_rw);
+            break;
+
+        default:
+            LLCP_TRACE_ERROR1 ("llcp_util_parse_cc (): Unexpected type 0x%x", param_type);
+            BE_STREAM_TO_UINT8 (param_len, p);
+            p += param_len;
+            break;
+        }
+
+        if (length >= param_len + 1)
+            length -= param_len + 1;
+        else
+        {
+            LLCP_TRACE_ERROR0 ("llcp_util_parse_cc (): Bad LTV's");
+            return LLCP_STATUS_FAIL;
+        }
+    }
+    return LLCP_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_dm
+**
+** Description      Send DM PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_send_dm (UINT8 dsap, UINT8 ssap, UINT8 reason)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_msg->len    = LLCP_PDU_DM_SIZE;
+        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_DM_TYPE, ssap));
+        UINT8_TO_BE_STREAM  (p, reason);
+
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+        llcp_link_check_send_data ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_build_info_pdu
+**
+** Description      Add DSAP, PTYPE, SSAP and sequence numbers and update local ack
+**                  sequence
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_build_info_pdu (tLLCP_DLCB *p_dlcb, BT_HDR *p_msg)
+{
+    UINT8  *p;
+    UINT8  rcv_seq;
+
+    p_msg->offset -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+    p_msg->len    += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_I_TYPE, p_dlcb->local_sap));
+
+    /* if local_busy or rx congested then do not update receive sequence number to flow off */
+    if (  (p_dlcb->local_busy)
+        ||(p_dlcb->is_rx_congested)
+        ||(llcp_cb.overall_rx_congested)  )
+    {
+        rcv_seq = p_dlcb->sent_ack_seq;
+    }
+    else
+    {
+        p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
+        rcv_seq = p_dlcb->sent_ack_seq;
+    }
+    UINT8_TO_BE_STREAM  (p, LLCP_GET_SEQUENCE (p_dlcb->next_tx_seq, rcv_seq));
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_frmr
+**
+** Description      Send FRMR PDU
+**
+** Returns          tLLCP_STATUS
+**
+*******************************************************************************/
+tLLCP_STATUS llcp_util_send_frmr (tLLCP_DLCB *p_dlcb, UINT8 flags, UINT8 ptype, UINT8 sequence)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_msg->len      = LLCP_PDU_FRMR_SIZE;
+        p_msg->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_FRMR_TYPE, p_dlcb->local_sap));
+        UINT8_TO_BE_STREAM (p, (flags << 4) | ptype);
+        UINT8_TO_BE_STREAM (p, sequence);
+        UINT8_TO_BE_STREAM (p, (p_dlcb->next_tx_seq << 4) | p_dlcb->next_rx_seq);
+        UINT8_TO_BE_STREAM (p, (p_dlcb->rcvd_ack_seq << 4) | p_dlcb->sent_ack_seq);
+
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+        llcp_link_check_send_data ();
+
+        return LLCP_STATUS_SUCCESS;
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("llcp_util_send_frmr (): Out of resource");
+        return LLCP_STATUS_FAIL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_send_rr_rnr
+**
+** Description      Send RR or RNR PDU
+**
+** Returns          void
+**
+*******************************************************************************/
+void llcp_util_send_rr_rnr (tLLCP_DLCB *p_dlcb)
+{
+    BT_HDR *p_msg;
+    UINT8  *p;
+    UINT8   pdu_type;
+    UINT8   pdu_size;
+    UINT8   rcv_seq;
+
+    /* if no indication of change in local busy or rx congestion */
+    if ((p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_RR_RNR) == 0)
+    {
+        /* if all ack is sent */
+        if (p_dlcb->sent_ack_seq == p_dlcb->next_rx_seq)
+        {
+            /* we don't need to send RR/RNR */
+            return;
+        }
+        else
+        {
+            /* if rx flow off because of local busy or congestion */
+            if (  (p_dlcb->local_busy)
+                ||(p_dlcb->is_rx_congested)
+                ||(llcp_cb.overall_rx_congested)  )
+            {
+                /* don't send RR/RNR */
+                return;
+            }
+        }
+    }
+
+    if (  (p_dlcb->local_busy)
+        ||(p_dlcb->is_rx_congested)
+        ||(llcp_cb.overall_rx_congested)  )
+    {
+        LLCP_TRACE_DEBUG3 ("llcp_util_send_rr_rnr (): local_busy=%d,is_rx_congested=%d,overall_rx_congested=%d",
+                            p_dlcb->local_busy, p_dlcb->is_rx_congested, llcp_cb.overall_rx_congested);
+
+        /* if local_busy or rx congested then do not update receive sequence number to flow off */
+        pdu_type = LLCP_PDU_RNR_TYPE;
+        pdu_size = LLCP_PDU_RNR_SIZE;
+        rcv_seq = p_dlcb->sent_ack_seq;
+    }
+    else
+    {
+        pdu_type = LLCP_PDU_RR_TYPE;
+        pdu_size = LLCP_PDU_RR_SIZE;
+
+        p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
+        rcv_seq = p_dlcb->sent_ack_seq;
+    }
+
+    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
+
+    if (p_msg)
+    {
+        p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
+
+        p_msg->len    = pdu_size;
+        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, pdu_type, p_dlcb->local_sap));
+
+        UINT8_TO_BE_STREAM (p, rcv_seq);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+        LLCP_TRACE_DEBUG5 ("LLCP TX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
+                            p_dlcb->next_rx_seq,
+                            p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
+                            p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
+#endif
+        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
+        llcp_link_check_send_data ();
+    }
+    else
+    {
+        LLCP_TRACE_ERROR0 ("llcp_util_send_rr_rnr (): Out of resource");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         llcp_util_get_app_cb
+**
+** Description      get pointer of application registered control block by SAP
+**
+** Returns          tLLCP_APP_CB *
+**
+*******************************************************************************/
+tLLCP_APP_CB *llcp_util_get_app_cb (UINT8 local_sap)
+{
+    tLLCP_APP_CB *p_app_cb = NULL;
+
+    if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
+    {
+        if ((local_sap != LLCP_SAP_LM) && (local_sap < LLCP_MAX_WKS))
+        {
+            p_app_cb = &llcp_cb.wks_cb[local_sap];
+        }
+    }
+    else if (local_sap <= LLCP_UPPER_BOUND_SDP_SAP)
+    {
+        if (local_sap - LLCP_LOWER_BOUND_SDP_SAP < LLCP_MAX_SERVER)
+        {
+            p_app_cb = &llcp_cb.server_cb[local_sap - LLCP_LOWER_BOUND_SDP_SAP];
+        }
+    }
+    else if (local_sap <= LLCP_UPPER_BOUND_LOCAL_SAP)
+    {
+        if (local_sap - LLCP_LOWER_BOUND_LOCAL_SAP < LLCP_MAX_CLIENT)
+        {
+            p_app_cb = &llcp_cb.client_cb[local_sap - LLCP_LOWER_BOUND_LOCAL_SAP];
+        }
+    }
+
+    return (p_app_cb);
+}
diff --git a/src/nfc/nci/nci_hmsgs.c b/src/nfc/nci/nci_hmsgs.c
new file mode 100644
index 0000000..4bb6896
--- /dev/null
+++ b/src/nfc/nci/nci_hmsgs.c
@@ -0,0 +1,658 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains function of the NCI unit to format and send NCI
+ *  commands (for DH).
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if NFC_INCLUDED == TRUE
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_reset
+**
+** Description      compose and send CORE RESET command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_reset (UINT8 reset_type)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_RESET)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_RESET;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_RESET);
+    UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_RESET);
+    UINT8_TO_STREAM (pp, reset_type);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_init
+**
+** Description      compose and send CORE INIT command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_init (void)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_INIT)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_INIT;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_INIT);
+    UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_INIT);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_get_config
+**
+** Description      compose and send CORE GET_CONFIG command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_get_config (UINT8 *param_ids, UINT8 num_ids)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (num_ids)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + num_ids + 1;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_GET_CONFIG);
+    UINT8_TO_STREAM (pp, (UINT8) (num_ids + 1));
+    UINT8_TO_STREAM (pp, num_ids);
+    ARRAY_TO_STREAM (pp, param_ids, num_ids);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_set_config
+**
+** Description      compose and send CORE SET_CONFIG command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_set_config (UINT8 *p_param_tlvs, UINT8 tlv_size)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+    UINT8  num = 0, ulen, len, *pt;
+
+    if ((p = NCI_GET_CMD_BUF (tlv_size + 1)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event    = BT_EVT_TO_NFC_NCI;
+    p->len      = NCI_MSG_HDR_SIZE + tlv_size + 1;
+    p->offset   = NCI_MSG_OFFSET_SIZE;
+    pp          = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_SET_CONFIG);
+    UINT8_TO_STREAM (pp, (UINT8) (tlv_size + 1));
+    len         = tlv_size;
+    pt          = p_param_tlvs;
+    while (len > 1)
+    {
+        len     -= 2;
+        pt++;
+        num++;
+        ulen     = *pt++;
+        pt      += ulen;
+        if (len >= ulen)
+        {
+            len -= ulen;
+        }
+        else
+        {
+            GKI_freebuf (p);
+            return NCI_STATUS_FAILED;
+        }
+    }
+
+    UINT8_TO_STREAM (pp, num);
+    ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+    nfc_ncif_send_cmd (p);
+
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_conn_create
+**
+** Description      compose and send CORE CONN_CREATE command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_conn_create (UINT8 dest_type, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+    UINT8 size = NCI_CORE_PARAM_SIZE_CON_CREATE+tlv_size;
+
+    if ((p = NCI_GET_CMD_BUF (size)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_CON_CREATE;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_CONN_CREATE);
+    UINT8_TO_STREAM (pp, size);
+    UINT8_TO_STREAM (pp, dest_type);
+    UINT8_TO_STREAM (pp, num_tlv);
+    if (tlv_size)
+    {
+        ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+        p->len         += tlv_size;
+    }
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_core_conn_close
+**
+** Description      compose and send CORE CONN_CLOSE command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_core_conn_close (UINT8 conn_id)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_CON_CLOSE)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_CON_CLOSE;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_CORE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_CORE_CONN_CLOSE);
+    UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_CON_CLOSE);
+    UINT8_TO_STREAM (pp, conn_id);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+/*******************************************************************************
+**
+** Function         nci_snd_nfcee_discover
+**
+** Description      compose and send NFCEE Management NFCEE_DISCOVER command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_nfcee_discover (UINT8 discover_action)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_PARAM_SIZE_DISCOVER_NFCEE)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_PARAM_SIZE_DISCOVER_NFCEE;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_NFCEE_DISCOVER);
+    UINT8_TO_STREAM (pp, NCI_PARAM_SIZE_DISCOVER_NFCEE);
+    UINT8_TO_STREAM (pp, discover_action);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_nfcee_mode_set
+**
+** Description      compose and send NFCEE Management NFCEE MODE SET command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_nfcee_mode_set (UINT8 nfcee_id, UINT8 nfcee_mode)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_NFCEE_MODE_SET);
+    UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_NFCEE_MODE_SET);
+    UINT8_TO_STREAM (pp, nfcee_id);
+    UINT8_TO_STREAM (pp, nfcee_mode);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+#endif
+#endif
+
+/*******************************************************************************
+**
+** Function         nci_snd_discover_cmd
+**
+** Description      compose and send RF Management DISCOVER command to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_discover_cmd (UINT8 num, tNCI_DISCOVER_PARAMS *p_param)
+{
+    BT_HDR *p;
+    UINT8 *pp, *p_size, *p_start;
+    int xx;
+    int size;
+
+    size   = num * sizeof (tNCI_DISCOVER_PARAMS) + 1;
+    if ((p = NCI_GET_CMD_BUF (size)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DISCOVER);
+    p_size  = pp;
+    pp++;
+    p_start = pp;
+    UINT8_TO_STREAM (pp, num);
+    for (xx=0; xx<num; xx++)
+    {
+        UINT8_TO_STREAM (pp, p_param[xx].type);
+        UINT8_TO_STREAM (pp, p_param[xx].frequency);
+    }
+    *p_size = (UINT8) (pp - p_start);
+    p->len  = NCI_MSG_HDR_SIZE + *p_size;
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_discover_select_cmd
+**
+** Description      compose and send RF Management DISCOVER SELECT command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_discover_select_cmd (UINT8 rf_disc_id, UINT8 protocol, UINT8 rf_interface)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_DISCOVER_PARAM_SIZE_SELECT)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_DISCOVER_PARAM_SIZE_SELECT;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DISCOVER_SELECT);
+    UINT8_TO_STREAM (pp, NCI_DISCOVER_PARAM_SIZE_SELECT);
+    UINT8_TO_STREAM (pp, rf_disc_id);
+    UINT8_TO_STREAM (pp, protocol);
+    UINT8_TO_STREAM (pp, rf_interface);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_deactivate_cmd
+**
+** Description      compose and send RF Management DEACTIVATE command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_deactivate_cmd (UINT8 de_act_type )
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_DISCOVER_PARAM_SIZE_DEACT)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_DISCOVER_PARAM_SIZE_DEACT;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DEACTIVATE);
+    UINT8_TO_STREAM (pp, NCI_DISCOVER_PARAM_SIZE_DEACT);
+    UINT8_TO_STREAM (pp, de_act_type);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_discover_map_cmd
+**
+** Description      compose and send RF Management DISCOVER MAP command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_discover_map_cmd (UINT8 num, tNCI_DISCOVER_MAPS *p_maps)
+{
+    BT_HDR *p;
+    UINT8 *pp, *p_size, *p_start;
+    int xx;
+    int size;
+
+    size = num * sizeof (tNCI_DISCOVER_MAPS) + 1;
+
+    if ((p = NCI_GET_CMD_BUF (size)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_DISCOVER_MAP);
+    p_size  = pp;
+    pp++;
+    p_start = pp;
+    UINT8_TO_STREAM (pp, num);
+    for (xx = 0; xx < num; xx++)
+    {
+        UINT8_TO_STREAM (pp, p_maps[xx].protocol);
+        UINT8_TO_STREAM (pp, p_maps[xx].mode);
+        UINT8_TO_STREAM (pp, p_maps[xx].intf_type);
+    }
+    *p_size = (UINT8) (pp - p_start);
+    p->len  = NCI_MSG_HDR_SIZE + *p_size;
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+/*******************************************************************************
+**
+** Function         nci_snd_t3t_polling
+**
+** Description      compose and send RF Management T3T POLLING command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_t3t_polling (UINT16 system_code, UINT8 rc, UINT8 tsn)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = NCI_GET_CMD_BUF (NCI_RF_PARAM_SIZE_T3T_POLLING)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + NCI_RF_PARAM_SIZE_T3T_POLLING;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_T3T_POLLING);
+    UINT8_TO_STREAM (pp, NCI_RF_PARAM_SIZE_T3T_POLLING);
+    UINT16_TO_BE_STREAM (pp, system_code);
+    UINT8_TO_STREAM (pp, rc);
+    UINT8_TO_STREAM (pp, tsn);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_parameter_update_cmd
+**
+** Description      compose and send RF Management RF Communication Parameter
+**                  Update commandto command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_parameter_update_cmd (UINT8 *p_param_tlvs, UINT8 tlv_size)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+    UINT8  num = 0, ulen, len, *pt;
+
+    if ((p = NCI_GET_CMD_BUF (tlv_size + 1)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event    = BT_EVT_TO_NFC_NCI;
+    p->len      = NCI_MSG_HDR_SIZE + tlv_size + 1;
+    p->offset   = NCI_MSG_OFFSET_SIZE;
+    pp          = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_PARAMETER_UPDATE);
+    UINT8_TO_STREAM (pp, (UINT8) (tlv_size + 1));
+    len         = tlv_size;
+    pt          = p_param_tlvs;
+    while (len > 1)
+    {
+        len     -= 2;
+        pt++;
+        num++;
+        ulen     = *pt++;
+        pt      += ulen;
+        if (len >= ulen)
+        {
+            len -= ulen;
+        }
+        else
+        {
+            GKI_freebuf (p);
+            return NCI_STATUS_FAILED;
+        }
+    }
+
+    UINT8_TO_STREAM (pp, num);
+    ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+    nfc_ncif_send_cmd (p);
+
+    return (NCI_STATUS_OK);
+}
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+/*******************************************************************************
+**
+** Function         nci_snd_set_routing_cmd
+**
+** Description      compose and send RF Management SET_LISTEN_MODE_ROUTING command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_set_routing_cmd (BOOLEAN more, UINT8 target_handle, UINT8 num_tlv, UINT8 tlv_size, UINT8 *p_param_tlvs)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+    UINT8 size = tlv_size + 2;
+
+    if (tlv_size == 0)
+    {
+        /* just to terminate routing table
+         * 2 bytes (more=FALSE and num routing entries=0) */
+        size = 2;
+    }
+
+    if ((p = NCI_GET_CMD_BUF(size)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->len              = NCI_MSG_HDR_SIZE + size;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_SET_ROUTING);
+    UINT8_TO_STREAM (pp, size);
+    UINT8_TO_STREAM (pp, more);
+    if (size == 2)
+    {
+        UINT8_TO_STREAM (pp, 0);
+    }
+    else
+    {
+        UINT8_TO_STREAM (pp, num_tlv);
+        ARRAY_TO_STREAM (pp, p_param_tlvs, tlv_size);
+    }
+    nfc_ncif_send_cmd (p);
+
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nci_snd_get_routing_cmd
+**
+** Description      compose and send RF Management GET_LISTEN_MODE_ROUTING command
+**                  to command queue
+**
+** Returns          status
+**
+*******************************************************************************/
+UINT8 nci_snd_get_routing_cmd (void)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+    UINT8   param_size = 0;
+
+    if ((p = NCI_GET_CMD_BUF (param_size)) == NULL)
+        return (NCI_STATUS_FAILED);
+
+    p->event            = BT_EVT_TO_NFC_NCI;
+    p->len              = NCI_MSG_HDR_SIZE + param_size;
+    p->offset           = NCI_MSG_OFFSET_SIZE;
+    p->layer_specific   = 0;
+    pp                  = (UINT8 *) (p + 1) + p->offset;
+
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_RF_MANAGE);
+    NCI_MSG_BLD_HDR1 (pp, NCI_MSG_RF_GET_ROUTING);
+    UINT8_TO_STREAM (pp, param_size);
+
+    nfc_ncif_send_cmd (p);
+    return (NCI_STATUS_OK);
+}
+#endif
+#endif
+
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/nci/nci_hrcv.c b/src/nfc/nci/nci_hrcv.c
new file mode 100644
index 0000000..b9f9bcb
--- /dev/null
+++ b/src/nfc/nci/nci_hrcv.c
@@ -0,0 +1,481 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains function of the NFC unit to receive/process NCI
+ *  commands.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "gki.h"
+
+#if NFC_INCLUDED == TRUE
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+
+/*******************************************************************************
+**
+** Function         nci_proc_core_rsp
+**
+** Description      Process NCI responses in the CORE group
+**
+** Returns          TRUE-caller of this function to free the GKI buffer p_msg
+**
+*******************************************************************************/
+BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *pp, len, op_code;
+    BOOLEAN free = TRUE;
+    UINT8   *p_old = nfc_cb.last_cmd;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    NFC_TRACE_DEBUG1 ("nci_proc_core_rsp opcode:0x%x", op_code);
+    len = *pp++;
+
+    /* process the message based on the opcode and message type */
+    switch (op_code)
+    {
+    case NCI_MSG_CORE_RESET:
+        nfc_ncif_proc_reset_rsp (pp, FALSE);
+        break;
+
+    case NCI_MSG_CORE_INIT:
+        nfc_ncif_proc_init_rsp (p_msg);
+        free = FALSE;
+        break;
+
+    case NCI_MSG_CORE_GET_CONFIG:
+        nfc_ncif_proc_get_config_rsp (p_msg);
+        break;
+
+    case NCI_MSG_CORE_SET_CONFIG:
+        nfc_ncif_set_config_status (pp, len);
+        break;
+
+    case NCI_MSG_CORE_CONN_CREATE:
+        nfc_ncif_proc_conn_create_rsp (p, p_msg->len, *p_old);
+        break;
+
+    case NCI_MSG_CORE_CONN_CLOSE:
+        nfc_ncif_report_conn_close_evt (*p_old, *pp);
+        break;
+
+    default:
+        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+        break;
+    }
+
+    return free;
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_core_ntf
+**
+** Description      Process NCI notifications in the CORE group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_core_ntf (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *pp, len, op_code;
+    UINT8   conn_id;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    NFC_TRACE_DEBUG1 ("nci_proc_core_ntf opcode:0x%x", op_code);
+    len = *pp++;
+
+    /* process the message based on the opcode and message type */
+    switch (op_code)
+    {
+    case NCI_MSG_CORE_RESET:
+        nfc_ncif_proc_reset_rsp (pp, TRUE);
+        break;
+
+    case NCI_MSG_CORE_GEN_ERR_STATUS:
+        /* process the error ntf */
+        /* in case of timeout: notify the static connection callback */
+        nfc_ncif_event_status (NFC_GEN_ERROR_REVT, *pp);
+        nfc_ncif_error_status (NFC_RF_CONN_ID, *pp);
+        break;
+
+    case NCI_MSG_CORE_INTF_ERR_STATUS:
+        conn_id = *(pp+1);
+        nfc_ncif_error_status (conn_id, *pp);
+        break;
+
+    case NCI_MSG_CORE_CONN_CREDITS:
+        nfc_ncif_proc_credits(pp, len);
+        break;
+
+    default:
+        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+        break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nci_proc_rf_management_rsp
+**
+** Description      Process NCI responses in the RF Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_rf_management_rsp (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *pp, len, op_code;
+    UINT8   *p_old = nfc_cb.last_cmd;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    len = *pp++;
+
+    switch (op_code)
+    {
+    case NCI_MSG_RF_DISCOVER:
+        nfc_ncif_rf_management_status (NFC_START_DEVT, *pp);
+        break;
+
+    case NCI_MSG_RF_DISCOVER_SELECT:
+        nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp);
+        break;
+
+    case NCI_MSG_RF_T3T_POLLING:
+        break;
+
+    case NCI_MSG_RF_DISCOVER_MAP:
+        nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp);
+        break;
+
+    case NCI_MSG_RF_DEACTIVATE:
+        nfc_ncif_proc_deactivate (*pp, *p_old, FALSE);
+        break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+
+    case NCI_MSG_RF_SET_ROUTING:
+        nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp);
+        break;
+
+    case NCI_MSG_RF_GET_ROUTING:
+        if (*pp != NFC_STATUS_OK)
+            nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp);
+        break;
+#endif
+#endif
+
+    case NCI_MSG_RF_PARAMETER_UPDATE:
+        nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
+        break;
+
+    default:
+        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_rf_management_ntf
+**
+** Description      Process NCI notifications in the RF Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_rf_management_ntf (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *pp, len, op_code;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    len = *pp++;
+
+    switch (op_code)
+    {
+    case NCI_MSG_RF_DISCOVER :
+        nfc_ncif_proc_discover_ntf (p, p_msg->len);
+        break;
+
+    case NCI_MSG_RF_DEACTIVATE:
+        nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
+        break;
+
+    case NCI_MSG_RF_INTF_ACTIVATED:
+        nfc_ncif_proc_activate (pp, len);
+        break;
+
+    case NCI_MSG_RF_FIELD:
+        nfc_ncif_proc_rf_field_ntf (*pp);
+        break;
+
+    case NCI_MSG_RF_T3T_POLLING:
+        nfc_ncif_proc_t3t_polling_ntf (pp, len);
+        break;
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+
+    case NCI_MSG_RF_GET_ROUTING:
+        nfc_ncif_proc_get_routing (pp, len);
+        break;
+
+    case NCI_MSG_RF_EE_ACTION:
+        nfc_ncif_proc_ee_action (pp, len);
+        break;
+
+    case NCI_MSG_RF_EE_DISCOVERY_REQ:
+        nfc_ncif_proc_ee_discover_req (pp, len);
+        break;
+#endif
+#endif
+
+    default:
+        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+        break;
+    }
+}
+
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+
+/*******************************************************************************
+**
+** Function         nci_proc_ee_management_rsp
+**
+** Description      Process NCI responses in the NFCEE Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_ee_management_rsp (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *pp, len, op_code;
+    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+    tNFC_NFCEE_DISCOVER_REVT    nfcee_discover;
+    tNFC_NFCEE_INFO_REVT        nfcee_info;
+    tNFC_NFCEE_MODE_SET_REVT    mode_set;
+    tNFC_RESPONSE   *p_evt = (tNFC_RESPONSE *) &nfcee_info;
+    tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
+    UINT8   *p_old = nfc_cb.last_cmd;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
+    len = *pp++;
+
+    switch (op_code)
+    {
+    case NCI_MSG_NFCEE_DISCOVER:
+        p_evt                       = (tNFC_RESPONSE *) &nfcee_discover;
+        nfcee_discover.status       = *pp++;
+        nfcee_discover.num_nfcee    = *pp++;
+
+        if (nfcee_discover.status != NFC_STATUS_OK)
+            nfcee_discover.num_nfcee    = 0;
+
+        event                       = NFC_NFCEE_DISCOVER_REVT;
+        break;
+
+    case NCI_MSG_NFCEE_MODE_SET:
+        p_evt                   = (tNFC_RESPONSE *) &mode_set;
+        mode_set.status         = *pp;
+        mode_set.nfcee_id       = 0;
+        event                   = NFC_NFCEE_MODE_SET_REVT;
+        mode_set.nfcee_id       = *p_old++;
+        mode_set.mode           = *p_old++;
+        break;
+
+    default:
+        p_cback = NULL;
+        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+        break;
+    }
+
+    if (p_cback)
+        (*p_cback) (event, p_evt);
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_ee_management_ntf
+**
+** Description      Process NCI notifications in the NFCEE Management group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_ee_management_ntf (BT_HDR *p_msg)
+{
+    UINT8                 *p;
+    UINT8                 *pp, len, op_code;
+    tNFC_RESPONSE_CBACK   *p_cback = nfc_cb.p_resp_cback;
+    tNFC_NFCEE_INFO_REVT  nfcee_info;
+    tNFC_RESPONSE         *p_evt   = (tNFC_RESPONSE *) &nfcee_info;
+    tNFC_RESPONSE_EVT     event    = NFC_NFCEE_INFO_REVT;
+    UINT8                 xx;
+    UINT8                 yy;
+    UINT8                 ee_status;
+    tNFC_NFCEE_TLV        *p_tlv;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
+    len = *pp++;
+
+    if (op_code == NCI_MSG_NFCEE_DISCOVER)
+    {
+        nfcee_info.nfcee_id    = *pp++;
+        ee_status                   = *pp++;
+
+        nfcee_info.ee_status        = ee_status;
+        yy                          = *pp;
+        nfcee_info.num_interface    = *pp++;
+        p                           = pp;
+
+        if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
+            nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
+
+        for (xx = 0; xx < nfcee_info.num_interface; xx++)
+        {
+            nfcee_info.ee_interface[xx] = *pp++;
+        }
+
+        pp                              = p + yy;
+        nfcee_info.num_tlvs             = *pp++;
+        NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
+            nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
+
+        if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
+            nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
+
+        p_tlv = &nfcee_info.ee_tlv[0];
+
+        for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
+        {
+            p_tlv->tag  = *pp++;
+            p_tlv->len  = yy = *pp++;
+            NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
+            if (p_tlv->len > NFC_MAX_EE_INFO)
+                p_tlv->len = NFC_MAX_EE_INFO;
+            p   = pp;
+            STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len);
+            pp  = p += yy;
+        }
+    }
+    else
+    {
+        p_cback = NULL;
+        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
+    }
+
+    if (p_cback)
+        (*p_cback) (event, p_evt);
+}
+
+#endif
+#endif
+
+/*******************************************************************************
+**
+** Function         nci_proc_prop_rsp
+**
+** Description      Process NCI responses in the Proprietary group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_prop_rsp (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *p_evt;
+    UINT8   *pp, len, op_code;
+    tNFC_VS_CBACK   *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    len = *pp++;
+
+    /*If there's a pending/stored command, restore the associated address of the callback function */
+    if (p_cback)
+        (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
+}
+
+/*******************************************************************************
+**
+** Function         nci_proc_prop_ntf
+**
+** Description      Process NCI notifications in the Proprietary group
+**
+** Returns          void
+**
+*******************************************************************************/
+void nci_proc_prop_ntf (BT_HDR *p_msg)
+{
+    UINT8   *p;
+    UINT8   *p_evt;
+    UINT8   *pp, len, op_code;
+    int i;
+
+    /* find the start of the NCI message and parse the NCI header */
+    p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
+    pp  = p+1;
+    NCI_MSG_PRS_HDR1 (pp, op_code);
+    len = *pp++;
+
+    for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
+    {
+        if (nfc_cb.p_vs_cb[i])
+        {
+            (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt);
+        }
+    }
+}
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/ndef/ndef_cho_utils.c b/src/nfc/ndef/ndef_cho_utils.c
new file mode 100644
index 0000000..53c2bfc
--- /dev/null
+++ b/src/nfc/ndef/ndef_cho_utils.c
@@ -0,0 +1,562 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains source code for some utility functions to help parse
+ *  and build NFC Data Exchange Format (NDEF) messages for Connection
+ *  Handover
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "ndef_utils.h"
+
+/*******************************************************************************
+**
+** Static Local Functions
+*/
+static UINT8 *ndef_get_bt_oob_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                      char *p_id_str);
+
+/*******************************************************************************
+**
+** Static data
+*/
+
+/* Handover Request Record Type */
+static UINT8 hr_rec_type[HR_REC_TYPE_LEN] = { 0x48, 0x72 }; /* "Hr" */
+
+/* Handover Select Record Type */
+static UINT8 hs_rec_type[HS_REC_TYPE_LEN] = { 0x48, 0x73 }; /* "Hs" */
+
+/* Handover Carrier recrod Type */
+static UINT8 hc_rec_type[HC_REC_TYPE_LEN] = { 0x48, 0x63 }; /* "Hc" */
+
+/* Collision Resolution Record Type */
+static UINT8 cr_rec_type[CR_REC_TYPE_LEN] = { 0x63, 0x72 }; /* "cr" */
+
+/* Alternative Carrier Record Type */
+static UINT8 ac_rec_type[AC_REC_TYPE_LEN] = { 0x61, 0x63 }; /* "ac" */
+
+/* Error Record Type */
+static UINT8 err_rec_type[ERR_REC_TYPE_LEN] = { 0x65, 0x72, 0x72 }; /* "err" */
+
+/* Bluetooth OOB Data Type */
+static UINT8 *p_bt_oob_rec_type = (UINT8 *) "application/vnd.bluetooth.ep.oob";
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCreateWktHr
+**
+** Description      This function creates Handover Request Record with version.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCreateWktHr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                  UINT8 version )
+{
+    tNDEF_STATUS    status;
+
+    NDEF_MsgInit (p_msg, max_size, p_cur_size);
+
+    /* Add record with version */
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN,
+                             NULL, 0, &version, 1);
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCreateWktHs
+**
+** Description      This function creates Handover Select Record with version.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCreateWktHs (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                  UINT8 version )
+{
+    tNDEF_STATUS    status;
+
+    NDEF_MsgInit (p_msg, max_size, p_cur_size);
+
+    /* Add record with version */
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN,
+                             NULL, 0, &version, 1);
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktHc
+**
+** Description      This function adds Handover Carrier Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktHc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                               char  *p_id_str, UINT8 ctf,
+                               UINT8 carrier_type_len, UINT8 *p_carrier_type,
+                               UINT8 carrier_data_len, UINT8 *p_carrier_data)
+{
+    tNDEF_STATUS    status;
+    UINT8           payload[256], *p, id_len;
+    UINT32          payload_len;
+
+    if (carrier_type_len + carrier_data_len + 2 > 256)
+    {
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+    }
+
+    p = payload;
+
+    UINT8_TO_STREAM (p, (ctf & 0x07));
+    UINT8_TO_STREAM (p, carrier_type_len);
+    ARRAY_TO_STREAM (p, p_carrier_type, carrier_type_len);
+    ARRAY_TO_STREAM (p, p_carrier_data, carrier_data_len);
+
+    payload_len = (UINT32) carrier_type_len + carrier_data_len + 2;
+
+    id_len = (UINT8) strlen (p_id_str);
+
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_WKT, hc_rec_type, HC_REC_TYPE_LEN,
+                             (UINT8*) p_id_str, id_len, payload, payload_len);
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktAc
+**
+** Description      This function adds Alternative Carrier Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktAc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                               UINT8 cps, char *p_carrier_data_ref_str,
+                               UINT8 aux_data_ref_count, char *p_aux_data_ref_str[])
+{
+    tNDEF_STATUS    status;
+    UINT32          payload_len;
+    UINT8           ref_str_len, xx;
+    UINT8 *p_rec, *p;
+
+    /* get payload length first */
+
+    /* CPS, length of carrier data ref, carrier data ref, Aux data reference count */
+    payload_len = 3 + (UINT8) strlen (p_carrier_data_ref_str);
+    for (xx = 0; xx < aux_data_ref_count; xx++)
+    {
+        /* Aux Data Reference length (1 byte) */
+        payload_len += 1 + (UINT8) strlen (p_aux_data_ref_str[xx]);
+    }
+
+    /* reserve memory for payload */
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN,
+                             NULL, 0, NULL, payload_len);
+
+    if (status == NDEF_OK)
+    {
+        /* get AC record added at the end */
+        p_rec = NDEF_MsgGetLastRecInMsg (p_msg);
+
+        /* get start pointer of reserved payload */
+        p = NDEF_RecGetPayload (p_rec, &payload_len);
+
+        /* Add Carrier Power State */
+        UINT8_TO_BE_STREAM (p, cps);
+
+        /* Carrier Data Reference length */
+        ref_str_len = (UINT8) strlen (p_carrier_data_ref_str);
+
+        UINT8_TO_BE_STREAM (p, ref_str_len);
+
+        /* Carrier Data Reference */
+        ARRAY_TO_BE_STREAM (p, p_carrier_data_ref_str, ref_str_len);
+
+        /* Aux Data Reference Count */
+        UINT8_TO_BE_STREAM (p, aux_data_ref_count);
+
+        for (xx = 0; xx < aux_data_ref_count; xx++)
+        {
+            /* Aux Data Reference length (1 byte) */
+            ref_str_len = (UINT8) strlen (p_aux_data_ref_str[xx]);
+
+            UINT8_TO_BE_STREAM (p, ref_str_len);
+
+            /* Aux Data Reference */
+            ARRAY_TO_BE_STREAM (p, p_aux_data_ref_str[xx], ref_str_len);
+        }
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktCr
+**
+** Description      This function adds Collision Resolution Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktCr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                               UINT16 random_number )
+{
+    tNDEF_STATUS    status;
+    UINT8           data[2], *p;
+
+    p = data;
+    UINT16_TO_BE_STREAM (p, random_number);
+
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN,
+                             NULL, 0, data, 2);
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddWktErr
+**
+** Description      This function adds Error Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddWktErr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                UINT8 error_reason, UINT32 error_data )
+{
+    tNDEF_STATUS    status;
+    UINT8           payload[5], *p;
+    UINT32          payload_len;
+
+    p = payload;
+
+    UINT8_TO_BE_STREAM (p, error_reason);
+
+    if (error_reason == 0x02)
+    {
+        UINT32_TO_BE_STREAM (p, error_data);
+        payload_len = 5;
+    }
+    else
+    {
+        UINT8_TO_BE_STREAM (p, error_data);
+        payload_len = 2;
+    }
+
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_WKT, err_rec_type, ERR_REC_TYPE_LEN,
+                             NULL, 0, payload, payload_len);
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddMediaBtOob
+**
+** Description      This function adds BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAddMediaBtOob (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                    char *p_id_str, BD_ADDR bd_addr)
+{
+    tNDEF_STATUS    status;
+    UINT8           payload[BD_ADDR_LEN + 2];
+    UINT8          *p;
+    UINT8           payload_len, id_len;
+
+    p = payload;
+
+    /* length including itself */
+    UINT16_TO_STREAM (p, BD_ADDR_LEN + 2);
+
+    /* BD Addr */
+    BDADDR_TO_STREAM (p, bd_addr);
+
+    payload_len = BD_ADDR_LEN + 2;
+    id_len = (UINT8) strlen (p_id_str);
+
+    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
+                             NDEF_TNF_MEDIA, p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN,
+                             (UINT8*) p_id_str, id_len, payload, payload_len);
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobCod
+**
+** Description      This function appends COD EIR data at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobCod (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                          char *p_id_str, DEV_CLASS cod)
+{
+    tNDEF_STATUS    status;
+    UINT8          *p_rec;
+    UINT8           eir_data[BT_OOB_COD_SIZE + 2];
+    UINT8          *p;
+    UINT8           eir_data_len;
+    UINT32          oob_data_len;
+
+    /* find record by Payload ID */
+    p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+    if (!p_rec)
+        return (NDEF_REC_NOT_FOUND);
+
+    /* create EIR data format for COD */
+    p = eir_data;
+    UINT8_TO_STREAM (p, BT_OOB_COD_SIZE + 1);
+    UINT8_TO_STREAM (p, BT_EIR_OOB_COD_TYPE);
+    DEVCLASS_TO_STREAM (p, cod);
+    eir_data_len = BT_OOB_COD_SIZE + 2;
+
+    /* append EIR data at the end of record */
+    status = NDEF_MsgAppendPayload (p_msg, max_size, p_cur_size,
+                                    p_rec, eir_data, eir_data_len);
+
+    /* update BT OOB data length, if success */
+    if (status == NDEF_OK)
+    {
+        /* payload length is the same as BT OOB data length */
+        p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+        UINT16_TO_STREAM (p, oob_data_len);
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobName
+**
+** Description      This function appends Bluetooth Local Name EIR data
+**                  at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobName (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                           char *p_id_str, BOOLEAN is_complete,
+                                           UINT8 name_len, UINT8 *p_name)
+{
+    tNDEF_STATUS    status;
+    UINT8          *p_rec;
+    UINT8           eir_data[256];
+    UINT8          *p;
+    UINT8           eir_data_len;
+    UINT32          oob_data_len;
+
+    /* find record by Payload ID */
+    p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+    if (!p_rec)
+        return (NDEF_REC_NOT_FOUND);
+
+    /* create EIR data format for COD */
+    p = eir_data;
+    UINT8_TO_STREAM (p, name_len + 1);
+
+    if (is_complete)
+    {
+        UINT8_TO_STREAM (p, BT_EIR_COMPLETE_LOCAL_NAME_TYPE);
+    }
+    else
+    {
+        UINT8_TO_STREAM (p, BT_EIR_SHORTENED_LOCAL_NAME_TYPE);
+    }
+
+    ARRAY_TO_STREAM (p, p_name, name_len);
+    eir_data_len = name_len + 2;
+
+    /* append EIR data at the end of record */
+    status = NDEF_MsgAppendPayload (p_msg, max_size, p_cur_size,
+                                    p_rec, eir_data, eir_data_len);
+
+    /* update BT OOB data length, if success */
+    if (status == NDEF_OK)
+    {
+        /* payload length is the same as BT OOB data length */
+        p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+        UINT16_TO_STREAM (p, oob_data_len);
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobHashCRandR
+**
+** Description      This function appends Hash C and Rand R at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobHashCRandR (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                                 char *p_id_str, UINT8 *p_hash_c, UINT8 *p_rand_r)
+{
+    tNDEF_STATUS    status;
+    UINT8          *p_rec;
+    UINT8           eir_data[BT_OOB_HASH_C_SIZE + BT_OOB_RAND_R_SIZE + 4];
+    UINT8          *p;
+    UINT8           eir_data_len;
+    UINT32          oob_data_len;
+
+    /* find record by Payload ID */
+    p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+    if (!p_rec)
+        return (NDEF_REC_NOT_FOUND);
+
+    /* create EIR data format */
+    p = eir_data;
+
+    UINT8_TO_STREAM (p, BT_OOB_HASH_C_SIZE + 1);
+    UINT8_TO_STREAM (p, BT_EIR_OOB_SSP_HASH_C_TYPE);
+    ARRAY16_TO_STREAM (p, p_hash_c);
+
+    UINT8_TO_STREAM (p, BT_OOB_RAND_R_SIZE + 1);
+    UINT8_TO_STREAM (p, BT_EIR_OOB_SSP_RAND_R_TYPE);
+    ARRAY16_TO_STREAM (p, p_rand_r);
+
+    eir_data_len = BT_OOB_HASH_C_SIZE + BT_OOB_RAND_R_SIZE + 4;
+
+    /* append EIR data at the end of record */
+    status = NDEF_MsgAppendPayload (p_msg, max_size, p_cur_size,
+                                    p_rec, eir_data, eir_data_len);
+
+    /* update BT OOB data length, if success */
+    if (status == NDEF_OK)
+    {
+        /* payload length is the same as BT OOB data length */
+        p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+        UINT16_TO_STREAM (p, oob_data_len);
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendMediaBtOobEirData
+**
+** Description      This function appends EIR Data at the end of BT OOB Record.
+**
+** Returns          NDEF_OK if all OK
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendMediaBtOobEirData (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                              char *p_id_str,
+                                              UINT8 eir_type, UINT8 data_len, UINT8 *p_data)
+{
+    tNDEF_STATUS    status;
+    UINT8          *p_rec;
+    UINT8           eir_data[256];
+    UINT8          *p;
+    UINT8           eir_data_len;
+    UINT32          oob_data_len;
+
+    /* find record by Payload ID */
+    p_rec = ndef_get_bt_oob_record (p_msg, max_size, p_cur_size, p_id_str);
+
+    if (!p_rec)
+        return (NDEF_REC_NOT_FOUND);
+
+    /* create EIR data format */
+    p = eir_data;
+    UINT8_TO_STREAM (p, data_len + 1);
+    UINT8_TO_STREAM (p, eir_type);
+    ARRAY_TO_STREAM (p, p_data, data_len);
+    eir_data_len = data_len + 2;
+
+    /* append EIR data at the end of record */
+    status = NDEF_MsgAppendPayload (p_msg, max_size, p_cur_size,
+                                    p_rec, eir_data, eir_data_len);
+
+    /* update BT OOB data length, if success */
+    if (status == NDEF_OK)
+    {
+        /* payload length is the same as BT OOB data length */
+        p = NDEF_RecGetPayload (p_rec, &oob_data_len);
+        UINT16_TO_STREAM (p, oob_data_len);
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+**              Static Local Functions
+**
+*******************************************************************************/
+/*******************************************************************************
+**
+** Function         ndef_get_bt_oob_record
+**
+** Description      This function returns BT OOB record which has matched payload ID
+**
+** Returns          pointer of record if found, otherwise NULL
+**
+*******************************************************************************/
+static UINT8 *ndef_get_bt_oob_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                      char *p_id_str)
+{
+    UINT8  *p_rec, *p_type;
+    UINT8   id_len, tnf, type_len;
+
+    /* find record by Payload ID */
+    id_len = (UINT8) strlen (p_id_str);
+    p_rec = NDEF_MsgGetFirstRecById (p_msg, (UINT8*) p_id_str, id_len);
+
+    if (!p_rec)
+        return (NULL);
+
+    p_type = NDEF_RecGetType (p_rec, &tnf, &type_len);
+
+    /* check type if this is BT OOB record */
+    if (  (!p_rec)
+        ||(tnf != NDEF_TNF_MEDIA)
+        ||(type_len != BT_OOB_REC_TYPE_LEN)
+        ||(memcmp (p_type, p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN))  )
+    {
+        return (NULL);
+    }
+
+    return (p_rec);
+}
+
diff --git a/src/nfc/ndef/ndef_utils.c b/src/nfc/ndef/ndef_utils.c
new file mode 100644
index 0000000..48084f0
--- /dev/null
+++ b/src/nfc/ndef/ndef_utils.c
@@ -0,0 +1,1566 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains source code for some utility functions to help parse
+ *  and build NFC Data Exchange Format (NDEF) messages
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "ndef_utils.h"
+
+/*******************************************************************************
+**
+**              Static Local Functions
+**
+*******************************************************************************/
+
+
+/*******************************************************************************
+**
+** Function         shiftdown
+**
+** Description      shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+static void shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount)
+{
+    register UINT8 *ps = p_mem + len - 1;
+    register UINT8 *pd = ps + shift_amount;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function         shiftup
+**
+** Description      shift memory up (to delete a record)
+**
+*******************************************************************************/
+static void shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len)
+{
+    register UINT8 *ps = p_src;
+    register UINT8 *pd = p_dest;
+    register UINT32 xx;
+
+    for (xx = 0; xx < len; xx++)
+        *pd++ = *ps++;
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgValidate
+**
+** Description      This function validates an NDEF message.
+**
+** Returns          TRUE if all OK, or FALSE if the message is invalid.
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgValidate (UINT8 *p_msg, UINT32 msg_len, BOOLEAN b_allow_chunks)
+{
+    UINT8   *p_rec = p_msg;
+    UINT8   *p_end = p_msg + msg_len;
+    UINT8   rec_hdr=0, type_len, id_len;
+    int     count;
+    UINT32  payload_len;
+    BOOLEAN bInChunk = FALSE;
+
+    if ( (p_msg == NULL) || (msg_len < 3) )
+        return (NDEF_MSG_TOO_SHORT);
+
+    /* The first record must have the MB bit set */
+    if ((*p_msg & NDEF_MB_MASK) == 0)
+        return (NDEF_MSG_NO_MSG_BEGIN);
+
+    /* The first record cannot be a chunk */
+    if ((*p_msg & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+        return (NDEF_MSG_UNEXPECTED_CHUNK);
+
+    for (count = 0; p_rec < p_end; count++)
+    {
+        /* if less than short record header */
+        if (p_rec + 3 > p_end)
+            return (NDEF_MSG_TOO_SHORT);
+
+        rec_hdr = *p_rec++;
+
+        /* The second and all subsequent records must NOT have the MB bit set */
+        if ( (count > 0) && (rec_hdr & NDEF_MB_MASK) )
+            return (NDEF_MSG_EXTRA_MSG_BEGIN);
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+        {
+            /* if less than 4 bytes payload length */
+            if (p_rec + 4 > p_end)
+                return (NDEF_MSG_TOO_SHORT);
+
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+        }
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+        {
+            /* if less than 1 byte ID field length */
+            if (p_rec + 1 > p_end)
+                return (NDEF_MSG_TOO_SHORT);
+
+            id_len = *p_rec++;
+        }
+        else
+            id_len = 0;
+
+        /* A chunk must have type "unchanged", and no type or ID fields */
+        if (rec_hdr & NDEF_CF_MASK)
+        {
+            if (!b_allow_chunks)
+                return (NDEF_MSG_UNEXPECTED_CHUNK);
+
+            /* Inside a chunk, the type must be unchanged and no type or ID field i sallowed */
+            if (bInChunk)
+            {
+                if ( (type_len != 0) || (id_len != 0) || ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED) )
+                    return (NDEF_MSG_INVALID_CHUNK);
+            }
+            else
+            {
+                /* First record of a chunk must NOT have type "unchanged" */
+                if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+                    return (NDEF_MSG_INVALID_CHUNK);
+
+                bInChunk = TRUE;
+            }
+        }
+        else
+        {
+            /* This may be the last guy in a chunk. */
+            if (bInChunk)
+            {
+                if ( (type_len != 0) || (id_len != 0) || ((rec_hdr & NDEF_TNF_MASK) != NDEF_TNF_UNCHANGED) )
+                    return (NDEF_MSG_INVALID_CHUNK);
+
+                bInChunk = FALSE;
+            }
+            else
+            {
+                /* If not in a chunk, the record must NOT have type "unchanged" */
+                if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNCHANGED)
+                    return (NDEF_MSG_INVALID_CHUNK);
+            }
+        }
+
+        /* An empty record must NOT have a type, ID or payload */
+        if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_EMPTY)
+        {
+            if ( (type_len != 0) || (id_len != 0) || (payload_len != 0) )
+                return (NDEF_MSG_INVALID_EMPTY_REC);
+        }
+
+        if ((rec_hdr & NDEF_TNF_MASK) == NDEF_TNF_UNKNOWN)
+        {
+            if (type_len != 0)
+                return (NDEF_MSG_LENGTH_MISMATCH);
+        }
+
+        /* Point to next record */
+        p_rec += (payload_len + type_len + id_len);
+
+        if (rec_hdr & NDEF_ME_MASK)
+            break;
+
+        rec_hdr = 0;
+    }
+
+    /* The last record should have the ME bit set */
+    if ((rec_hdr & NDEF_ME_MASK) == 0)
+        return (NDEF_MSG_NO_MSG_END);
+
+    /* p_rec should equal p_end if all the length fields were correct */
+    if (p_rec != p_end)
+        return (NDEF_MSG_LENGTH_MISMATCH);
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNumRecs
+**
+** Description      This function gets the number of records in the given NDEF
+**                  message.
+**
+** Returns          The record count, or 0 if the message is invalid.
+**
+*******************************************************************************/
+INT32 NDEF_MsgGetNumRecs (UINT8 *p_msg)
+{
+    UINT8   *p_rec = p_msg;
+    UINT8   rec_hdr, type_len, id_len;
+    int     count;
+    UINT32  payload_len;
+
+    for (count = 0; ; )
+    {
+        count++;
+
+        rec_hdr = *p_rec++;
+
+        if (rec_hdr & NDEF_ME_MASK)
+            break;
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* Point to next record */
+        p_rec += (payload_len + type_len + id_len);
+    }
+
+    /* Return the number of records found */
+    return (count);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecLength
+**
+** Description      This function returns length of the current record in the given
+**                  NDEF message.
+**
+** Returns          Length of record
+**
+*******************************************************************************/
+UINT32 NDEF_MsgGetRecLength (UINT8 *p_cur_rec)
+{
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  rec_len = 0;
+    UINT32  payload_len;
+
+    /* Get the current record's header */
+    rec_hdr = *p_cur_rec++;
+    rec_len++;
+
+    /* Type field length */
+    type_len = *p_cur_rec++;
+    rec_len++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+    {
+        payload_len = *p_cur_rec++;
+        rec_len++;
+    }
+    else
+    {
+        BE_STREAM_TO_UINT32 (payload_len, p_cur_rec);
+        rec_len += 4;
+    }
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+    {
+        id_len = *p_cur_rec++;
+        rec_len++;
+    }
+    else
+        id_len = 0;
+
+    /* Total length of record */
+    rec_len += (payload_len + type_len + id_len);
+
+    return (rec_len);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRec
+**
+** Description      This function gets a pointer to the next record in the given
+**                  NDEF message. If the current record pointer is NULL, a pointer
+**                  to the first record is returned.
+**
+** Returns          Pointer to the start of the record, or NULL if no more
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetNextRec (UINT8 *p_cur_rec)
+{
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    /* Get the current record's header */
+    rec_hdr = *p_cur_rec++;
+
+    /* If this is the last record, return NULL */
+    if (rec_hdr & NDEF_ME_MASK)
+        return (NULL);
+
+    /* Type field length */
+    type_len = *p_cur_rec++;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (rec_hdr & NDEF_SR_MASK)
+        payload_len = *p_cur_rec++;
+    else
+        BE_STREAM_TO_UINT32 (payload_len, p_cur_rec);
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+        id_len = *p_cur_rec++;
+    else
+        id_len = 0;
+
+    /* Point to next record */
+    p_cur_rec += (payload_len + type_len + id_len);
+
+    return (p_cur_rec);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetRecByIndex
+**
+** Description      This function gets a pointer to the record with the given
+**                  index (0-based index) in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetRecByIndex (UINT8 *p_msg, INT32 index)
+{
+    UINT8   *p_rec = p_msg;
+    UINT8   rec_hdr, type_len, id_len;
+    INT32   count;
+    UINT32  payload_len;
+
+    for (count = 0; ; count++)
+    {
+        if (count == index)
+            return (p_rec);
+
+        rec_hdr = *p_rec++;
+
+        if (rec_hdr & NDEF_ME_MASK)
+            return (NULL);
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* Point to next record */
+        p_rec += (payload_len + type_len + id_len);
+    }
+
+    /* If here, there is no record of that index */
+    return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetLastRecInMsg
+**
+** Description      This function gets a pointer to the last record in the
+**                  given NDEF message.
+**
+** Returns          Pointer to the start of the last record, or NULL if some problem
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetLastRecInMsg (UINT8 *p_msg)
+{
+    UINT8   *p_rec = p_msg;
+    UINT8   *pRecStart;
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    for ( ; ; )
+    {
+        pRecStart = p_rec;
+        rec_hdr = *p_rec++;
+
+        if (rec_hdr & NDEF_ME_MASK)
+            break;
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* Point to next record */
+        p_rec += (payload_len + type_len + id_len);
+    }
+
+    return (pRecStart);
+}
+
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecByType
+**
+** Description      This function gets a pointer to the first record with the given
+**                  record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetFirstRecByType (UINT8 *p_msg, UINT8 tnf, UINT8 *p_type, UINT8 tlen)
+{
+    UINT8   *p_rec = p_msg;
+    UINT8   *pRecStart;
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    for ( ; ; )
+    {
+        pRecStart = p_rec;
+
+        rec_hdr = *p_rec++;
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* At this point, p_rec points to the start of the type field. We need to */
+        /* compare the type of the type, the length of the type and the data     */
+        if ( ((rec_hdr & NDEF_TNF_MASK) == tnf)
+         &&  (type_len == tlen)
+         &&  (!memcmp (p_rec, p_type, tlen)) )
+             return (pRecStart);
+
+        /* If this was the last record, return NULL */
+        if (rec_hdr & NDEF_ME_MASK)
+            return (NULL);
+
+        /* Point to next record */
+        p_rec += (payload_len + type_len + id_len);
+    }
+
+    /* If here, there is no record of that type */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecByType
+**
+** Description      This function gets a pointer to the next record with the given
+**                  record type in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetNextRecByType (UINT8 *p_cur_rec, UINT8 tnf, UINT8 *p_type, UINT8 tlen)
+{
+    UINT8   *p_rec;
+    UINT8   *pRecStart;
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    /* If this is the last record in the message, return NULL */
+    if ((p_rec = NDEF_MsgGetNextRec (p_cur_rec)) == NULL)
+        return (NULL);
+
+    for ( ; ; )
+    {
+        pRecStart = p_rec;
+
+        rec_hdr = *p_rec++;
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* At this point, p_rec points to the start of the type field. We need to */
+        /* compare the type of the type, the length of the type and the data     */
+        if ( ((rec_hdr & NDEF_TNF_MASK) == tnf)
+         &&  (type_len == tlen)
+         &&  (!memcmp (p_rec, p_type, tlen)) )
+             return (pRecStart);
+
+        /* If this was the last record, return NULL */
+        if (rec_hdr & NDEF_ME_MASK)
+            break;
+
+        /* Point to next record */
+        p_rec += (payload_len + type_len + id_len);
+    }
+
+    /* If here, there is no record of that type */
+    return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetFirstRecById
+**
+** Description      This function gets a pointer to the first record with the given
+**                  record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetFirstRecById (UINT8 *p_msg, UINT8 *p_id, UINT8 ilen)
+{
+    UINT8   *p_rec = p_msg;
+    UINT8   *pRecStart;
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    for ( ; ; )
+    {
+        pRecStart = p_rec;
+
+        rec_hdr = *p_rec++;
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* At this point, p_rec points to the start of the type field. Skip it */
+        p_rec += type_len;
+
+        /* At this point, p_rec points to the start of the ID field. Compare length and data */
+        if ( (id_len == ilen) && (!memcmp (p_rec, p_id, ilen)) )
+             return (pRecStart);
+
+        /* If this was the last record, return NULL */
+        if (rec_hdr & NDEF_ME_MASK)
+            return (NULL);
+
+        /* Point to next record */
+        p_rec += (id_len + payload_len);
+    }
+
+    /* If here, there is no record of that ID */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgGetNextRecById
+**
+** Description      This function gets a pointer to the next record with the given
+**                  record id in the given NDEF message.
+**
+** Returns          Pointer to the start of the record, or NULL
+**
+*******************************************************************************/
+UINT8 *NDEF_MsgGetNextRecById (UINT8 *p_cur_rec, UINT8 *p_id, UINT8 ilen)
+{
+    UINT8   *p_rec;
+    UINT8   *pRecStart;
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    /* If this is the last record in the message, return NULL */
+    if ((p_rec = NDEF_MsgGetNextRec (p_cur_rec)) == NULL)
+        return (NULL);
+
+    for ( ; ; )
+    {
+        pRecStart = p_rec;
+
+        rec_hdr = *p_rec++;
+
+        /* Type field length */
+        type_len = *p_rec++;
+
+        /* Payload length - can be 1 or 4 bytes */
+        if (rec_hdr & NDEF_SR_MASK)
+            payload_len = *p_rec++;
+        else
+            BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+        /* ID field Length */
+        if (rec_hdr & NDEF_IL_MASK)
+            id_len = *p_rec++;
+        else
+            id_len = 0;
+
+        /* At this point, p_rec points to the start of the type field. Skip it */
+        p_rec += type_len;
+
+        /* At this point, p_rec points to the start of the ID field. Compare length and data */
+        if ( (id_len == ilen) && (!memcmp (p_rec, p_id, ilen)) )
+             return (pRecStart);
+
+        /* If this was the last record, return NULL */
+        if (rec_hdr & NDEF_ME_MASK)
+            break;
+
+        /* Point to next record */
+        p_rec += (id_len + payload_len);
+    }
+
+    /* If here, there is no record of that ID */
+    return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetType
+**
+** Description      This function gets a pointer to the record type for the given NDEF record.
+**
+** Returns          Pointer to Type (NULL if none). TNF and len are filled in.
+**
+*******************************************************************************/
+UINT8 *NDEF_RecGetType (UINT8 *p_rec, UINT8 *p_tnf, UINT8 *p_type_len)
+{
+    UINT8   rec_hdr, type_len;
+
+    /* First byte is the record header */
+    rec_hdr = *p_rec++;
+
+    /* Next byte is the type field length */
+    type_len = *p_rec++;
+
+    /* Skip the payload length */
+    if (rec_hdr & NDEF_SR_MASK)
+        p_rec += 1;
+    else
+        p_rec += 4;
+
+    /* Skip ID field Length, if present */
+    if (rec_hdr & NDEF_IL_MASK)
+        p_rec++;
+
+    /* At this point, p_rec points to the start of the type field.  */
+    *p_type_len = type_len;
+    *p_tnf      = rec_hdr & NDEF_TNF_MASK;
+
+    if (type_len == 0)
+        return (NULL);
+    else
+        return (p_rec);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetId
+**
+** Description      This function gets a pointer to the record id for the given NDEF record.
+**
+** Returns          Pointer to Id (NULL if none). ID Len is filled in.
+**
+*******************************************************************************/
+UINT8 *NDEF_RecGetId (UINT8 *p_rec, UINT8 *p_id_len)
+{
+    UINT8   rec_hdr, type_len;
+
+    /* First byte is the record header */
+    rec_hdr = *p_rec++;
+
+    /* Next byte is the type field length */
+    type_len = *p_rec++;
+
+    /* Skip the payload length */
+    if (rec_hdr & NDEF_SR_MASK)
+        p_rec++;
+    else
+        p_rec += 4;
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+        *p_id_len = *p_rec++;
+    else
+        *p_id_len = 0;
+
+    /* p_rec now points to the start of the type field. The ID field follows it */
+    if (*p_id_len == 0)
+        return (NULL);
+    else
+        return (p_rec + type_len);
+}
+
+
+/*******************************************************************************
+**
+** Function         NDEF_RecGetPayload
+**
+** Description      This function gets a pointer to the payload for the given NDEF record.
+**
+** Returns          a pointer to the payload (or NULL none). Payload len filled in.
+**
+*******************************************************************************/
+UINT8 *NDEF_RecGetPayload (UINT8 *p_rec, UINT32 *p_payload_len)
+{
+    UINT8   rec_hdr, type_len, id_len;
+    UINT32  payload_len;
+
+    /* First byte is the record header */
+    rec_hdr = *p_rec++;
+
+    /* Next byte is the type field length */
+    type_len = *p_rec++;
+
+    /* Next is the payload length (1 or 4 bytes) */
+    if (rec_hdr & NDEF_SR_MASK)
+        payload_len = *p_rec++;
+    else
+        BE_STREAM_TO_UINT32 (payload_len, p_rec);
+
+    *p_payload_len = payload_len;
+
+    /* ID field Length */
+    if (rec_hdr & NDEF_IL_MASK)
+        id_len = *p_rec++;
+    else
+        id_len = 0;
+
+    /* p_rec now points to the start of the type field. The ID field follows it, then the payload */
+    if (payload_len == 0)
+        return (NULL);
+    else
+        return (p_rec + type_len + id_len);
+}
+
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgInit
+**
+** Description      This function initializes an NDEF message.
+**
+** Returns          void
+**                  *p_cur_size is initialized to 0
+**
+*******************************************************************************/
+void NDEF_MsgInit (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size)
+{
+    *p_cur_size = 0;
+    memset (p_msg, 0, max_size);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAddRec
+**
+** Description      This function adds an NDEF record to the end of an NDEF message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS  NDEF_MsgAddRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                     UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+                                     UINT8 *p_id, UINT8  id_len,
+                                     UINT8 *p_payload, UINT32 payload_len)
+{
+    UINT8   *p_rec = p_msg + *p_cur_size;
+    UINT32  recSize;
+    int     plen = (payload_len < 256) ? 1 : 4;
+    int     ilen = (id_len == 0) ? 0 : 1;
+
+    if (tnf > NDEF_TNF_RESERVED)
+    {
+        tnf = NDEF_TNF_UNKNOWN;
+        type_len  = 0;
+    }
+
+    /* First, make sure the record will fit. we need at least 2 bytes for header and type length */
+    recSize = payload_len + 2 + type_len + plen + ilen + id_len;
+
+    if ((*p_cur_size + recSize) > max_size)
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* Construct the record header. For the first record, set both begin and end bits */
+    if (*p_cur_size == 0)
+        *p_rec = tnf | NDEF_MB_MASK | NDEF_ME_MASK;
+    else
+    {
+        /* Find the previous last and clear his 'Message End' bit */
+        UINT8  *pLast = NDEF_MsgGetLastRecInMsg (p_msg);
+
+        if (!pLast)
+            return (FALSE);
+
+        *pLast &= ~NDEF_ME_MASK;
+        *p_rec   = tnf | NDEF_ME_MASK;
+    }
+
+    if (plen == 1)
+        *p_rec |= NDEF_SR_MASK;
+
+    if (ilen != 0)
+        *p_rec |= NDEF_IL_MASK;
+
+    p_rec++;
+
+    /* The next byte is the type field length */
+    *p_rec++ = type_len;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (plen == 1)
+        *p_rec++ = (UINT8)payload_len;
+    else
+         UINT32_TO_BE_STREAM (p_rec, payload_len);
+
+    /* ID field Length (optional) */
+    if (ilen > 0)
+        *p_rec++ = id_len;
+
+    /* Next comes the type */
+    if (type_len)
+    {
+        if (p_type)
+            memcpy (p_rec, p_type, type_len);
+
+        p_rec += type_len;
+    }
+
+    /* Next comes the ID */
+    if (id_len)
+    {
+        if (p_id)
+            memcpy (p_rec, p_id, id_len);
+
+        p_rec += id_len;
+    }
+
+    /* And lastly the payload. If NULL, the app just wants to reserve memory */
+    if (p_payload)
+        memcpy (p_rec, p_payload, payload_len);
+
+    *p_cur_size += recSize;
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgInsertRec
+**
+** Description      This function inserts a record at a specific index into the
+**                  given NDEF message
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS NDEF_MsgInsertRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size, INT32 index,
+                                       UINT8 tnf, UINT8 *p_type, UINT8 type_len,
+                                       UINT8 *p_id, UINT8  id_len,
+                                       UINT8 *p_payload, UINT32 payload_len)
+{
+    UINT8   *p_rec;
+    UINT32  recSize;
+    INT32   plen = (payload_len < 256) ? 1 : 4;
+    INT32   ilen = (id_len == 0) ? 0 : 1;
+
+    /* First, make sure the record will fit. we need at least 2 bytes for header and type length */
+    recSize = payload_len + 2 + type_len + plen + ilen + id_len;
+
+    if ((*p_cur_size + recSize) > max_size)
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* See where the new record goes. If at the end, call the 'AddRec' function */
+    if ( (index >= NDEF_MsgGetNumRecs (p_msg))
+      || ((p_rec = NDEF_MsgGetRecByIndex(p_msg, index)) == NULL) )
+    {
+        return NDEF_MsgAddRec (p_msg, max_size, p_cur_size, tnf, p_type, type_len,
+                               p_id, id_len, p_payload, payload_len);
+    }
+
+    /* If we are inserting at the beginning, remove the MB bit from the current first */
+    if (index == 0)
+        *p_msg &= ~NDEF_MB_MASK;
+
+    /* Make space for the new record */
+    shiftdown (p_rec, (UINT32)(*p_cur_size - (p_rec - p_msg)), recSize);
+
+    /* If adding at the beginning, set begin bit */
+    if (index == 0)
+        *p_rec = tnf | NDEF_MB_MASK;
+    else
+        *p_rec = tnf;
+
+    if (plen == 1)
+        *p_rec |= NDEF_SR_MASK;
+
+    if (ilen != 0)
+        *p_rec |= NDEF_IL_MASK;
+
+    p_rec++;
+
+    /* The next byte is the type field length */
+    *p_rec++ = type_len;
+
+    /* Payload length - can be 1 or 4 bytes */
+    if (plen == 1)
+        *p_rec++ = (UINT8)payload_len;
+    else
+         UINT32_TO_BE_STREAM (p_rec, payload_len);
+
+    /* ID field Length (optional) */
+    if (ilen != 0)
+        *p_rec++ = id_len;
+
+    /* Next comes the type */
+    if (type_len)
+    {
+        if (p_type)
+            memcpy (p_rec, p_type, type_len);
+
+        p_rec += type_len;
+    }
+
+    /* Next comes the ID */
+    if (ilen != 0)
+    {
+        if (p_id)
+            memcpy (p_rec, p_id, id_len);
+
+        p_rec += id_len;
+    }
+
+    /* And lastly the payload. If NULL, the app just wants to reserve memory */
+    if (p_payload)
+        memcpy (p_rec, p_payload, payload_len);
+
+    *p_cur_size += recSize;
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendRec
+**
+** Description      This function adds NDEF records to the end of an NDEF message.
+**
+** Returns          OK, or error if the record did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+extern tNDEF_STATUS  NDEF_MsgAppendRec (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                        UINT8 *p_new_rec, UINT32 new_rec_len)
+{
+    UINT8   *p_rec;
+    tNDEF_STATUS    status;
+
+    /* First, validate new records */
+    if ((status = NDEF_MsgValidate(p_new_rec, new_rec_len, FALSE)) != NDEF_OK)
+        return (status);
+
+    /* First, make sure the record will fit */
+    if ((*p_cur_size + new_rec_len) > max_size)
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* Find where to copy new record */
+    if (*p_cur_size == 0)
+        p_rec = p_msg;
+    else
+    {
+        /* Find the previous last and clear his 'Message End' bit */
+        UINT8  *pLast = NDEF_MsgGetLastRecInMsg (p_msg);
+
+        if (!pLast)
+            return (NDEF_MSG_NO_MSG_END);
+
+        *pLast &= ~NDEF_ME_MASK;
+        p_rec   = p_msg + *p_cur_size;
+
+        /* clear 'Message Begin' bit of new record */
+        *p_new_rec &= ~NDEF_MB_MASK;
+    }
+
+    /* append new records */
+    memcpy (p_rec, p_new_rec, new_rec_len);
+
+    *p_cur_size += new_rec_len;
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgAppendPayload
+**
+** Description      This function appends extra payload to a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the extra payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgAppendPayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                    UINT8 *p_rec, UINT8 *p_add_pl, UINT32 add_pl_len)
+{
+    UINT32      prev_paylen, new_paylen;
+    UINT8       *p_prev_pl, *pp;
+    UINT8       incr_lenfld = 0;
+    UINT8       type_len, id_len;
+
+    /* Skip header */
+    pp = p_rec + 1;
+
+    /* Next byte is the type field length */
+    type_len = *pp++;
+
+    /* Next is the payload length (1 or 4 bytes) */
+    if (*p_rec & NDEF_SR_MASK)
+        prev_paylen = *pp++;
+    else
+        BE_STREAM_TO_UINT32 (prev_paylen, pp);
+
+    /* ID field Length */
+    if (*p_rec & NDEF_IL_MASK)
+        id_len = *pp++;
+    else
+        id_len = 0;
+
+    p_prev_pl = pp + type_len + id_len;
+
+    new_paylen = prev_paylen + add_pl_len;
+
+    /* Previous payload may be < 256, and this addition may make it larger than 256 */
+    /* If that were to happen, the payload length field goes from 1 byte to 4 bytes */
+    if ( (prev_paylen < 256) && (new_paylen > 255) )
+        incr_lenfld = 3;
+
+    /* Check that it all fits */
+    if ((*p_cur_size + add_pl_len + incr_lenfld) > max_size)
+        return (NDEF_MSG_INSUFFICIENT_MEM);
+
+    /* Point to payload length field */
+    pp = p_rec + 2;
+
+    /* If we need to increase the length field from 1 to 4 bytes, do it first */
+    if (incr_lenfld)
+    {
+        shiftdown (pp + 1, (UINT32)(*p_cur_size - (pp - p_msg) - 1), 3);
+        p_prev_pl += 3;
+    }
+
+    /* Store in the new length */
+    if (new_paylen > 255)
+    {
+        *p_rec &= ~NDEF_SR_MASK;
+        UINT32_TO_BE_STREAM (pp, new_paylen);
+    }
+    else
+        *pp = (UINT8)new_paylen;
+
+    /* Point to the end of the previous payload */
+    pp = p_prev_pl + prev_paylen;
+
+    /* If we are not the last record, make space for the extra payload */
+    if ((*p_rec & NDEF_ME_MASK) == 0)
+        shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), add_pl_len);
+
+    /* Now copy in the additional payload data */
+    memcpy (pp, p_add_pl, add_pl_len);
+
+    *p_cur_size += add_pl_len + incr_lenfld;
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplacePayload
+**
+** Description      This function replaces the payload of a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the new payload did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplacePayload (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                     UINT8 *p_rec, UINT8 *p_new_pl, UINT32 new_pl_len)
+{
+    UINT32      prev_paylen;
+    UINT8       *p_prev_pl, *pp;
+    UINT32      paylen_delta;
+    UINT8       type_len, id_len;
+
+    /* Skip header */
+    pp = p_rec + 1;
+
+    /* Next byte is the type field length */
+    type_len = *pp++;
+
+    /* Next is the payload length (1 or 4 bytes) */
+    if (*p_rec & NDEF_SR_MASK)
+        prev_paylen = *pp++;
+    else
+        BE_STREAM_TO_UINT32 (prev_paylen, pp);
+
+    /* ID field Length */
+    if (*p_rec & NDEF_IL_MASK)
+        id_len = *pp++;
+    else
+        id_len = 0;
+
+    p_prev_pl = pp + type_len + id_len;
+
+    /* Point to payload length field again */
+    pp = p_rec + 2;
+
+    if (new_pl_len > prev_paylen)
+    {
+        /* New payload is larger than the previous */
+        paylen_delta = new_pl_len - prev_paylen;
+
+        /* If the previous payload length was < 256, and new is > 255 */
+        /* the payload length field goes from 1 byte to 4 bytes       */
+        if ( (prev_paylen < 256) && (new_pl_len > 255) )
+        {
+            if ((*p_cur_size + paylen_delta + 3) > max_size)
+                return (NDEF_MSG_INSUFFICIENT_MEM);
+
+            shiftdown (pp + 1, (UINT32)(*p_cur_size - (pp - p_msg) - 1), 3);
+            p_prev_pl   += 3;
+            *p_cur_size += 3;
+            *p_rec      &= ~NDEF_SR_MASK;
+        }
+        else if ((*p_cur_size + paylen_delta) > max_size)
+            return (NDEF_MSG_INSUFFICIENT_MEM);
+
+        /* Store in the new length */
+        if (new_pl_len > 255)
+        {
+            UINT32_TO_BE_STREAM (pp, new_pl_len);
+        }
+        else
+            *pp = (UINT8)new_pl_len;
+
+        /* Point to the end of the previous payload */
+        pp = p_prev_pl + prev_paylen;
+
+        /* If we are not the last record, make space for the extra payload */
+        if ((*p_rec & NDEF_ME_MASK) == 0)
+            shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), paylen_delta);
+
+        *p_cur_size += paylen_delta;
+    }
+    else if (new_pl_len < prev_paylen)
+    {
+        /* New payload is smaller than the previous */
+        paylen_delta = prev_paylen - new_pl_len;
+
+        /* If the previous payload was > 256, and new is less than 256 */
+        /* the payload length field goes from 4 bytes to 1 byte        */
+        if ( (prev_paylen > 255) && (new_pl_len < 256) )
+        {
+            shiftup (pp + 1, pp + 4, (UINT32)(*p_cur_size - (pp - p_msg) - 3));
+            p_prev_pl   -= 3;
+            *p_cur_size -= 3;
+            *p_rec      |= NDEF_SR_MASK;
+        }
+
+        /* Store in the new length */
+        if (new_pl_len > 255)
+        {
+            UINT32_TO_BE_STREAM (pp, new_pl_len);
+        }
+        else
+            *pp = (UINT8)new_pl_len;
+
+        /* Point to the end of the previous payload */
+        pp = p_prev_pl + prev_paylen;
+
+        /* If we are not the last record, remove the extra space from the previous payload */
+        if ((*p_rec & NDEF_ME_MASK) == 0)
+            shiftup (pp - paylen_delta, pp, (UINT32)(*p_cur_size - (pp - p_msg)));
+
+        *p_cur_size -= paylen_delta;
+    }
+
+    /* Now copy in the new payload data */
+    if (p_new_pl)
+        memcpy (p_prev_pl, p_new_pl, new_pl_len);
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceType
+**
+** Description      This function replaces the type field of a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the new type field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplaceType (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                  UINT8 *p_rec, UINT8 *p_new_type, UINT8 new_type_len)
+{
+    UINT8       typelen_delta;
+    UINT8       *p_prev_type, prev_type_len;
+    UINT8       *pp;
+
+    /* Skip header */
+    pp = p_rec + 1;
+
+    /* Next byte is the type field length */
+    prev_type_len = *pp++;
+
+    /* Skip the payload length */
+    if (*p_rec & NDEF_SR_MASK)
+        pp += 1;
+    else
+        pp += 4;
+
+    if (*p_rec & NDEF_IL_MASK)
+        pp++;
+
+    /* Save pointer to the start of the type field */
+    p_prev_type = pp;
+
+    if (new_type_len > prev_type_len)
+    {
+        /* New type is larger than the previous */
+        typelen_delta = new_type_len - prev_type_len;
+
+        if ((*p_cur_size + typelen_delta) > max_size)
+            return (NDEF_MSG_INSUFFICIENT_MEM);
+
+        /* Point to the end of the previous type, and make space for the extra data */
+        pp = p_prev_type + prev_type_len;
+        shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), typelen_delta);
+
+        *p_cur_size += typelen_delta;
+    }
+    else if (new_type_len < prev_type_len)
+    {
+        /* New type field is smaller than the previous */
+        typelen_delta = prev_type_len - new_type_len;
+
+        /* Point to the end of the previous type, and shift up to fill the the unused space */
+        pp = p_prev_type + prev_type_len;
+        shiftup (pp - typelen_delta, pp, (UINT32)(*p_cur_size - (pp - p_msg)));
+
+        *p_cur_size -= typelen_delta;
+    }
+
+    /* Save in new type length */
+    p_rec[1] = new_type_len;
+
+    /* Now copy in the new type field data */
+    if (p_new_type)
+        memcpy (p_prev_type, p_new_type, new_type_len);
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgReplaceId
+**
+** Description      This function replaces the ID field of a specific record in the
+**                  given NDEF message
+**
+** Returns          OK, or error if the new ID field did not fit
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgReplaceId (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
+                                UINT8 *p_rec, UINT8 *p_new_id, UINT8 new_id_len)
+{
+    UINT8       idlen_delta;
+    UINT8       *p_prev_id, *p_idlen_field;
+    UINT8       prev_id_len, type_len;
+    UINT8       *pp;
+
+    /* Skip header */
+    pp = p_rec + 1;
+
+    /* Next byte is the type field length */
+    type_len = *pp++;
+
+    /* Skip the payload length */
+    if (*p_rec & NDEF_SR_MASK)
+        pp += 1;
+    else
+        pp += 4;
+
+    p_idlen_field = pp;
+
+    if (*p_rec & NDEF_IL_MASK)
+        prev_id_len = *pp++;
+    else
+        prev_id_len = 0;
+
+    /* Save pointer to the start of the ID field (right after the type field) */
+    p_prev_id = pp + type_len;
+
+    if (new_id_len > prev_id_len)
+    {
+        /* New ID field is larger than the previous */
+        idlen_delta = new_id_len - prev_id_len;
+
+        /* If the previous ID length was 0, we need to add a 1-byte ID length */
+        if (prev_id_len == 0)
+        {
+            if ((*p_cur_size + idlen_delta + 1) > max_size)
+                return (NDEF_MSG_INSUFFICIENT_MEM);
+
+            shiftdown (p_idlen_field, (UINT32)(*p_cur_size - (p_idlen_field - p_msg)), 1);
+            p_prev_id   += 1;
+            *p_cur_size += 1;
+            *p_rec      |= NDEF_IL_MASK;
+        }
+        else if ((*p_cur_size + idlen_delta) > max_size)
+            return (NDEF_MSG_INSUFFICIENT_MEM);
+
+        /* Point to the end of the previous ID field, and make space for the extra data */
+        pp = p_prev_id + prev_id_len;
+        shiftdown (pp, (UINT32)(*p_cur_size - (pp - p_msg)), idlen_delta);
+
+        *p_cur_size += idlen_delta;
+    }
+    else if (new_id_len < prev_id_len)
+    {
+        /* New ID field is smaller than the previous */
+        idlen_delta = prev_id_len - new_id_len;
+
+        /* Point to the end of the previous ID, and shift up to fill the the unused space */
+        pp = p_prev_id + prev_id_len;
+        shiftup (pp - idlen_delta, pp, (UINT32)(*p_cur_size - (pp - p_msg)));
+
+        *p_cur_size -= idlen_delta;
+
+        /* If removing the ID, make sure that length field is also removed */
+        if (new_id_len == 0)
+        {
+            shiftup (p_idlen_field, p_idlen_field + 1, (UINT32)(*p_cur_size - (p_idlen_field - p_msg - (UINT32)1)));
+            *p_rec      &= ~NDEF_IL_MASK;
+            *p_cur_size -= 1;
+        }
+    }
+
+    /* Save in new ID length and data */
+    if (new_id_len)
+    {
+        *p_idlen_field = new_id_len;
+
+        if (p_new_id)
+            memcpy (p_prev_id, p_new_id, new_id_len);
+    }
+
+    return (NDEF_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgRemoveRec
+**
+** Description      This function removes the record at the given
+**                  index in the given NDEF message.
+**
+** Returns          TRUE if OK, FALSE if the index was invalid
+**                  *p_cur_size is updated
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgRemoveRec (UINT8 *p_msg, UINT32 *p_cur_size, INT32 index)
+{
+    UINT8   *p_rec = NDEF_MsgGetRecByIndex (p_msg, index);
+    UINT8   *pNext, *pPrev;
+
+    if (!p_rec)
+        return (NDEF_REC_NOT_FOUND);
+
+    /* If this is the first record in the message... */
+    if (*p_rec & NDEF_MB_MASK)
+    {
+        /* Find the second record (if any) and set his 'Message Begin' bit */
+        if ((pNext = NDEF_MsgGetRecByIndex(p_msg, 1)) != NULL)
+        {
+            *pNext |= NDEF_MB_MASK;
+
+            *p_cur_size -= (UINT32)(pNext - p_msg);
+
+            shiftup (p_msg, pNext, *p_cur_size);
+        }
+        else
+            *p_cur_size = 0;              /* No more records, lenght must be zero */
+
+        return (NDEF_OK);
+    }
+
+    /* If this is the last record in the message... */
+    if (*p_rec & NDEF_ME_MASK)
+    {
+        if (index > 0)
+        {
+            /* Find the previous record and set his 'Message End' bit */
+            if ((pPrev = NDEF_MsgGetRecByIndex(p_msg, index - 1)) == NULL)
+                return (FALSE);
+
+            *pPrev |= NDEF_ME_MASK;
+        }
+        *p_cur_size = (UINT32)(p_rec - p_msg);
+
+        return (NDEF_OK);
+    }
+
+    /* Not the first or the last... get the address of the next record */
+    if ((pNext = NDEF_MsgGetNextRec (p_rec)) == NULL)
+        return (FALSE);
+
+    /* We are removing p_rec, so shift from pNext to the end */
+    shiftup (p_rec, pNext, (UINT32)(*p_cur_size - (pNext - p_msg)));
+
+    *p_cur_size -= (UINT32)(pNext - p_rec);
+
+    return (NDEF_OK);
+}
+
+
+/*******************************************************************************
+**
+** Function         NDEF_MsgCopyAndDechunk
+**
+** Description      This function copies and de-chunks an NDEF message.
+**                  It is assumed that the destination is at least as large
+**                  as the source, since the source may not actually contain
+**                  any chunks.
+**
+** Returns          The output byte count
+**
+*******************************************************************************/
+tNDEF_STATUS NDEF_MsgCopyAndDechunk (UINT8 *p_src, UINT32 src_len, UINT8 *p_dest, UINT32 *p_out_len)
+{
+    UINT32          out_len, max_out_len;
+    UINT8           *p_rec;
+    UINT8           *p_prev_rec = p_dest;
+    UINT8           *p_type, *p_id, *p_pay;
+    UINT8           type_len, id_len, tnf;
+    UINT32          pay_len;
+    tNDEF_STATUS    status;
+
+    /* First, validate the source */
+    if ((status = NDEF_MsgValidate(p_src, src_len, TRUE)) != NDEF_OK)
+        return (status);
+
+    /* The output buffer must be at least as large as the input buffer */
+    max_out_len = src_len;
+
+    /* Initialize output */
+    NDEF_MsgInit (p_dest, max_out_len, &out_len);
+
+    p_rec = p_src;
+
+    /* Now, copy record by record */
+    while (p_rec != NULL)
+    {
+        p_type = NDEF_RecGetType (p_rec, &tnf, &type_len);
+        p_id   = NDEF_RecGetId (p_rec, &id_len);
+        p_pay  = NDEF_RecGetPayload (p_rec, &pay_len);
+
+        /* If this is the continuation of a chunk, append the payload to the previous */
+        if (tnf == NDEF_TNF_UNCHANGED)
+        {
+            NDEF_MsgAppendPayload (p_dest, max_out_len, &out_len, p_prev_rec, p_pay, pay_len);
+        }
+        else
+        {
+            p_prev_rec = p_dest + out_len;
+
+            NDEF_MsgAddRec (p_dest, max_out_len, &out_len, tnf, p_type, type_len,
+                            p_id, id_len, p_pay, pay_len);
+        }
+
+        p_rec = NDEF_MsgGetNextRec (p_rec);
+    }
+
+    *p_out_len = out_len;
+
+    return (NDEF_OK);
+}
+
diff --git a/src/nfc/nfc/nfc_ee.c b/src/nfc/nfc/nfc_ee.c
new file mode 100644
index 0000000..5f2969a
--- /dev/null
+++ b/src/nfc/nfc/nfc_ee.c
@@ -0,0 +1,125 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFCEEs.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeDiscover
+**
+** Description      This function is called to enable or disable NFCEE Discovery.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_DISCOVER_REVT.
+**                  The notification from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_INFO_REVT.
+**
+** Parameters       discover - 1 to enable discover, 0 to disable.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceeDiscover (BOOLEAN discover)
+{
+    return nci_snd_nfcee_discover ((UINT8) (discover ? NCI_DISCOVER_ACTION_ENABLE : NCI_DISCOVER_ACTION_DISABLE));
+}
+
+/*******************************************************************************
+**
+** Function         NFC_NfceeModeSet
+**
+** Description      This function is called to activate or de-activate an NFCEE
+**                  connected to the NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_NFCEE_MODE_SET_REVT.
+**
+** Parameters       nfcee_id - the NFCEE to activate or de-activate.
+**                  mode - NFC_MODE_ACTIVATE to activate NFCEE,
+**                         NFC_MODE_DEACTIVATE to de-activate.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_NfceeModeSet (UINT8              nfcee_id,
+                              tNFC_NFCEE_MODE    mode)
+{
+    if (mode >= NCI_NUM_NFCEE_MODE)
+    {
+        NFC_TRACE_ERROR1 ("NFC_NfceeModeSet bad mode:%d", mode);
+        return NFC_STATUS_FAILED;
+    }
+
+    return nci_snd_nfcee_mode_set (nfcee_id, mode);
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function         NFC_SetRouting
+**
+** Description      This function is called to configure the CE routing table.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_SET_ROUTING_REVT.
+**
+** Parameters
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetRouting (BOOLEAN more,
+                             UINT8  nfcee_id,
+                             UINT8  num_tlv,
+                             UINT8  tlv_size,
+                             UINT8  *p_param_tlvs)
+{
+    return nci_snd_set_routing_cmd (more, nfcee_id, num_tlv, tlv_size, p_param_tlvs);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetRouting
+**
+** Description      This function is called to retrieve the CE routing table from
+**                  NFCC. The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_GET_ROUTING_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_GetRouting (void)
+{
+    return nci_snd_get_routing_cmd ();
+}
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_main.c b/src/nfc/nfc/nfc_main.c
new file mode 100644
index 0000000..3850e4b
--- /dev/null
+++ b/src/nfc/nfc/nfc_main.c
@@ -0,0 +1,1316 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "hcidefs.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_hal_api.h"
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_int.h"
+#include "ce_int.h"
+
+#if (NFC_RW_ONLY == FALSE)
+#include "ce_api.h"
+#include "ce_int.h"
+#include "llcp_int.h"
+
+/* NFC mandates support for at least one logical connection;
+ * Update max_conn to the NFCC capability on InitRsp */
+#define NFC_SET_MAX_CONN_DEFAULT()    {nfc_cb.max_conn = 1;}
+
+#else /* NFC_RW_ONLY */
+#define ce_init()
+#define llcp_init()
+
+#define NFC_SET_MAX_CONN_DEFAULT()
+
+#endif /* NFC_RW_ONLY */
+/****************************************************************************
+** Declarations
+****************************************************************************/
+#if NFC_DYNAMIC_MEMORY == FALSE
+tNFC_CB nfc_cb;
+#endif
+
+#if (NFC_RW_ONLY == FALSE)
+#define NFC_NUM_INTERFACE_MAP   2
+#else
+#define NFC_NUM_INTERFACE_MAP   1
+#endif
+
+static const tNCI_DISCOVER_MAPS nfc_interface_mapping[NFC_NUM_INTERFACE_MAP] =
+{
+    /* Protocols that use Frame Interface do not need to be included in the interface mapping */
+    {
+        NCI_PROTOCOL_ISO_DEP,
+        NCI_INTERFACE_MODE_POLL_N_LISTEN,
+        NCI_INTERFACE_ISO_DEP
+    }
+#if (NFC_RW_ONLY == FALSE)
+    ,
+    /* this can not be set here due to 2079xB0 NFCC issues */
+    {
+        NCI_PROTOCOL_NFC_DEP,
+        NCI_INTERFACE_MODE_POLL_N_LISTEN,
+        NCI_INTERFACE_NFC_DEP
+    }
+#endif
+};
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         nfc_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *nfc_state_name (UINT8 state)
+{
+    switch (state)
+    {
+    case NFC_STATE_NONE:
+        return ("NONE");
+    case NFC_STATE_W4_HAL_OPEN:
+        return ("W4_HAL_OPEN");
+    case NFC_STATE_CORE_INIT:
+        return ("CORE_INIT");
+    case NFC_STATE_W4_POST_INIT_CPLT:
+        return ("W4_POST_INIT_CPLT");
+    case NFC_STATE_IDLE:
+        return ("IDLE");
+    case NFC_STATE_OPEN:
+        return ("OPEN");
+    case NFC_STATE_CLOSING:
+        return ("CLOSING");
+    case NFC_STATE_W4_HAL_CLOSE:
+        return ("W4_HAL_CLOSE");
+    case NFC_STATE_NFCC_POWER_OFF_SLEEP:
+        return ("NFCC_POWER_OFF_SLEEP");
+    default:
+        return ("???? UNKNOWN STATE");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_event_name
+**
+** Description      This function returns the HAL event name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *nfc_hal_event_name (UINT8 event)
+{
+    switch (event)
+    {
+    case HAL_NFC_OPEN_CPLT_EVT:
+        return ("HAL_NFC_OPEN_CPLT_EVT");
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+        return ("HAL_NFC_CLOSE_CPLT_EVT");
+
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+        return ("HAL_NFC_POST_INIT_CPLT_EVT");
+
+    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+        return ("HAL_NFC_PRE_DISCOVER_CPLT_EVT");
+
+    case HAL_NFC_REQUEST_CONTROL_EVT:
+        return ("HAL_NFC_REQUEST_CONTROL_EVT");
+
+    case HAL_NFC_RELEASE_CONTROL_EVT:
+        return ("HAL_NFC_RELEASE_CONTROL_EVT");
+
+    case HAL_NFC_ERROR_EVT:
+        return ("HAL_NFC_ERROR_EVT");
+
+    default:
+        return ("???? UNKNOWN EVENT");
+    }
+}
+#endif /* BT_TRACE_VERBOSE == TRUE */
+
+/*******************************************************************************
+**
+** Function         nfc_main_notify_enable_status
+**
+** Description      Notify status of Enable/PowerOffSleep/PowerCycle
+**
+*******************************************************************************/
+static void nfc_main_notify_enable_status (tNFC_STATUS nfc_status)
+{
+    tNFC_RESPONSE   evt_data;
+
+    evt_data.status = nfc_status;
+
+    if (nfc_cb.p_resp_cback)
+    {
+        /* if getting out of PowerOffSleep mode or restarting NFCC */
+        if (nfc_cb.flags & (NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC))
+        {
+            nfc_cb.flags &= ~(NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC);
+            if (nfc_status != NFC_STATUS_OK)
+            {
+                nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
+            }
+            (*nfc_cb.p_resp_cback) (NFC_NFCC_RESTART_REVT, &evt_data);
+        }
+        else
+        {
+            (*nfc_cb.p_resp_cback) (NFC_ENABLE_REVT, &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_enabled
+**
+** Description      NFCC enabled, proceed with stack start up.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_enabled (tNFC_STATUS nfc_status, BT_HDR *p_init_rsp_msg)
+{
+    tNFC_RESPONSE evt_data;
+    tNFC_CONN_CB  *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+    UINT8   *p;
+    UINT8   num_interfaces = 0, xx;
+    int     yy = 0;
+
+    memset (&evt_data, 0, sizeof (tNFC_RESPONSE));
+
+    if (nfc_status == NCI_STATUS_OK)
+    {
+        nfc_set_state (NFC_STATE_IDLE);
+
+        p = (UINT8 *) (p_init_rsp_msg + 1) + p_init_rsp_msg->offset + NCI_MSG_HDR_SIZE + 1;
+        /* we currently only support NCI of the same version.
+        * We may need to change this, when we support multiple version of NFCC */
+        evt_data.enable.nci_version = NCI_VERSION;
+        STREAM_TO_UINT32 (evt_data.enable.nci_features, p);
+        STREAM_TO_UINT8 (num_interfaces, p);
+
+        evt_data.enable.nci_interfaces = 0;
+        for (xx = 0; xx < num_interfaces; xx++)
+        {
+            if ((*p) <= NCI_INTERFACE_MAX)
+                evt_data.enable.nci_interfaces |= (1 << (*p));
+            else if (((*p) > NCI_INTERFACE_FIRST_VS) && (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE))
+            {
+                /* save the VS RF interface in control block, if there's still room */
+                nfc_cb.vs_interface[yy++] = *p;
+            }
+            p++;
+        }
+        nfc_cb.nci_interfaces    = evt_data.enable.nci_interfaces;
+        memcpy (evt_data.enable.vs_interface, nfc_cb.vs_interface, NFC_NFCC_MAX_NUM_VS_INTERFACE);
+        evt_data.enable.max_conn = *p++;
+        STREAM_TO_UINT16 (evt_data.enable.max_ce_table, p);
+#if (NFC_RW_ONLY == FALSE)
+        nfc_cb.max_ce_table          = evt_data.enable.max_ce_table;
+        nfc_cb.nci_features          = evt_data.enable.nci_features;
+        nfc_cb.max_conn              = evt_data.enable.max_conn;
+#endif
+        nfc_cb.nci_ctrl_size         = *p++; /* Max Control Packet Payload Length */
+        p_cb->init_credits           = p_cb->num_buff = 0;
+        STREAM_TO_UINT16 (evt_data.enable.max_param_size, p);
+        nfc_set_conn_id (p_cb, NFC_RF_CONN_ID);
+        evt_data.enable.manufacture_id   = *p++;
+        STREAM_TO_ARRAY (evt_data.enable.nfcc_info, p, NFC_NFCC_INFO_LEN);
+        NFC_DiscoveryMap (nfc_cb.num_disc_maps, (tNCI_DISCOVER_MAPS *) nfc_cb.p_disc_maps, NULL);
+    }
+    /* else not successful. the buffers will be freed in nfc_free_conn_cb () */
+    else
+    {
+        if (nfc_cb.flags & NFC_FL_RESTARTING)
+        {
+            nfc_set_state (NFC_STATE_NFCC_POWER_OFF_SLEEP);
+        }
+        else
+        {
+            nfc_free_conn_cb (p_cb);
+
+            /* if NFCC didn't respond to CORE_RESET or CORE_INIT */
+            if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT)
+            {
+                /* report status after closing HAL */
+                nfc_cb.p_hal->close ();
+                return;
+            }
+            else
+                nfc_set_state (NFC_STATE_NONE);
+        }
+    }
+
+    nfc_main_notify_enable_status (nfc_status);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_set_state
+**
+** Description      Set the state of NFC stack
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_set_state (tNFC_STATE nfc_state)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFC_TRACE_DEBUG4 ("nfc_set_state %d (%s)->%d (%s)", nfc_cb.nfc_state, nfc_state_name (nfc_cb.nfc_state), nfc_state, nfc_state_name (nfc_state));
+#else
+    NFC_TRACE_DEBUG2 ("nfc_set_state %d->%d", nfc_cb.nfc_state, nfc_state);
+#endif
+    nfc_cb.nfc_state = nfc_state;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_gen_cleanup
+**
+** Description      Clean up for both going into low power mode and disabling NFC
+**
+*******************************************************************************/
+void nfc_gen_cleanup (void)
+{
+    nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
+
+    /* the HAL pre-discover is still active - clear the pending flag/free the buffer */
+    if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+    {
+        nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+        GKI_freebuf (nfc_cb.p_disc_pending);
+        nfc_cb.p_disc_pending = NULL;
+    }
+
+    nfc_cb.flags &= ~(NFC_FL_CONTROL_REQUESTED|NFC_FL_CONTROL_GRANTED);
+
+    nfc_stop_timer (&nfc_cb.deactivate_timer);
+
+    /* Reset the connection control blocks */
+    nfc_reset_all_conn_cbs ();
+
+    if (nfc_cb.p_nci_init_rsp)
+    {
+        GKI_freebuf (nfc_cb.p_nci_init_rsp);
+        nfc_cb.p_nci_init_rsp = NULL;
+    }
+
+    /* clear any pending CMD/RSP */
+    nfc_main_flush_cmd_queue ();
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_handle_hal_evt
+**
+** Description      Handle BT_EVT_TO_NFC_MSGS
+**
+*******************************************************************************/
+void nfc_main_handle_hal_evt (tNFC_HAL_EVT_MSG *p_msg)
+{
+    UINT8  *ps;
+
+    NFC_TRACE_DEBUG1 ("nfc_main_handle_hal_evt(): HAL event=0x%x", p_msg->hal_evt);
+
+    switch (p_msg->hal_evt)
+    {
+    case HAL_NFC_OPEN_CPLT_EVT: /* only for failure case */
+        nfc_enabled (NFC_STATUS_FAILED, NULL);
+        break;
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+        if (nfc_cb.p_resp_cback)
+        {
+            if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE)
+            {
+                if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP)
+                {
+                    nfc_cb.flags &= ~NFC_FL_POWER_OFF_SLEEP;
+                    nfc_set_state (NFC_STATE_NFCC_POWER_OFF_SLEEP);
+                    (*nfc_cb.p_resp_cback) (NFC_NFCC_POWER_OFF_REVT, NULL);
+                }
+                else
+                {
+                    nfc_set_state (NFC_STATE_NONE);
+                    (*nfc_cb.p_resp_cback) (NFC_DISABLE_REVT, NULL);
+                    nfc_cb.p_resp_cback = NULL;
+                }
+            }
+            else
+            {
+                /* found error during initialization */
+                nfc_set_state (NFC_STATE_NONE);
+                nfc_main_notify_enable_status (NFC_STATUS_FAILED);
+            }
+        }
+        break;
+
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+        if (nfc_cb.p_nci_init_rsp)
+        {
+            /*
+            ** if NFC_Disable() is called before receiving HAL_NFC_POST_INIT_CPLT_EVT,
+            ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
+            */
+            if (nfc_cb.nfc_state == NFC_STATE_W4_POST_INIT_CPLT)
+            {
+                if (p_msg->status == HAL_NFC_STATUS_OK)
+                {
+                    nfc_enabled (NCI_STATUS_OK, nfc_cb.p_nci_init_rsp);
+                }
+                else /* if post initailization failed */
+                {
+                    nfc_enabled (NCI_STATUS_FAILED, NULL);
+                }
+            }
+
+            GKI_freebuf (nfc_cb.p_nci_init_rsp);
+            nfc_cb.p_nci_init_rsp = NULL;
+        }
+        break;
+
+    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+        /* restore the command window, no matter if the discover command is still pending */
+        nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+        nfc_cb.flags         &= ~NFC_FL_CONTROL_GRANTED;
+        if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+        {
+            /* issue the discovery command now, if it is still pending */
+            nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+            ps            = (UINT8 *)nfc_cb.p_disc_pending;
+            nci_snd_discover_cmd (*ps, (tNFC_DISCOVER_PARAMS *)(ps + 1));
+            GKI_freebuf (nfc_cb.p_disc_pending);
+            nfc_cb.p_disc_pending = NULL;
+        }
+        else
+        {
+            /* check if there's other pending commands */
+            nfc_ncif_check_cmd_queue (NULL);
+        }
+
+        if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
+            nfc_ncif_event_status (NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+        break;
+
+    case HAL_NFC_REQUEST_CONTROL_EVT:
+        nfc_cb.flags    |= NFC_FL_CONTROL_REQUESTED;
+        nfc_ncif_check_cmd_queue (NULL);
+        break;
+
+    case HAL_NFC_RELEASE_CONTROL_EVT:
+        if (nfc_cb.flags & NFC_FL_CONTROL_GRANTED)
+        {
+            nfc_cb.flags &= ~NFC_FL_CONTROL_GRANTED;
+            nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+            nfc_ncif_check_cmd_queue (NULL);
+
+            if (p_msg->status == HAL_NFC_STATUS_ERR_CMD_TIMEOUT)
+                nfc_ncif_event_status (NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+        }
+        break;
+
+    case HAL_NFC_ERROR_EVT:
+        switch (p_msg->status)
+        {
+        case HAL_NFC_STATUS_ERR_TRANSPORT:
+            /* Notify app of transport error */
+            if (nfc_cb.p_resp_cback)
+            {
+                (*nfc_cb.p_resp_cback) (NFC_NFCC_TRANSPORT_ERR_REVT, NULL);
+
+                /* if enabling NFC, notify upper layer of failure after closing HAL */
+                if (nfc_cb.nfc_state < NFC_STATE_IDLE)
+                {
+                    nfc_enabled (NFC_STATUS_FAILED, NULL);
+                }
+            }
+            break;
+
+        case HAL_NFC_STATUS_ERR_CMD_TIMEOUT:
+            nfc_ncif_event_status (NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+
+            /* if enabling NFC, notify upper layer of failure after closing HAL */
+            if (nfc_cb.nfc_state < NFC_STATE_IDLE)
+            {
+                nfc_enabled (NFC_STATUS_FAILED, NULL);
+                return;
+            }
+            break;
+
+        default:
+            break;
+        }
+        break;
+
+    default:
+        NFC_TRACE_ERROR1 ("nfc_main_handle_hal_evt (): unhandled event (0x%x).", p_msg->hal_evt);
+        break;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_main_flush_cmd_queue
+**
+** Description      This function is called when setting power off sleep state.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_main_flush_cmd_queue (void)
+{
+    BT_HDR *p_msg;
+
+    NFC_TRACE_DEBUG0 ("nfc_main_flush_cmd_queue ()");
+
+    /* initialize command window */
+    nfc_cb.nci_cmd_window = NCI_MAX_CMD_WINDOW;
+
+    /* Stop command-pending timer */
+    nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
+
+    /* dequeue and free buffer */
+    while ((p_msg = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q)) != NULL)
+    {
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_post_hal_evt
+**
+** Description      This function posts HAL event to NFC_TASK
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_main_post_hal_evt (UINT8 hal_evt, tHAL_NFC_STATUS status)
+{
+    tNFC_HAL_EVT_MSG *p_msg;
+
+    if ((p_msg = (tNFC_HAL_EVT_MSG *) GKI_getbuf (sizeof(tNFC_HAL_EVT_MSG))) != NULL)
+    {
+        /* Initialize BT_HDR */
+        p_msg->hdr.len    = 0;
+        p_msg->hdr.event  = BT_EVT_TO_NFC_MSGS;
+        p_msg->hdr.offset = 0;
+        p_msg->hdr.layer_specific = 0;
+        p_msg->hal_evt = hal_evt;
+        p_msg->status  = status;
+        GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+    }
+    else
+    {
+        NFC_TRACE_ERROR0 ("nfc_main_post_hal_evt (): No buffer");
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_main_hal_cback
+**
+** Description      HAL event handler
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_main_hal_cback(UINT8 event, tHAL_NFC_STATUS status)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFC_TRACE_DEBUG3 ("nfc_main_hal_cback event: %s(0x%x), status=%d",
+                       nfc_hal_event_name (event), event, status);
+#else
+    NFC_TRACE_DEBUG2 ("nfc_main_hal_cback event: 0x%x, status=%d", event, status);
+#endif
+
+    switch (event)
+    {
+    case HAL_NFC_OPEN_CPLT_EVT:
+        /*
+        ** if NFC_Disable() is called before receiving HAL_NFC_OPEN_CPLT_EVT,
+        ** then wait for HAL_NFC_CLOSE_CPLT_EVT.
+        */
+        if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_OPEN)
+        {
+            if (status == HAL_NFC_STATUS_OK)
+            {
+                /* Notify NFC_TASK that NCI tranport is initialized */
+                GKI_send_event (NFC_TASK, NFC_TASK_EVT_TRANSPORT_READY);
+            }
+            else
+            {
+                nfc_main_post_hal_evt (event, status);
+            }
+        }
+        break;
+
+    case HAL_NFC_CLOSE_CPLT_EVT:
+    case HAL_NFC_POST_INIT_CPLT_EVT:
+    case HAL_NFC_PRE_DISCOVER_CPLT_EVT:
+    case HAL_NFC_REQUEST_CONTROL_EVT:
+    case HAL_NFC_RELEASE_CONTROL_EVT:
+    case HAL_NFC_ERROR_EVT:
+        nfc_main_post_hal_evt (event, status);
+        break;
+
+    default:
+        NFC_TRACE_DEBUG1 ("nfc_main_hal_cback unhandled event %x", event);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_main_hal_data_cback
+**
+** Description      HAL data event handler
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_main_hal_data_cback(UINT16 data_len, UINT8   *p_data)
+{
+    BT_HDR *p_msg;
+
+    /* ignore all data while shutting down NFCC */
+    if (nfc_cb.nfc_state == NFC_STATE_W4_HAL_CLOSE)
+    {
+        return;
+    }
+
+    if (p_data)
+    {
+        if ((p_msg = (BT_HDR *) GKI_getpoolbuf (NFC_NCI_POOL_ID)) != NULL)
+        {
+            /* Initialize BT_HDR */
+            p_msg->len    = data_len;
+            p_msg->event  = BT_EVT_TO_NFC_NCI;
+            p_msg->offset = NFC_RECEIVE_MSGS_OFFSET;
+
+            /* no need to check length, it always less than pool size */
+            memcpy ((UINT8 *)(p_msg + 1) + p_msg->offset, p_data, p_msg->len);
+
+            GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+        }
+        else
+        {
+            NFC_TRACE_ERROR0 ("nfc_main_hal_data_cback (): No buffer");
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Enable
+**
+** Description      This function enables NFC. Prior to calling NFC_Enable:
+**                  - the NFCC must be powered up, and ready to receive commands.
+**                  - GKI must be enabled
+**                  - NFC_TASK must be started
+**                  - NCIT_TASK must be started (if using dedicated NCI transport)
+**
+**                  This function opens the NCI transport (if applicable),
+**                  resets the NFC controller, and initializes the NFC subsystems.
+**
+**                  When the NFC startup procedure is completed, an
+**                  NFC_ENABLE_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Enable (tNFC_RESPONSE_CBACK *p_cback)
+{
+    NFC_TRACE_API0 ("NFC_Enable ()");
+
+    /* Validate callback */
+    if (!p_cback)
+    {
+        return (NFC_STATUS_INVALID_PARAM);
+    }
+    nfc_cb.p_resp_cback = p_cback;
+
+    /* Open HAL transport. */
+    nfc_set_state (NFC_STATE_W4_HAL_OPEN);
+    nfc_cb.p_hal->open (nfc_main_hal_cback, nfc_main_hal_data_cback);
+
+    return (NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Disable
+**
+** Description      This function performs clean up routines for shutting down
+**                  NFC and closes the NCI transport (if using dedicated NCI
+**                  transport).
+**
+**                  When the NFC shutdown procedure is completed, an
+**                  NFC_DISABLED_REVT is returned to the application using the
+**                  tNFC_RESPONSE_CBACK.
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void NFC_Disable (void)
+{
+    NFC_TRACE_API1 ("NFC_Disable (): nfc_state = %d", nfc_cb.nfc_state);
+
+    if (nfc_cb.nfc_state == NFC_STATE_NONE || nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)
+    {
+        nfc_set_state (NFC_STATE_NONE);
+        if (nfc_cb.p_resp_cback)
+        {
+            (*nfc_cb.p_resp_cback) (NFC_DISABLE_REVT, NULL);
+            nfc_cb.p_resp_cback = NULL;
+        }
+        return;
+    }
+
+    /* Close transport and clean up */
+    nfc_task_shutdown_nfcc ();
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Init
+**
+** Description      This function initializes control block for NFC
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void NFC_Init (tHAL_NFC_ENTRY *p_hal_entry_tbl)
+{
+    int xx;
+
+    /* Clear nfc control block */
+    memset (&nfc_cb, 0, sizeof (tNFC_CB));
+
+    /* Reset the nfc control block */
+    for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
+    {
+        nfc_cb.conn_cb[xx].conn_id = NFC_ILLEGAL_CONN_ID;
+    }
+
+    /* NCI init */
+    nfc_cb.p_hal            = p_hal_entry_tbl;
+    nfc_cb.nfc_state        = NFC_STATE_NONE;
+    nfc_cb.nci_cmd_window   = NCI_MAX_CMD_WINDOW;
+    nfc_cb.nci_wait_rsp_tout= NFC_CMD_CMPL_TIMEOUT;
+    nfc_cb.p_disc_maps      = nfc_interface_mapping;
+    nfc_cb.num_disc_maps    = NFC_NUM_INTERFACE_MAP;
+    nfc_cb.trace_level      = NFC_INITIAL_TRACE_LEVEL;
+    nfc_cb.nci_ctrl_size    = NCI_CTRL_INIT_SIZE;
+
+    rw_init ();
+    ce_init ();
+    llcp_init ();
+    NFC_SET_MAX_CONN_DEFAULT ();
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetLmrtSize
+**
+** Description      Called by application wto query the Listen Mode Routing
+**                  Table size supported by NFCC
+**
+** Returns          Listen Mode Routing Table size
+**
+*******************************************************************************/
+UINT16 NFC_GetLmrtSize (void)
+{
+    UINT16 size = 0;
+#if (NFC_RW_ONLY == FALSE)
+    size = nfc_cb.max_ce_table;
+#endif
+    return size;
+}
+
+
+/*******************************************************************************
+**
+** Function         NFC_SetConfig
+**
+** Description      This function is called to send the configuration parameter
+**                  TLV to NFCC. The response from NFCC is reported by
+**                  tNFC_RESPONSE_CBACK as NFC_SET_CONFIG_REVT.
+**
+** Parameters       tlv_size - the length of p_param_tlvs.
+**                  p_param_tlvs - the parameter ID/Len/Value list
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetConfig (UINT8     tlv_size,
+                           UINT8    *p_param_tlvs)
+{
+    return nci_snd_core_set_config (p_param_tlvs, tlv_size);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_GetConfig
+**
+** Description      This function is called to retrieve the parameter TLV from NFCC.
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_GET_CONFIG_REVT.
+**
+** Parameters       num_ids - the number of parameter IDs
+**                  p_param_ids - the parameter ID list.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_GetConfig (UINT8     num_ids,
+                           UINT8    *p_param_ids)
+{
+    return nci_snd_core_get_config (p_param_ids, num_ids);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryMap
+**
+** Description      This function is called to set the discovery interface mapping.
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+**                  NFC_MAP_DEVT.
+**
+** Parameters       num - the number of items in p_params.
+**                  p_maps - the discovery interface mappings
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoveryMap (UINT8 num, tNFC_DISCOVER_MAPS *p_maps,
+                                        tNFC_DISCOVER_CBACK *p_cback)
+{
+    UINT8   num_disc_maps = num;
+    UINT8   xx, yy, num_intf, intf_mask;
+    tNFC_DISCOVER_MAPS  max_maps[NFC_NFCC_MAX_NUM_VS_INTERFACE + NCI_INTERFACE_MAX];
+    BOOLEAN is_supported;
+
+    nfc_cb.p_discv_cback = p_cback;
+    num_intf             = 0;
+    NFC_TRACE_DEBUG1 ("nci_interfaces supported by NFCC: 0x%x", nfc_cb.nci_interfaces);
+    for (xx = 0; xx < num_disc_maps; xx++)
+    {
+        is_supported = FALSE;
+        if (p_maps[xx].intf_type > NCI_INTERFACE_MAX)
+        {
+            for (yy = 0; yy < NFC_NFCC_MAX_NUM_VS_INTERFACE; yy++)
+            {
+                if (nfc_cb.vs_interface[yy] == p_maps[xx].intf_type)
+                    is_supported    = TRUE;
+            }
+            NFC_TRACE_DEBUG3 ("[%d]: vs intf_type:0x%x is_supported:%d", xx, p_maps[xx].intf_type, is_supported);
+        }
+        else
+        {
+            intf_mask = (1 << (p_maps[xx].intf_type));
+            if (intf_mask & nfc_cb.nci_interfaces)
+            {
+                is_supported    = TRUE;
+            }
+            NFC_TRACE_DEBUG4 ("[%d]: intf_type:%d intf_mask: 0x%x is_supported:%d", xx, p_maps[xx].intf_type, intf_mask, is_supported);
+        }
+        if (is_supported)
+            memcpy (&max_maps[num_intf++], &p_maps[xx], sizeof (tNFC_DISCOVER_MAPS));
+        else
+        {
+            NFC_TRACE_WARNING1 ("NFC_DiscoveryMap interface=0x%x is not supported by NFCC", p_maps[xx].intf_type);
+        }
+    }
+
+    return nci_snd_discover_map_cmd (num_intf, (tNCI_DISCOVER_MAPS *) max_maps);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoveryStart
+**
+** Description      This function is called to start Polling and/or Listening.
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK as.
+**                  NFC_START_DEVT. The notification from NFCC is reported by
+**                  tNFC_DISCOVER_CBACK as NFC_RESULT_DEVT.
+**
+** Parameters       num_params - the number of items in p_params.
+**                  p_params - the discovery parameters
+**                  p_cback - the discovery callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoveryStart (UINT8                 num_params,
+                                tNFC_DISCOVER_PARAMS *p_params,
+                                tNFC_DISCOVER_CBACK  *p_cback)
+{
+    UINT8   *p;
+    int     params_size;
+    tNFC_STATUS status = NFC_STATUS_NO_BUFFERS;
+
+    NFC_TRACE_API0 ("NFC_DiscoveryStart");
+    if (nfc_cb.p_disc_pending)
+    {
+        NFC_TRACE_ERROR0 ("There's pending NFC_DiscoveryStart");
+        status = NFC_STATUS_BUSY;
+    }
+    else
+    {
+        nfc_cb.p_discv_cback = p_cback;
+        nfc_cb.flags        |= NFC_FL_DISCOVER_PENDING;
+        nfc_cb.flags        |= NFC_FL_CONTROL_REQUESTED;
+        params_size          = sizeof (tNFC_DISCOVER_PARAMS) * num_params;
+        nfc_cb.p_disc_pending = GKI_getbuf ((UINT16)(BT_HDR_SIZE + 1 + params_size));
+        if (nfc_cb.p_disc_pending)
+        {
+            p       = (UINT8 *)nfc_cb.p_disc_pending;
+            *p++    = num_params;
+            memcpy (p, p_params, params_size);
+            status = NFC_STATUS_CMD_STARTED;
+            nfc_ncif_check_cmd_queue (NULL);
+        }
+    }
+
+    NFC_TRACE_API1 ("NFC_DiscoveryStart status: 0x%x", status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_DiscoverySelect
+**
+** Description      If tNFC_DISCOVER_CBACK reports status=NFC_MULTIPLE_PROT,
+**                  the application needs to use this function to select the
+**                  the logical endpoint to continue. The response from NFCC is
+**                  reported by tNFC_DISCOVER_CBACK as NFC_SELECT_DEVT.
+**
+** Parameters       rf_disc_id - The ID identifies the remote device.
+**                  protocol - the logical endpoint on the remote devide
+**                  rf_interface - the RF interface to communicate with NFCC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_DiscoverySelect (UINT8    rf_disc_id,
+                                 UINT8    protocol,
+                                 UINT8    rf_interface)
+{
+    return nci_snd_discover_select_cmd (rf_disc_id, protocol, rf_interface);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_ConnCreate
+**
+** Description      This function is called to create a logical connection with
+**                  NFCC for data exchange.
+**
+** Parameters       dest_type - the destination type
+**                  id   - the NFCEE ID or RF Discovery ID .
+**                  protocol   - the protocol.
+**                  p_cback - the connection callback function
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ConnCreate (UINT8            dest_type,
+                            UINT8            id,
+                            UINT8            protocol,
+                            tNFC_CONN_CBACK *p_cback)
+{
+    tNFC_STATUS     status = NFC_STATUS_FAILED;
+    tNFC_CONN_CB    *p_cb;
+    UINT8           num_tlv=0, tlv_size=0;
+    UINT8           param_tlvs[4], *pp;
+
+    p_cb = nfc_alloc_conn_cb (p_cback);
+    if (p_cb)
+    {
+        p_cb->id = id;
+        pp = param_tlvs;
+        if (dest_type == NCI_DEST_TYPE_NFCEE)
+        {
+            num_tlv = 1;
+            UINT8_TO_STREAM (pp, NCI_CON_CREATE_TAG_NFCEE_VAL);
+            UINT8_TO_STREAM (pp, 2);
+            UINT8_TO_STREAM (pp, id);
+            UINT8_TO_STREAM (pp, protocol);
+            tlv_size = 4;
+        }
+        else if (dest_type == NCI_DEST_TYPE_REMOTE)
+        {
+            num_tlv = 1;
+            UINT8_TO_STREAM (pp, NCI_CON_CREATE_TAG_RF_DISC_ID);
+            UINT8_TO_STREAM (pp, 1);
+            UINT8_TO_STREAM (pp, id);
+            tlv_size = 3;
+        }
+        else if (dest_type == NCI_DEST_TYPE_NFCC)
+        {
+            p_cb->id = NFC_TEST_ID;
+        }
+        /* Add handling of NCI_DEST_TYPE_REMOTE when more RF interface definitions are added */
+        p_cb->act_protocol = protocol;
+        p_cb->p_cback = p_cback;
+        status = nci_snd_core_conn_create (dest_type, num_tlv, tlv_size, param_tlvs);
+        if (status == NFC_STATUS_FAILED)
+            nfc_free_conn_cb (p_cb);
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_ConnClose
+**
+** Description      This function is called to close a logical connection with
+**                  NFCC.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_ConnClose (UINT8 conn_id)
+{
+    tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+    tNFC_STATUS     status = NFC_STATUS_FAILED;
+
+    if (p_cb)
+    {
+        status = nci_snd_core_conn_close (conn_id);
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetStaticRfCback
+**
+** Description      This function is called to update the data callback function
+**                  to receive the data for the given connection id.
+**
+** Parameters       p_cback - the connection callback function
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void NFC_SetStaticRfCback (tNFC_CONN_CBACK    *p_cback)
+{
+    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+
+    p_cb->p_cback = p_cback;
+    /* just in case DH has received NCI data before the data callback is set
+     * check if there's any data event to report on this connection id */
+    nfc_data_event (p_cb);
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SendData
+**
+** Description      This function is called to send the given data packet
+**                  to the connection identified by the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**                  p_data - the data packet.
+**                  p_data->offset must be >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE
+**                  The data payload starts at ((UINT8 *) (p_data + 1) + p_data->offset)
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendData (UINT8       conn_id,
+                          BT_HDR     *p_data)
+{
+    tNFC_STATUS     status = NFC_STATUS_FAILED;
+    tNFC_CONN_CB *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+
+    if (p_cb && p_data && p_data->offset >= NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE)
+    {
+        status = nfc_ncif_send_data (p_cb, p_data);
+    }
+
+    if (status != NFC_STATUS_OK)
+        GKI_freebuf (p_data);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_FlushData
+**
+** Description      This function is called to discard the tx data queue of
+**                  the given connection id.
+**
+** Parameters       conn_id - the connection id.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_FlushData (UINT8       conn_id)
+{
+    tNFC_STATUS     status = NFC_STATUS_FAILED;
+    tNFC_CONN_CB    *p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+    void            *p_buf;
+
+    if (p_cb)
+    {
+        status  = NFC_STATUS_OK;
+        while ((p_buf = GKI_dequeue (&p_cb->tx_q)) != NULL)
+            GKI_freebuf (p_buf);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_Deactivate
+**
+** Description      This function is called to stop the discovery process or
+**                  put the listen device in sleep mode or terminate the NFC link.
+**
+**                  The response from NFCC is reported by tNFC_DISCOVER_CBACK
+**                  as NFC_DEACTIVATE_DEVT.
+**
+** Parameters       deactivate_type - NFC_DEACTIVATE_TYPE_IDLE, to IDLE mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP to SLEEP mode.
+**                                    NFC_DEACTIVATE_TYPE_SLEEP_AF to SLEEP_AF mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_Deactivate (tNFC_DEACT_TYPE deactivate_type)
+{
+    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+    tNFC_STATUS  status = NFC_STATUS_OK;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    NFC_TRACE_API3 ("NFC_Deactivate %d (%s) deactivate_type:%d", nfc_cb.nfc_state, nfc_state_name (nfc_cb.nfc_state), deactivate_type);
+#else
+    NFC_TRACE_API2 ("NFC_Deactivate %d deactivate_type:%d", nfc_cb.nfc_state, deactivate_type);
+#endif
+
+    if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+    {
+        /* the HAL pre-discover is still active - clear the pending flag */
+        nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
+        GKI_freebuf (nfc_cb.p_disc_pending);
+        nfc_cb.p_disc_pending = NULL;
+        return NFC_STATUS_OK;
+    }
+
+    if (nfc_cb.nfc_state == NFC_STATE_OPEN)
+    {
+        nfc_set_state (NFC_STATE_CLOSING);
+        NFC_TRACE_DEBUG3 ( "act_protocol %d credits:%d/%d", p_cb->act_protocol, p_cb->init_credits, p_cb->num_buff);
+        if ((p_cb->act_protocol == NCI_PROTOCOL_NFC_DEP) &&
+            (p_cb->init_credits != p_cb->num_buff))
+        {
+            nfc_cb.flags           |= NFC_FL_DEACTIVATING;
+            nfc_cb.deactivate_timer.param = (TIMER_PARAM_TYPE) deactivate_type;
+            nfc_start_timer (&nfc_cb.deactivate_timer , (UINT16) (NFC_TTYPE_WAIT_2_DEACTIVATE), NFC_DEACTIVATE_TIMEOUT);
+            return status;
+        }
+    }
+
+    status = nci_snd_deactivate_cmd (deactivate_type);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_UpdateRFCommParams
+**
+** Description      This function is called to update RF Communication parameters
+**                  once the Frame RF Interface has been activated.
+**
+**                  The response from NFCC is reported by tNFC_RESPONSE_CBACK
+**                  as NFC_RF_COMM_PARAMS_UPDATE_REVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_UpdateRFCommParams (tNFC_RF_COMM_PARAMS *p_params)
+{
+    UINT8 tlvs[12];
+    UINT8 *p = tlvs;
+    UINT8 data_exch_config;
+
+    /* RF Technology and Mode */
+    if (p_params->include_rf_tech_mode)
+    {
+        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_TECH_N_MODE);
+        UINT8_TO_STREAM (p, 1);
+        UINT8_TO_STREAM (p, p_params->rf_tech_n_mode);
+    }
+
+    /* Transmit Bit Rate */
+    if (p_params->include_tx_bit_rate)
+    {
+        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_TX_BIT_RATE);
+        UINT8_TO_STREAM (p, 1);
+        UINT8_TO_STREAM (p, p_params->tx_bit_rate);
+    }
+
+    /* Receive Bit Rate */
+    if (p_params->include_tx_bit_rate)
+    {
+        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_RX_BIT_RATE);
+        UINT8_TO_STREAM (p, 1);
+        UINT8_TO_STREAM (p, p_params->rx_bit_rate);
+    }
+
+    /* NFC-B Data Exchange Configuration */
+    if (p_params->include_nfc_b_config)
+    {
+        UINT8_TO_STREAM (p, NCI_RF_PARAM_ID_B_DATA_EX_PARAM);
+        UINT8_TO_STREAM (p, 1);
+
+        data_exch_config =  (p_params->min_tr0 & 0x03) << 6;          /* b7b6 : Mininum TR0 */
+        data_exch_config |= (p_params->min_tr1 & 0x03) << 4;          /* b5b4 : Mininum TR1 */
+        data_exch_config |= (p_params->suppression_eos & 0x01) << 3;  /* b3 :   Suppression of EoS */
+        data_exch_config |= (p_params->suppression_sos & 0x01) << 2;  /* b2 :   Suppression of SoS */
+        data_exch_config |= (p_params->min_tr2 & 0x03);               /* b1b0 : Mininum TR2 */
+
+        UINT8_TO_STREAM (p, data_exch_config);
+    }
+
+    return nci_snd_parameter_update_cmd (tlvs, (UINT8) (p - tlvs));
+}
+
+/*******************************************************************************
+**
+** Function         NFC_SetPowerOffSleep
+**
+** Description      This function closes/opens transport and turns off/on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SetPowerOffSleep (BOOLEAN enable)
+{
+    NFC_TRACE_API1 ("NFC_SetPowerOffSleep () enable = %d", enable);
+
+    if (  (enable == FALSE)
+        &&(nfc_cb.nfc_state == NFC_STATE_NFCC_POWER_OFF_SLEEP)  )
+    {
+        nfc_cb.flags |= NFC_FL_RESTARTING;
+
+        /* open transport */
+        nfc_set_state (NFC_STATE_W4_HAL_OPEN);
+        nfc_cb.p_hal->open (nfc_main_hal_cback, nfc_main_hal_data_cback);
+
+        return NFC_STATUS_OK;
+    }
+    else if (  (enable == TRUE)
+             &&(nfc_cb.nfc_state == NFC_STATE_IDLE)  )
+    {
+        /* close transport to turn off NFCC and clean up */
+        nfc_cb.flags |= NFC_FL_POWER_OFF_SLEEP;
+        nfc_task_shutdown_nfcc ();
+
+        return NFC_STATUS_OK;
+    }
+
+    NFC_TRACE_ERROR1 ("NFC_SetPowerOffSleep () invalid state = %d", nfc_cb.nfc_state);
+    return NFC_STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function         NFC_PowerCycleNFCC
+**
+** Description      This function turns off and then on NFCC.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_PowerCycleNFCC (void)
+{
+    NFC_TRACE_API0 ("NFC_PowerCycleNFCC ()");
+
+    if (nfc_cb.nfc_state == NFC_STATE_IDLE)
+    {
+        /* power cycle NFCC */
+        nfc_cb.flags |= NFC_FL_POWER_CYCLE_NFCC;
+        nfc_task_shutdown_nfcc ();
+
+        return NFC_STATUS_OK;
+    }
+
+    NFC_TRACE_ERROR1 ("NFC_PowerCycleNFCC () invalid state = %d", nfc_cb.nfc_state);
+    return NFC_STATUS_FAILED;
+}
+
+
+/*******************************************************************************
+**
+** Function         NFC_SetTraceLevel
+**
+** Description      This function sets the trace level for NFC.  If called with
+**                  a value of 0xFF, it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 NFC_SetTraceLevel (UINT8 new_level)
+{
+    NFC_TRACE_API1 ("NFC_SetTraceLevel () new_level = %d", new_level);
+
+    if (new_level != 0xFF)
+        nfc_cb.trace_level = new_level;
+
+    return (nfc_cb.trace_level);
+}
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
new file mode 100644
index 0000000..0bf772b
--- /dev/null
+++ b/src/nfc/nfc/nfc_ncif.c
@@ -0,0 +1,1519 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if NFC_INCLUDED == TRUE
+#include "nfc_hal_api.h"
+#include "nfc_api.h"
+#include "nci_defs.h"
+#include "nci_hmsgs.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "hcidefs.h"
+#include "nfc_hal_api.h"
+
+#if (NFC_RW_ONLY == FALSE)
+static const UINT8 nfc_mpl_code_to_size[] =
+{64, 128, 192, 254};
+
+#endif /* NFC_RW_ONLY */
+
+
+#define NFC_PB_ATTRIB_REQ_FIXED_BYTES   1
+#define NFC_LB_ATTRIB_REQ_FIXED_BYTES   8
+
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_update_window
+**
+** Description      Update tx cmd window to indicate that NFCC can received
+**
+** Returns          void
+**
+*********************************************************************************/
+void nfc_ncif_update_window (void)
+{
+    /* Sanity check - see if we were expecting a update_window */
+    if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW)
+    {
+        if (nfc_cb.nfc_state != NFC_STATE_W4_HAL_CLOSE)
+        {
+            NFC_TRACE_ERROR0("nfc_ncif_update_window: Unexpected call");
+        }
+        return;
+    }
+
+    /* Stop command-pending timer */
+    nfc_stop_timer (&nfc_cb.nci_wait_rsp_timer);
+
+    nfc_cb.p_vsc_cback = NULL;
+    nfc_cb.nci_cmd_window++;
+
+    /* Check if there were any commands waiting to be sent */
+    nfc_ncif_check_cmd_queue (NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_cmd_timeout
+**
+** Description      Handle a command timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_cmd_timeout (void)
+{
+    NFC_TRACE_ERROR0 ("nfc_ncif_cmd_timeout");
+
+    /* report an error */
+    nfc_ncif_event_status(NFC_GEN_ERROR_REVT, NFC_STATUS_HW_TIMEOUT);
+    nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
+
+    /* if enabling NFC, notify upper layer of failure */
+    if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT)
+    {
+        nfc_enabled (NFC_STATUS_FAILED, NULL);
+    }
+
+    /* terminate the process so we'll try again */
+    NFC_TRACE_ERROR0 ("NFC controller stopped responding, aborting the NFC process");
+    abort();
+}
+
+/*******************************************************************************
+**
+** Function         nfc_wait_2_deactivate_timeout
+**
+** Description      Handle a command timeout
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_wait_2_deactivate_timeout (void)
+{
+    NFC_TRACE_ERROR0 ("nfc_wait_2_deactivate_timeout");
+    nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
+    nci_snd_deactivate_cmd ((UINT8) ((TIMER_PARAM_TYPE) nfc_cb.deactivate_timer.param));
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_send_data
+**
+** Description      This function is called to add the NCI data header
+**                  and send it to NCIT task for sending it to transport
+**                  as credits are available.
+**
+** Returns          void
+**
+*******************************************************************************/
+UINT8 nfc_ncif_send_data (tNFC_CONN_CB *p_cb, BT_HDR *p_data)
+{
+    UINT8 *pp;
+    UINT8 *ps;
+    UINT8   ulen = NCI_MAX_PAYLOAD_SIZE;
+    BT_HDR *p;
+    UINT8   pbf = 1;
+    UINT8   buffer_size = p_cb->buff_size;
+    UINT8   hdr0 = p_cb->conn_id;
+    BOOLEAN fragmented = FALSE;
+
+    NFC_TRACE_DEBUG3 ("nfc_ncif_send_data :%d, num_buff:%d qc:%d", p_cb->conn_id, p_cb->num_buff, p_cb->tx_q.count);
+    if (p_cb->id == NFC_RF_CONN_ID)
+    {
+        if (nfc_cb.nfc_state != NFC_STATE_OPEN)
+        {
+            if (nfc_cb.nfc_state == NFC_STATE_CLOSING)
+            {
+                if ((p_data == NULL) && /* called because credit from NFCC */
+                    (nfc_cb.flags  & NFC_FL_DEACTIVATING))
+                {
+                    if (p_cb->init_credits == p_cb->num_buff)
+                    {
+                        /* all the credits are back */
+                        nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
+                        NFC_TRACE_DEBUG2 ("deactivating NFC-DEP init_credits:%d, num_buff:%d", p_cb->init_credits, p_cb->num_buff);
+                        nfc_stop_timer(&nfc_cb.deactivate_timer);
+                        nci_snd_deactivate_cmd ((UINT8)((TIMER_PARAM_TYPE)nfc_cb.deactivate_timer.param));
+                    }
+                }
+            }
+            return NCI_STATUS_FAILED;
+        }
+    }
+
+    if (p_data)
+    {
+        /* always enqueue the data to the tx queue */
+        GKI_enqueue (&p_cb->tx_q, p_data);
+    }
+
+    /* try to send the first data packet in the tx queue  */
+    p_data = (BT_HDR *)GKI_getfirst (&p_cb->tx_q);
+
+    /* post data fragment to NCIT task as credits are available */
+    while (p_data && (p_data->len > 0) && (p_cb->num_buff > 0))
+    {
+        if (p_data->len <= buffer_size)
+        {
+            pbf         = 0;   /* last fragment */
+            ulen        = (UINT8)(p_data->len);
+            fragmented  = FALSE;
+        }
+        else
+        {
+            fragmented  = TRUE;
+            ulen        = buffer_size;
+        }
+
+        if (!fragmented)
+        {
+            /* if data packet is not fragmented, use the original buffer */
+            p         = p_data;
+            p_data    = (BT_HDR *)GKI_dequeue (&p_cb->tx_q);
+        }
+        else
+        {
+            /* the data packet is too big and need to be fragmented
+             * prepare a new GKI buffer
+             * (even the last fragment to avoid issues) */
+            if ((p = NCI_GET_CMD_BUF(ulen)) == NULL)
+                return (NCI_STATUS_BUFFER_FULL);
+            p->len    = ulen;
+            p->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+            pp        = (UINT8 *)(p + 1) + p->offset;
+            ps        = (UINT8 *)(p_data + 1) + p_data->offset;
+            memcpy (pp, ps, ulen);
+            /* adjust the BT_HDR on the old fragment */
+            p_data->len     -= ulen;
+            p_data->offset  += ulen;
+        }
+
+        p->event             = BT_EVT_TO_NFC_NCI;
+        p->layer_specific    = pbf;
+        p->len              += NCI_DATA_HDR_SIZE;
+        p->offset           -= NCI_DATA_HDR_SIZE;
+        pp = (UINT8 *)(p + 1) + p->offset;
+        /* build NCI Data packet header */
+        NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen);
+
+        if (p_cb->num_buff != NFC_CONN_NO_FC)
+            p_cb->num_buff--;
+
+        /* send to HAL */
+        nfc_cb.p_hal->write(p->len, (UINT8 *)(p+1) + p->offset);
+        GKI_freebuf(p);
+
+        if (!fragmented)
+        {
+            /* check if there are more data to send */
+            p_data = (BT_HDR *)GKI_getfirst (&p_cb->tx_q);
+        }
+    }
+
+    return (NCI_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_check_cmd_queue
+**
+** Description      Send NCI command to the transport
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_check_cmd_queue (BT_HDR *p_buf)
+{
+    UINT8   *ps;
+    /* If there are commands waiting in the xmit queue, or if the controller cannot accept any more commands, */
+    /* then enqueue this command */
+    if (p_buf)
+    {
+        if ((nfc_cb.nci_cmd_xmit_q.count) || (nfc_cb.nci_cmd_window == 0))
+        {
+            GKI_enqueue (&nfc_cb.nci_cmd_xmit_q, p_buf);
+            p_buf = NULL;
+        }
+    }
+
+    /* If controller can accept another command, then send the next command */
+    if (nfc_cb.nci_cmd_window > 0)
+    {
+        /* If no command was provided, or if older commands were in the queue, then get cmd from the queue */
+        if (!p_buf)
+            p_buf = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q);
+
+        if (p_buf)
+        {
+            /* save the message header to double check the response */
+            ps   = (UINT8 *)(p_buf + 1) + p_buf->offset;
+            memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE);
+            memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE);
+            if (p_buf->layer_specific == NFC_WAIT_RSP_VSC)
+            {
+                /* save the callback for NCI VSCs)  */
+                nfc_cb.p_vsc_cback = (void *)((tNFC_NCI_VS_MSG *)p_buf)->p_cback;
+            }
+
+            /* send to HAL */
+            nfc_cb.p_hal->write(p_buf->len, (UINT8 *)(p_buf+1) + p_buf->offset);
+            GKI_freebuf(p_buf);
+
+            /* Indicate command is pending */
+            nfc_cb.nci_cmd_window--;
+
+            /* start NFC command-timeout timer */
+            nfc_start_timer (&nfc_cb.nci_wait_rsp_timer, (UINT16)(NFC_TTYPE_NCI_WAIT_RSP), nfc_cb.nci_wait_rsp_tout);
+        }
+    }
+
+    if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW)
+    {
+        /* the command queue must be empty now */
+        if (nfc_cb.flags & NFC_FL_CONTROL_REQUESTED)
+        {
+            /* HAL requested control or stack needs to handle pre-discover */
+            nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
+            if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
+            {
+                if (nfc_cb.p_hal->prediscover ())
+                {
+                    /* HAL has the command window now */
+                    nfc_cb.flags         |= NFC_FL_CONTROL_GRANTED;
+                    nfc_cb.nci_cmd_window = 0;
+                }
+                else
+                {
+                    /* HAL does not need to send command,
+                     * - restore the command window and issue the discovery command now */
+                    nfc_cb.flags         &= ~NFC_FL_DISCOVER_PENDING;
+                    ps                    = (UINT8 *)nfc_cb.p_disc_pending;
+                    nci_snd_discover_cmd (*ps, (tNFC_DISCOVER_PARAMS *)(ps + 1));
+                    GKI_freebuf (nfc_cb.p_disc_pending);
+                    nfc_cb.p_disc_pending = NULL;
+                }
+            }
+            else
+            {
+                /* grant the control to HAL */
+                nfc_cb.flags         |= NFC_FL_CONTROL_GRANTED;
+                nfc_cb.nci_cmd_window = 0;
+                nfc_cb.p_hal->control_granted ();
+            }
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_send_cmd
+**
+** Description      Send NCI command to the NCIT task
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_send_cmd (BT_HDR *p_buf)
+{
+    /* post the p_buf to NCIT task */
+    p_buf->event            = BT_EVT_TO_NFC_NCI;
+    p_buf->layer_specific   = 0;
+    nfc_ncif_check_cmd_queue (p_buf);
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_process_event
+**
+** Description      This function is called to process the data/response/notification
+**                  from NFCC
+**
+** Returns          TRUE if need to free buffer
+**
+*******************************************************************************/
+BOOLEAN nfc_ncif_process_event (BT_HDR *p_msg)
+{
+    UINT8   mt, pbf, gid, *p, *pp;
+    BOOLEAN free = TRUE;
+    UINT8   oid;
+    UINT8   *p_old, old_gid, old_oid, old_mt;
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    pp = p;
+    NCI_MSG_PRS_HDR0 (pp, mt, pbf, gid);
+
+    switch (mt)
+    {
+    case NCI_MT_DATA:
+        NFC_TRACE_DEBUG0 ("NFC received data");
+        nfc_ncif_proc_data (p_msg);
+        free = FALSE;
+        break;
+
+    case NCI_MT_RSP:
+        NFC_TRACE_DEBUG1 ("NFC received rsp gid:%d", gid);
+        oid = ((*pp) & NCI_OID_MASK);
+        p_old   = nfc_cb.last_hdr;
+        NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid);
+        old_oid = ((*p_old) & NCI_OID_MASK);
+        /* make sure this is the RSP we are waiting for before updating the command window */
+        if ((old_gid != gid) || (old_oid != oid))
+        {
+            NFC_TRACE_ERROR2 ("nfc_ncif_process_event unexpected rsp: gid:0x%x, oid:0x%x", gid, oid);
+            return TRUE;
+        }
+
+        switch (gid)
+        {
+        case NCI_GID_CORE:      /* 0000b NCI Core group */
+            free = nci_proc_core_rsp (p_msg);
+            break;
+        case NCI_GID_RF_MANAGE:   /* 0001b NCI Discovery group */
+            nci_proc_rf_management_rsp (p_msg);
+            break;
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+        case NCI_GID_EE_MANAGE:  /* 0x02 0010b NFCEE Discovery group */
+            nci_proc_ee_management_rsp (p_msg);
+            break;
+#endif
+#endif
+        case NCI_GID_PROP:      /* 1111b Proprietary */
+                nci_proc_prop_rsp (p_msg);
+            break;
+        default:
+            NFC_TRACE_ERROR1 ("NFC: Unknown gid:%d", gid);
+            break;
+        }
+
+        nfc_ncif_update_window ();
+        break;
+
+    case NCI_MT_NTF:
+        NFC_TRACE_DEBUG1 ("NFC received ntf gid:%d", gid);
+        switch (gid)
+        {
+        case NCI_GID_CORE:      /* 0000b NCI Core group */
+            nci_proc_core_ntf (p_msg);
+            break;
+        case NCI_GID_RF_MANAGE:   /* 0001b NCI Discovery group */
+            nci_proc_rf_management_ntf (p_msg);
+            break;
+#if (NFC_NFCEE_INCLUDED == TRUE)
+#if (NFC_RW_ONLY == FALSE)
+        case NCI_GID_EE_MANAGE:  /* 0x02 0010b NFCEE Discovery group */
+            nci_proc_ee_management_ntf (p_msg);
+            break;
+#endif
+#endif
+        case NCI_GID_PROP:      /* 1111b Proprietary */
+                nci_proc_prop_ntf (p_msg);
+            break;
+        default:
+            NFC_TRACE_ERROR1 ("NFC: Unknown gid:%d", gid);
+            break;
+        }
+        break;
+
+    default:
+        NFC_TRACE_DEBUG2 ("NFC received unknown mt:0x%x, gid:%d", mt, gid);
+    }
+
+    return (free);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_rf_management_status
+**
+** Description      This function is called to report an event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_rf_management_status (tNFC_DISCOVER_EVT event, UINT8 status)
+{
+    tNFC_DISCOVER   evt_data;
+    if (nfc_cb.p_discv_cback)
+    {
+        evt_data.status = (tNFC_STATUS) status;
+        (*nfc_cb.p_discv_cback) (event, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_set_config_status
+**
+** Description      This function is called to report NFC_SET_CONFIG_REVT
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_set_config_status (UINT8 *p, UINT8 len)
+{
+    tNFC_RESPONSE   evt_data;
+    if (nfc_cb.p_resp_cback)
+    {
+        evt_data.set_config.status          = (tNFC_STATUS) *p++;
+        evt_data.set_config.num_param_id    = NFC_STATUS_OK;
+        if (evt_data.set_config.status != NFC_STATUS_OK)
+        {
+            evt_data.set_config.num_param_id    = *p++;
+            STREAM_TO_ARRAY (evt_data.set_config.param_ids, p, evt_data.set_config.num_param_id);
+        }
+
+        (*nfc_cb.p_resp_cback) (NFC_SET_CONFIG_REVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_event_status
+**
+** Description      This function is called to report an event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_event_status (tNFC_RESPONSE_EVT event, UINT8 status)
+{
+    tNFC_RESPONSE   evt_data;
+    if (nfc_cb.p_resp_cback)
+    {
+        evt_data.status = (tNFC_STATUS) status;
+        (*nfc_cb.p_resp_cback) (event, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_error_status
+**
+** Description      This function is called to report an error event to data cback
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_error_status (UINT8 conn_id, UINT8 status)
+{
+    tNFC_CONN_CB * p_cb;
+    p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+    if (p_cb && p_cb->p_cback)
+    {
+        (*p_cb->p_cback) (conn_id, NFC_ERROR_CEVT, (tNFC_CONN *) &status);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_rf_field_ntf
+**
+** Description      This function is called to process RF field notification
+**
+** Returns          void
+**
+*******************************************************************************/
+#if (NFC_RW_ONLY == FALSE)
+void nfc_ncif_proc_rf_field_ntf (UINT8 rf_status)
+{
+    tNFC_RESPONSE   evt_data;
+    if (nfc_cb.p_resp_cback)
+    {
+        evt_data.status            = (tNFC_STATUS) NFC_STATUS_OK;
+        evt_data.rf_field.rf_field = rf_status;
+        (*nfc_cb.p_resp_cback) (NFC_RF_FIELD_REVT, &evt_data);
+    }
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_credits
+**
+** Description      This function is called to process data credits
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_credits(UINT8 *p, UINT16 plen)
+{
+    UINT8   num, xx;
+    tNFC_CONN_CB * p_cb;
+
+    num = *p++;
+    for (xx = 0; xx < num; xx++)
+    {
+        p_cb = nfc_find_conn_cb_by_conn_id(*p++);
+        if (p_cb && p_cb->num_buff != NFC_CONN_NO_FC)
+        {
+            p_cb->num_buff += (*p);
+#if (BT_USE_TRACES == TRUE)
+            if (p_cb->num_buff > p_cb->init_credits)
+            {
+                if (nfc_cb.nfc_state == NFC_STATE_OPEN)
+                {
+                    /* if this happens in activated state, it's very likely that our NFCC has issues */
+                    /* However, credit may be returned after deactivation */
+                    NFC_TRACE_ERROR2( "num_buff:0x%x, init_credits:0x%x", p_cb->num_buff, p_cb->init_credits);
+                }
+                p_cb->num_buff = p_cb->init_credits;
+            }
+#endif
+            /* check if there's nay data in tx q to be sent */
+            nfc_ncif_send_data (p_cb, NULL);
+        }
+        p++;
+    }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_decode_rf_params
+**
+** Description      This function is called to process the detected technology
+**                  and mode and the associated parameters for DISCOVER_NTF and
+**                  ACTIVATE_NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+UINT8 * nfc_ncif_decode_rf_params (tNFC_RF_TECH_PARAMS *p_param, UINT8 *p)
+{
+    tNFC_RF_PA_PARAMS   *p_pa;
+    UINT8               len, *p_start, u8;
+    tNFC_RF_PB_PARAMS   *p_pb;
+    tNFC_RF_LF_PARAMS   *p_lf;
+    tNFC_RF_PF_PARAMS   *p_pf;
+    tNFC_RF_PISO15693_PARAMS *p_i93;
+
+    len             = *p++;
+    p_start         = p;
+    switch (p_param->mode)
+    {
+    case NCI_DISCOVERY_TYPE_POLL_A:
+    case NCI_DISCOVERY_TYPE_POLL_A_ACTIVE:
+        p_pa        = &p_param->param.pa;
+        /*
+SENS_RES Response   2 bytes Defined in [DIGPROT] Available after Technology Detection
+NFCID1 length   1 byte  Length of NFCID1 Available after Collision Resolution
+NFCID1  4, 7, or 10 bytes   Defined in [DIGPROT]Available after Collision Resolution
+SEL_RES Response    1 byte  Defined in [DIGPROT]Available after Collision Resolution
+        */
+        STREAM_TO_ARRAY (p_pa->sens_res, p, 2);
+        p_pa->nfcid1_len     = *p++;
+        if (p_pa->nfcid1_len > NCI_NFCID1_MAX_LEN)
+            p_pa->nfcid1_len = NCI_NFCID1_MAX_LEN;
+        STREAM_TO_ARRAY (p_pa->nfcid1, p, p_pa->nfcid1_len);
+        u8                   = *p++;
+        if (u8)
+            p_pa->sel_rsp    = *p++;
+        break;
+
+    case NCI_DISCOVERY_TYPE_POLL_B:
+        /*
+SENSB_RES Response length (n)   1 byte  Length of SENSB_RES Response (Byte 2 - Byte 12 or 13)Available after Technology Detection
+SENSB_RES Response Byte 2 - Byte 12 or 13   11 or 12 bytes  Defined in [DIGPROT] Available after Technology Detection
+        */
+        p_pb                = &p_param->param.pb;
+        p_pb->sensb_res_len = *p++;
+        if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN)
+            p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN;
+        STREAM_TO_ARRAY (p_pb->sensb_res, p, p_pb->sensb_res_len);
+        memcpy (p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN);
+        break;
+
+    case NCI_DISCOVERY_TYPE_POLL_F:
+    case NCI_DISCOVERY_TYPE_POLL_F_ACTIVE:
+        /*
+Bit Rate    1 byte  1   212 kbps/2   424 kbps/0 and 3 to 255  RFU
+SENSF_RES Response length.(n) 1 byte  Length of SENSF_RES (Byte 2 - Byte 17 or 19).Available after Technology Detection
+SENSF_RES Response Byte 2 - Byte 17 or 19  n bytes Defined in [DIGPROT] Available after Technology Detection
+        */
+        p_pf                = &p_param->param.pf;
+        p_pf->bit_rate      = *p++;
+        p_pf->sensf_res_len = *p++;
+        if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN)
+            p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN;
+        STREAM_TO_ARRAY (p_pf->sensf_res, p, p_pf->sensf_res_len);
+        memcpy (p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN);
+        p_pf->mrti_check    = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX];
+        p_pf->mrti_update   = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX];
+        break;
+
+    case NCI_DISCOVERY_TYPE_LISTEN_F:
+    case NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
+        p_lf                = &p_param->param.lf;
+        u8                  = *p++;
+        if (u8)
+        {
+            STREAM_TO_ARRAY (p_lf->nfcid2, p, NCI_NFCID2_LEN);
+        }
+        break;
+
+    case NCI_DISCOVERY_TYPE_POLL_ISO15693:
+        p_i93               = &p_param->param.pi93;
+        p_i93->flag         = *p++;
+        p_i93->dsfid        = *p++;
+        STREAM_TO_ARRAY (p_i93->uid, p, NFC_ISO15693_UID_LEN);
+        break;
+
+    case NCI_DISCOVERY_TYPE_POLL_KOVIO:
+        p_param->param.pk.uid_len = *p++;
+        STREAM_TO_ARRAY (p_param->param.pk.uid, p, NFC_KOVIO_MAX_LEN);
+        break;
+    }
+
+    return (p_start + len);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_discover_ntf
+**
+** Description      This function is called to process discover notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_discover_ntf (UINT8 *p, UINT16 plen)
+{
+    tNFC_DISCOVER   evt_data;
+
+    if (nfc_cb.p_discv_cback)
+    {
+        p                              += NCI_MSG_HDR_SIZE;
+        evt_data.status                 = NCI_STATUS_OK;
+        evt_data.result.rf_disc_id      = *p++;
+        evt_data.result.protocol        = *p++;
+
+        /* fill in tNFC_RESULT_DEVT */
+        evt_data.result.rf_tech_param.mode  = *p++;
+        p = nfc_ncif_decode_rf_params (&evt_data.result.rf_tech_param, p);
+
+        evt_data.result.more            = *p++;
+        (*nfc_cb.p_discv_cback) (NFC_RESULT_DEVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_activate
+**
+** Description      This function is called to process de-activate
+**                  response and notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_activate (UINT8 *p, UINT8 len)
+{
+    tNFC_DISCOVER   evt_data;
+    tNFC_INTF_PARAMS        *p_intf = &evt_data.activate.intf_param;
+    tNFC_INTF_PA_ISO_DEP    *p_pa_iso;
+    tNFC_INTF_LB_ISO_DEP    *p_lb_iso;
+    tNFC_INTF_PB_ISO_DEP    *p_pb_iso;
+#if (NFC_RW_ONLY == FALSE)
+    tNFC_INTF_PA_NFC_DEP    *p_pa_nfc;
+    int                     mpl_idx = 0;
+    UINT8                   gb_idx = 0, mpl;
+#endif
+    UINT8                   t0;
+    tNCI_DISCOVERY_TYPE     mode;
+    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+    UINT8                   *pp, len_act;
+    UINT8                   buff_size, num_buff;
+
+    nfc_set_state (NFC_STATE_OPEN);
+
+    memset (p_intf, 0, sizeof (tNFC_INTF_PARAMS));
+    evt_data.activate.rf_disc_id    = *p++;
+    p_intf->type                    = *p++;
+    evt_data.activate.protocol      = *p++;
+
+    if (evt_data.activate.protocol == NCI_PROTOCOL_18092_ACTIVE)
+        evt_data.activate.protocol = NCI_PROTOCOL_NFC_DEP;
+
+    evt_data.activate.rf_tech_param.mode    = *p++;
+    buff_size                               = *p++;
+    num_buff                                = *p++;
+    /* fill in tNFC_activate_DEVT */
+    p = nfc_ncif_decode_rf_params (&evt_data.activate.rf_tech_param, p);
+
+    evt_data.activate.rf_tech_param.mode    = *p++;
+    evt_data.activate.tx_bitrate            = *p++;
+    evt_data.activate.rx_bitrate            = *p++;
+    mode         = evt_data.activate.rf_tech_param.mode;
+    len_act      = *p++;
+    NFC_TRACE_DEBUG3 ("nfc_ncif_proc_activate:%d %d, mode:0x%02x", len, len_act, mode);
+    /* just in case the interface reports activation parameters not defined in the NCI spec */
+    p_intf->intf_param.frame.param_len      = len_act;
+    if (p_intf->intf_param.frame.param_len > NFC_MAX_RAW_PARAMS)
+        p_intf->intf_param.frame.param_len = NFC_MAX_RAW_PARAMS;
+    pp = p;
+    STREAM_TO_ARRAY (p_intf->intf_param.frame.param, pp, p_intf->intf_param.frame.param_len);
+    if (evt_data.activate.intf_param.type == NCI_INTERFACE_ISO_DEP)
+    {
+        /* Make max payload of NCI aligned to max payload of ISO-DEP for better performance */
+        if (buff_size > NCI_ISO_DEP_MAX_INFO)
+            buff_size = NCI_ISO_DEP_MAX_INFO;
+
+        switch (mode)
+        {
+        case NCI_DISCOVERY_TYPE_POLL_A:
+            p_pa_iso                  = &p_intf->intf_param.pa_iso;
+            p_pa_iso->ats_res_len     = *p++;
+
+            if (p_pa_iso->ats_res_len == 0)
+                break;
+
+            if (p_pa_iso->ats_res_len > NFC_MAX_ATS_LEN)
+                p_pa_iso->ats_res_len = NFC_MAX_ATS_LEN;
+            STREAM_TO_ARRAY (p_pa_iso->ats_res, p, p_pa_iso->ats_res_len);
+            pp = &p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
+            t0 = p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
+            pp++;       /* T0 */
+            if (t0 & NCI_ATS_TA_MASK)
+                pp++;   /* TA */
+            if (t0 & NCI_ATS_TB_MASK)
+            {
+                /* FWI (Frame Waiting time Integer) & SPGI (Start-up Frame Guard time Integer) */
+                p_pa_iso->fwi       = (((*pp) >> 4) & 0x0F);
+                p_pa_iso->sfgi      = ((*pp) & 0x0F);
+                pp++;   /* TB */
+            }
+            if (t0 & NCI_ATS_TC_MASK)
+            {
+                p_pa_iso->nad_used  = ((*pp) & 0x01);
+                pp++;   /* TC */
+            }
+            p_pa_iso->his_byte_len  = (UINT8) (p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res));
+            memcpy (p_pa_iso->his_byte,  pp, p_pa_iso->his_byte_len);
+            break;
+
+        case NCI_DISCOVERY_TYPE_LISTEN_A:
+            p_intf->intf_param.la_iso.rats = *p++;
+            break;
+
+        case NCI_DISCOVERY_TYPE_POLL_B:
+            /* ATTRIB RSP
+            Byte 1   Byte 2 ~ 2+n-1
+            MBLI/DID Higher layer - Response
+            */
+            p_pb_iso                     = &p_intf->intf_param.pb_iso;
+            p_pb_iso->attrib_res_len     = *p++;
+
+            if (p_pb_iso->attrib_res_len == 0)
+                break;
+
+            if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN)
+                p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN;
+            STREAM_TO_ARRAY (p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len);
+            p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4;
+            if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES)
+            {
+                p_pb_iso->hi_info_len    = p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES;
+                if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
+                    p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
+                memcpy (p_pb_iso->hi_info, &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES], p_pb_iso->hi_info_len);
+            }
+            break;
+
+        case NCI_DISCOVERY_TYPE_LISTEN_B:
+            /* ATTRIB CMD
+            Byte 2~5 Byte 6  Byte 7  Byte 8  Byte 9  Byte 10 ~ 10+k-1
+            NFCID0   Param 1 Param 2 Param 3 Param 4 Higher layer - INF
+            */
+            p_lb_iso                     = &p_intf->intf_param.lb_iso;
+            p_lb_iso->attrib_req_len     = *p++;
+
+            if (p_lb_iso->attrib_req_len == 0)
+                break;
+
+            if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN)
+                p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN;
+            STREAM_TO_ARRAY (p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len);
+            memcpy (p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN);
+            if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES)
+            {
+                p_lb_iso->hi_info_len    = p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES;
+                if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
+                    p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
+                memcpy (p_lb_iso->hi_info, &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES], p_lb_iso->hi_info_len);
+            }
+            break;
+        }
+
+    }
+#if (NFC_RW_ONLY == FALSE)
+    else if (evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP)
+    {
+        /* Make max payload of NCI aligned to max payload of NFC-DEP for better performance */
+        if (buff_size > NCI_NFC_DEP_MAX_DATA)
+            buff_size = NCI_NFC_DEP_MAX_DATA;
+
+        p_pa_nfc                  = &p_intf->intf_param.pa_nfc;
+        p_pa_nfc->atr_res_len     = *p++;
+
+        if (p_pa_nfc->atr_res_len > 0)
+        {
+            if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN)
+                p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN;
+            STREAM_TO_ARRAY (p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len);
+            if (  (mode == NCI_DISCOVERY_TYPE_POLL_A)
+                ||(mode == NCI_DISCOVERY_TYPE_POLL_F)
+                ||(mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE)
+                ||(mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE)  )
+            {
+                /* ATR_RES
+                Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n
+                NFCID3T   DIDT    BST     BRT     TO      PPT     [GT0 ... GTn] */
+                mpl_idx                 = 14;
+                gb_idx                  = NCI_P_GEN_BYTE_INDEX;
+                p_pa_nfc->waiting_time  = p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F;
+            }
+            else if (  (mode == NCI_DISCOVERY_TYPE_LISTEN_A)
+                     ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F)
+                     ||(mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE)
+                     ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE)  )
+            {
+                /* ATR_REQ
+                Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n
+                NFCID3I   DIDI    BSI     BRI     PPI     [GI0 ... GIn] */
+                mpl_idx = 13;
+                gb_idx  = NCI_L_GEN_BYTE_INDEX;
+            }
+
+            mpl                         = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03;
+            p_pa_nfc->max_payload_size  = nfc_mpl_code_to_size[mpl];
+            if (p_pa_nfc->atr_res_len > gb_idx)
+            {
+                p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx;
+                if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN)
+                    p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN;
+                memcpy (p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx], p_pa_nfc->gen_bytes_len);
+            }
+        }
+    }
+#endif
+    p_cb->act_protocol  = evt_data.activate.protocol;
+    p_cb->buff_size     = buff_size;
+    p_cb->num_buff      = num_buff;
+    p_cb->init_credits  = num_buff;
+
+    if (nfc_cb.p_discv_cback)
+    {
+        (*nfc_cb.p_discv_cback) (NFC_ACTIVATE_DEVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_deactivate
+**
+** Description      This function is called to process de-activate
+**                  response and notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_deactivate (UINT8 status, UINT8 deact_type, BOOLEAN is_ntf)
+{
+    tNFC_DISCOVER   evt_data;
+    tNFC_DEACTIVATE_DEVT    *p_deact;
+    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+    void    *p_data;
+
+    nfc_set_state (NFC_STATE_IDLE);
+    p_deact             = &evt_data.deactivate;
+    p_deact->status     = status;
+    p_deact->type       = deact_type;
+    p_deact->is_ntf     = is_ntf;
+
+    while ((p_data = GKI_dequeue (&p_cb->rx_q)) != NULL)
+    {
+        GKI_freebuf (p_data);
+    }
+
+    while ((p_data = GKI_dequeue (&p_cb->tx_q)) != NULL)
+    {
+        GKI_freebuf (p_data);
+    }
+
+    if (p_cb->p_cback)
+        (*p_cb->p_cback) (NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN *) p_deact);
+
+    if (nfc_cb.p_discv_cback)
+    {
+        (*nfc_cb.p_discv_cback) (NFC_DEACTIVATE_DEVT, &evt_data);
+    }
+}
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_ee_action
+**
+** Description      This function is called to process NFCEE ACTION NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
+void nfc_ncif_proc_ee_action (UINT8 *p, UINT16 plen)
+{
+    tNFC_EE_ACTION_REVT evt_data;
+    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+    UINT8   data_len, ulen, tag, *p_data;
+    UINT8   max_len;
+
+    if (p_cback)
+    {
+        memset (&evt_data.act_data, 0, sizeof (tNFC_ACTION_DATA));
+        evt_data.status             = NFC_STATUS_OK;
+        evt_data.nfcee_id           = *p++;
+        evt_data.act_data.trigger   = *p++;
+        data_len                    = *p++;
+        if (plen >= 3)
+            plen -= 3;
+        if (data_len > plen)
+            data_len = (UINT8) plen;
+
+        switch (evt_data.act_data.trigger)
+        {
+        case NCI_EE_TRIG_7816_SELECT:
+            if (data_len > NFC_MAX_AID_LEN)
+                data_len = NFC_MAX_AID_LEN;
+            evt_data.act_data.param.aid.len_aid = data_len;
+            STREAM_TO_ARRAY (evt_data.act_data.param.aid.aid, p, data_len);
+            break;
+        case NCI_EE_TRIG_RF_PROTOCOL:
+            evt_data.act_data.param.protocol    = *p++;
+            break;
+        case NCI_EE_TRIG_RF_TECHNOLOGY:
+            evt_data.act_data.param.technology  = *p++;
+            break;
+        case NCI_EE_TRIG_APP_INIT:
+            while (data_len > NFC_TL_SIZE)
+            {
+                data_len    -= NFC_TL_SIZE;
+                tag         = *p++;
+                ulen        = *p++;
+                if (ulen > data_len)
+                    ulen = data_len;
+                p_data      = NULL;
+                max_len     = ulen;
+                switch (tag)
+                {
+                case NCI_EE_ACT_TAG_AID:    /* AID                 */
+                    if (max_len > NFC_MAX_AID_LEN)
+                        max_len = NFC_MAX_AID_LEN;
+                    evt_data.act_data.param.app_init.len_aid = max_len;
+                    p_data = evt_data.act_data.param.app_init.aid;
+                    break;
+                case NCI_EE_ACT_TAG_DATA:   /* hex data for app    */
+                    if (max_len > NFC_MAX_APP_DATA_LEN)
+                        max_len = NFC_MAX_APP_DATA_LEN;
+                    evt_data.act_data.param.app_init.len_data   = max_len;
+                    p_data                                      = evt_data.act_data.param.app_init.data;
+                    break;
+                }
+                if (p_data)
+                {
+                    STREAM_TO_ARRAY (p_data, p, max_len);
+                }
+                data_len -= ulen;
+            }
+            break;
+        }
+        (*p_cback) (NFC_EE_ACTION_REVT, (tNFC_RESPONSE *) &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_ee_discover_req
+**
+** Description      This function is called to process NFCEE DISCOVER REQ NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_ee_discover_req (UINT8 *p, UINT16 plen)
+{
+    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+    tNFC_EE_DISCOVER_REQ_REVT   ee_disc_req;
+    tNFC_EE_DISCOVER_INFO       *p_info;
+    UINT8                       u8;
+
+    NFC_TRACE_DEBUG2 ("nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen);
+    if (p_cback)
+    {
+        u8  = *p;
+        ee_disc_req.status      = NFC_STATUS_OK;
+        ee_disc_req.num_info    = *p++;
+        p_info                  = ee_disc_req.info;
+        if (plen)
+            plen--;
+        while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN))
+        {
+            p_info->op  = *p++;                  /* T */
+            if (*p != NFC_EE_DISCOVER_INFO_LEN)/* L */
+            {
+                NFC_TRACE_DEBUG1 ("bad entry len:%d", *p );
+                return;
+            }
+            p++;
+            /* V */
+            p_info->nfcee_id    = *p++;
+            p_info->tech_n_mode = *p++;
+            p_info->protocol    = *p++;
+            u8--;
+            plen    -=NFC_EE_DISCOVER_ENTRY_LEN;
+            p_info++;
+        }
+        (*p_cback) (NFC_EE_DISCOVER_REQ_REVT, (tNFC_RESPONSE *) &ee_disc_req);
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_get_routing
+**
+** Description      This function is called to process get routing notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_get_routing (UINT8 *p, UINT8 len)
+{
+    tNFC_GET_ROUTING_REVT evt_data;
+    UINT8       more, num_entries, xx, yy, *pn, tl;
+    tNFC_STATUS status = NFC_STATUS_CONTINUE;
+
+    if (nfc_cb.p_resp_cback)
+    {
+        more        = *p++;
+        num_entries = *p++;
+        for (xx = 0; xx < num_entries; xx++)
+        {
+            if ((more == FALSE) && (xx == (num_entries - 1)))
+                status = NFC_STATUS_OK;
+            evt_data.status         = (tNFC_STATUS) status;
+            evt_data.nfcee_id       = *p++;
+            evt_data.num_tlvs       = *p++;
+            evt_data.tlv_size       = 0;
+            pn                      = evt_data.param_tlvs;
+            for (yy = 0; yy < evt_data.num_tlvs; yy++)
+            {
+                tl                  = *(p+1);
+                tl                 += NFC_TL_SIZE;
+                STREAM_TO_ARRAY (pn, p, tl);
+                evt_data.tlv_size  += tl;
+                pn                 += tl;
+            }
+            (*nfc_cb.p_resp_cback) (NFC_GET_ROUTING_REVT, (tNFC_RESPONSE *) &evt_data);
+        }
+    }
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_conn_create_rsp
+**
+** Description      This function is called to process connection create
+**                  response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_conn_create_rsp (UINT8 *p, UINT16 plen, UINT8 dest_type)
+{
+    tNFC_CONN_CB * p_cb;
+    tNFC_STATUS    status;
+    tNFC_CONN_CBACK *p_cback;
+    tNFC_CONN   evt_data;
+    UINT8           conn_id;
+
+    /* find the pending connection control block */
+    p_cb                = nfc_find_conn_cb_by_conn_id (NFC_PEND_CONN_ID);
+    if (p_cb)
+    {
+        p                                  += NCI_MSG_HDR_SIZE;
+        status                              = *p++;
+        p_cb->buff_size                     = *p++;
+        p_cb->num_buff = p_cb->init_credits = *p++;
+        conn_id                             = *p++;
+        evt_data.conn_create.status         = status;
+        evt_data.conn_create.dest_type      = dest_type;
+        evt_data.conn_create.id             = p_cb->id;
+        evt_data.conn_create.buff_size      = p_cb->buff_size;
+        evt_data.conn_create.num_buffs      = p_cb->num_buff;
+        p_cback = p_cb->p_cback;
+        if (status == NCI_STATUS_OK)
+        {
+            nfc_set_conn_id (p_cb, conn_id);
+        }
+        else
+        {
+            nfc_free_conn_cb (p_cb);
+        }
+
+
+        if (p_cback)
+            (*p_cback) (conn_id, NFC_CONN_CREATE_CEVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_report_conn_close_evt
+**
+** Description      This function is called to report connection close event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_report_conn_close_evt (UINT8 conn_id, tNFC_STATUS status)
+{
+    tNFC_CONN       evt_data;
+    tNFC_CONN_CBACK *p_cback;
+    tNFC_CONN_CB    *p_cb;
+
+    p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
+    if (p_cb)
+    {
+        p_cback         = p_cb->p_cback;
+        nfc_free_conn_cb (p_cb);
+        evt_data.status = status;
+        if (p_cback)
+            (*p_cback) (conn_id, NFC_CONN_CLOSE_CEVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_reset_rsp
+**
+** Description      This function is called to process reset response/notification
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_reset_rsp (UINT8 *p, BOOLEAN is_ntf)
+{
+    UINT8 status = *p++;
+
+    if (is_ntf)
+    {
+        NFC_TRACE_ERROR1 ("reset notification!!:0x%x ", status);
+        /* clean up, if the state is OPEN
+         * FW does not report reset ntf right now */
+        if (nfc_cb.nfc_state == NFC_STATE_OPEN)
+        {
+            /*if any conn_cb is connected, close it.
+              if any pending outgoing packets are dropped.*/
+            nfc_reset_all_conn_cbs ();
+        }
+        status = NCI_STATUS_OK;
+    }
+
+    if (nfc_cb.flags & (NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC))
+    {
+        nfc_reset_all_conn_cbs ();
+    }
+
+    if (status == NCI_STATUS_OK)
+    {
+        if ((*p) != NCI_VERSION)
+        {
+            NFC_TRACE_DEBUG2 ("NCI version mismatch!!:0x%02x != 0x%02x ", NCI_VERSION, *p);
+            if ((*p) < NCI_VERSION_0_F)
+            {
+                NFC_TRACE_ERROR0 ("NFCC version is too old");
+                status = NCI_STATUS_FAILED;
+            }
+        }
+    }
+
+    if (status == NCI_STATUS_OK)
+    {
+        nci_snd_core_init ();
+    }
+    else
+    {
+        NFC_TRACE_ERROR0 ("Failed to reset NFCC");
+        nfc_enabled (status, NULL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_init_rsp
+**
+** Description      This function is called to process init response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_init_rsp (BT_HDR *p_msg)
+{
+    UINT8 *p, status;
+    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+
+    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+    /* handle init params in nfc_enabled */
+    status   = *(p + NCI_MSG_HDR_SIZE);
+    if (status == NCI_STATUS_OK)
+    {
+        p_cb->id            = NFC_RF_CONN_ID;
+        p_cb->act_protocol  = NCI_PROTOCOL_UNKNOWN;
+
+        nfc_set_state (NFC_STATE_W4_POST_INIT_CPLT);
+
+        nfc_cb.p_nci_init_rsp = p_msg;
+        nfc_cb.p_hal->core_initialized (p);
+    }
+    else
+    {
+        nfc_enabled (status, NULL);
+        GKI_freebuf (p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_get_config_rsp
+**
+** Description      This function is called to process get config response
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_get_config_rsp (BT_HDR *p_evt)
+{
+    UINT8   *p;
+    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
+    tNFC_RESPONSE  evt_data;
+
+    p_evt->offset += NCI_MSG_HDR_SIZE;
+    p_evt->len    -= NCI_MSG_HDR_SIZE;
+    if (p_cback)
+    {
+        p                                = (UINT8 *) (p_evt + 1) + p_evt->offset;
+        evt_data.get_config.status       = *p++;
+        evt_data.get_config.tlv_size     = p_evt->len;
+        evt_data.get_config.p_param_tlvs = p;
+        (*p_cback) (NFC_GET_CONFIG_REVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_t3t_polling_ntf
+**
+** Description      Handle NCI_MSG_RF_T3T_POLLING NTF
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_t3t_polling_ntf (UINT8 *p, UINT16 plen)
+{
+    UINT8 status;
+    UINT8 num_responses;
+
+    /* Pass result to RW_T3T for processing */
+    STREAM_TO_UINT8 (status, p);
+    STREAM_TO_UINT8 (num_responses, p);
+    plen-=NFC_TL_SIZE;
+    rw_t3t_handle_nci_poll_ntf (status, num_responses, (UINT8) plen, p);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_data_event
+**
+** Description      Report Data event on the given connection control block
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_data_event (tNFC_CONN_CB * p_cb)
+{
+    BT_HDR      *p_evt;
+    tNFC_DATA_CEVT data_cevt;
+    UINT8       *p;
+
+    if (p_cb->p_cback)
+    {
+        while ((p_evt = (BT_HDR *)GKI_getfirst (&p_cb->rx_q)) != NULL)
+        {
+            if (p_evt->layer_specific & NFC_RAS_FRAGMENTED)
+            {
+                break;
+            }
+            p_evt = (BT_HDR *) GKI_dequeue (&p_cb->rx_q);
+            /* report data event */
+            p_evt->offset   += NCI_MSG_HDR_SIZE;
+            p_evt->len      -= NCI_MSG_HDR_SIZE;
+            if (p_evt->layer_specific)
+                data_cevt.status = NFC_STATUS_BAD_LENGTH;
+            else
+                data_cevt.status = NFC_STATUS_OK;
+            data_cevt.p_data = p_evt;
+            /* adjust payload, if needed */
+            if (p_cb->conn_id == NFC_RF_CONN_ID)
+            {
+                /* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status byte needs to be removed
+                 */
+                if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) && (p_cb->act_protocol <= NCI_PROTOCOL_T3T))
+                {
+                    p_evt->len--;
+                    p                = (UINT8 *) (p_evt + 1);
+                    data_cevt.status = *(p + p_evt->offset + p_evt->len);
+                }
+            }
+            (*p_cb->p_cback) (p_cb->conn_id, NFC_DATA_CEVT, (tNFC_CONN *) &data_cevt);
+            p_evt = NULL;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_ncif_proc_data
+**
+** Description      Find the connection control block associated with the data
+**                  packet. Assemble the data packet, if needed.
+**                  Report the Data event.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_ncif_proc_data (BT_HDR *p_msg)
+{
+    UINT8   *pp, cid;
+    tNFC_CONN_CB * p_cb;
+    UINT8   pbf;
+    BT_HDR  *p_last;
+    UINT8   *ps, *pd;
+    UINT16  size;
+    BT_HDR  *p_max = NULL;
+    UINT16  len;
+    UINT16  error_mask = 0;
+
+    pp   = (UINT8 *) (p_msg+1) + p_msg->offset;
+    NFC_TRACE_DEBUG3 ("nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]);
+    NCI_DATA_PRS_HDR (pp, pbf, cid, len);
+    p_cb = nfc_find_conn_cb_by_conn_id (cid);
+    if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE))
+    {
+        NFC_TRACE_DEBUG1 ("nfc_ncif_proc_data len:%d", len);
+        if (len > 0)
+        {
+            p_msg->layer_specific       = 0;
+            if (pbf)
+                p_msg->layer_specific   = NFC_RAS_FRAGMENTED;
+            p_last = (BT_HDR *)GKI_getlast (&p_cb->rx_q);
+            if (p_last && (p_last->layer_specific & NFC_RAS_FRAGMENTED))
+            {
+                /* last data buffer is not last fragment, append this new packet to the last */
+                size = GKI_get_buf_size(p_last);
+                if (size < (BT_HDR_SIZE + p_last->len + p_last->offset + len))
+                {
+                    /* the current size of p_last is not big enough to hold the new fragment, p_msg */
+                    if (size != GKI_MAX_BUF_SIZE)
+                    {
+                        /* try the biggest GKI pool */
+                        p_max = (BT_HDR *)GKI_getpoolbuf (GKI_MAX_BUF_SIZE_POOL_ID);
+                        if (p_max)
+                        {
+                            /* copy the content of last buffer to the new buffer */
+                            memcpy(p_max, p_last, BT_HDR_SIZE);
+                            pd  = (UINT8 *)(p_max + 1) + p_max->offset;
+                            ps  = (UINT8 *)(p_last + 1) + p_last->offset;
+                            memcpy(pd, ps, p_last->len);
+
+                            /* place the new buffer in the queue instead */
+                            GKI_remove_from_queue (&p_cb->rx_q, p_last);
+                            GKI_freebuf (p_last);
+                            GKI_enqueue (&p_cb->rx_q, p_max);
+                            p_last  = p_max;
+                        }
+                    }
+                    if (p_max == NULL)
+                    {
+                        p_last->layer_specific  |= NFC_RAS_TOO_BIG;
+                        NFC_TRACE_ERROR1 ("nci_reassemble_msg buffer overrun(%d)!!", len);
+                    }
+                }
+
+                ps   = (UINT8 *)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
+                len  = p_msg->len - NCI_MSG_HDR_SIZE;
+                if ((p_last->layer_specific & NFC_RAS_TOO_BIG) == 0)
+                {
+                    pd   = (UINT8 *)(p_last + 1) + p_last->offset + p_last->len;
+                    memcpy(pd, ps, len);
+                    p_last->len  += len;
+                    /* do not need to update pbf and len in NCI header.
+                     * They are stripped off at NFC_DATA_CEVT and len may exceed 255 */
+                    NFC_TRACE_DEBUG1 ("nfc_ncif_proc_data len:%d", p_last->len);
+                }
+
+                error_mask              = (p_last->layer_specific & NFC_RAS_TOO_BIG);
+                p_last->layer_specific  = (p_msg->layer_specific | error_mask);
+                GKI_freebuf (p_msg);
+#ifdef DISP_NCI
+                if ((p_last->layer_specific & NFC_RAS_FRAGMENTED) == 0)
+                {
+                    /* this packet was reassembled. display the complete packet */
+                    DISP_NCI ((UINT8 *)(p_last + 1) + p_last->offset, p_last->len, TRUE);
+                }
+#endif
+            }
+            else
+            {
+                /* enqueue the new buffer to the rx queue */
+                GKI_enqueue (&p_cb->rx_q, p_msg);
+            }
+            nfc_data_event (p_cb);
+            return;
+        }
+        /* else an empty data packet*/
+    }
+    GKI_freebuf (p_msg);
+}
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/nfc/nfc_task.c b/src/nfc/nfc/nfc_task.c
new file mode 100644
index 0000000..e8da53b
--- /dev/null
+++ b/src/nfc/nfc/nfc_task.c
@@ -0,0 +1,457 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Entry point for NFC_TASK
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_hal_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_int.h"
+#include "ce_int.h"
+#if (NFC_RW_ONLY == FALSE)
+#include "llcp_int.h"
+#else
+#define llcp_cleanup()
+#endif
+
+#if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
+#include "nfa_sys.h"
+#include "nfa_dm_int.h"
+#endif
+
+/*******************************************************************************
+**
+** Function         nfc_start_timer
+**
+** Description      Start a timer for the specified amount of time.
+**                  NOTE: The timeout resolution is in SECONDS! (Even
+**                          though the timer structure field is ticks)
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
+{
+    BT_HDR *p_msg;
+
+    /* if timer list is currently empty, start periodic GKI timer */
+    if (nfc_cb.timer_queue.p_first == NULL)
+    {
+        /* if timer starts on other than NFC task (scritp wrapper) */
+        if (GKI_get_taskid () != NFC_TASK)
+        {
+            /* post event to start timer in NFC task */
+            if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
+            {
+                p_msg->event = BT_EVT_TO_START_TIMER;
+                GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+            }
+        }
+        else
+        {
+            /* Start nfc_task 1-sec resolution timer */
+            GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE);
+        }
+    }
+
+    GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
+
+    p_tle->event = type;
+    p_tle->ticks = timeout;         /* Save the number of seconds for the timer */
+
+    GKI_add_to_timer_list (&nfc_cb.timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_remaining_time
+**
+** Description      Return amount of time to expire
+**
+** Returns          time in second
+**
+*******************************************************************************/
+UINT32 nfc_remaining_time (TIMER_LIST_ENT *p_tle)
+{
+    return (GKI_get_remaining_ticks (&nfc_cb.timer_queue, p_tle));
+}
+
+/*******************************************************************************
+**
+** Function         nfc_process_timer_evt
+**
+** Description      Process nfc GKI timer event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_process_timer_evt (void)
+{
+    TIMER_LIST_ENT  *p_tle;
+
+    GKI_update_timer_list (&nfc_cb.timer_queue, 1);
+
+    while ((nfc_cb.timer_queue.p_first) && (!nfc_cb.timer_queue.p_first->ticks))
+    {
+        p_tle = nfc_cb.timer_queue.p_first;
+        GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
+
+        switch (p_tle->event)
+        {
+        case NFC_TTYPE_NCI_WAIT_RSP:
+            nfc_ncif_cmd_timeout();
+            break;
+
+        case NFC_TTYPE_WAIT_2_DEACTIVATE:
+            nfc_wait_2_deactivate_timeout ();
+            break;
+
+        default:
+            NFC_TRACE_DEBUG2 ("nfc_process_timer_evt: timer:0x%x event (0x%04x)", p_tle, p_tle->event);
+            NFC_TRACE_DEBUG1 ("nfc_process_timer_evt: unhandled timer event (0x%04x)", p_tle->event);
+        }
+    }
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_cb.timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_stop_timer
+**
+** Description      Stop a timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_stop_timer (TIMER_LIST_ENT *p_tle)
+{
+    GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_cb.timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_start_quick_timer
+**
+** Description      Start a timer for the specified amount of time.
+**                  NOTE: The timeout resolution depends on including modules.
+**                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
+**                  time to ticks.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
+{
+    BT_HDR *p_msg;
+
+    /* if timer list is currently empty, start periodic GKI timer */
+    if (nfc_cb.quick_timer_queue.p_first == NULL)
+    {
+        /* if timer starts on other than NFC task (scritp wrapper) */
+        if (GKI_get_taskid () != NFC_TASK)
+        {
+            /* post event to start timer in NFC task */
+            if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
+            {
+                p_msg->event = BT_EVT_TO_START_QUICK_TIMER;
+                GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+            }
+        }
+        else
+        {
+            /* Quick-timer is required for LLCP */
+            GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+        }
+    }
+
+    GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+
+    p_tle->event = type;
+    p_tle->ticks = timeout; /* Save the number of ticks for the timer */
+
+    GKI_add_to_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+}
+
+
+
+
+/*******************************************************************************
+**
+** Function         nfc_stop_quick_timer
+**
+** Description      Stop a timer.
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_stop_quick_timer (TIMER_LIST_ENT *p_tle)
+{
+    GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_cb.quick_timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_QUICK_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_process_quick_timer_evt
+**
+** Description      Process quick timer event
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_process_quick_timer_evt (void)
+{
+    TIMER_LIST_ENT  *p_tle;
+
+    GKI_update_timer_list (&nfc_cb.quick_timer_queue, 1);
+
+    while ((nfc_cb.quick_timer_queue.p_first) && (!nfc_cb.quick_timer_queue.p_first->ticks))
+    {
+        p_tle = nfc_cb.quick_timer_queue.p_first;
+        GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
+
+        switch (p_tle->event)
+        {
+#if (NFC_RW_ONLY == FALSE)
+        case NFC_TTYPE_LLCP_LINK_MANAGER:
+        case NFC_TTYPE_LLCP_LINK_INACT:
+        case NFC_TTYPE_LLCP_DATA_LINK:
+        case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
+            llcp_process_timeout (p_tle);
+            break;
+#endif
+        case NFC_TTYPE_RW_T1T_RESPONSE:
+            rw_t1t_process_timeout (p_tle);
+            break;
+        case NFC_TTYPE_RW_T2T_RESPONSE:
+            rw_t2t_process_timeout (p_tle);
+            break;
+        case NFC_TTYPE_RW_T3T_RESPONSE:
+            rw_t3t_process_timeout (p_tle);
+            break;
+        case NFC_TTYPE_RW_T4T_RESPONSE:
+            rw_t4t_process_timeout (p_tle);
+            break;
+        case NFC_TTYPE_RW_I93_RESPONSE:
+            rw_i93_process_timeout (p_tle);
+            break;
+#if (NFC_RW_ONLY == FALSE)
+        case NFC_TTYPE_CE_T4T_UPDATE:
+            ce_t4t_process_timeout (p_tle);
+            break;
+#endif
+        default:
+            break;
+        }
+    }
+
+    /* if timer list is empty stop periodic GKI timer */
+    if (nfc_cb.quick_timer_queue.p_first == NULL)
+    {
+        GKI_stop_timer (NFC_QUICK_TIMER_ID);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_task_shutdown_nfcc
+**
+** Description      Handle NFC shutdown
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfc_task_shutdown_nfcc (void)
+{
+    BT_HDR        *p_msg;
+
+    /* Free any messages still in the mbox */
+    while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL)
+    {
+        GKI_freebuf (p_msg);
+    }
+
+    nfc_gen_cleanup ();
+
+    if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP)
+    {
+        nfc_set_state (NFC_STATE_W4_HAL_CLOSE);
+        nfc_cb.p_hal->close();
+    }
+    else if (nfc_cb.flags & NFC_FL_POWER_CYCLE_NFCC)
+    {
+        nfc_set_state (NFC_STATE_W4_HAL_OPEN);
+        nfc_cb.p_hal->power_cycle();
+    }
+    else
+    {
+        nfc_set_state (NFC_STATE_W4_HAL_CLOSE);
+        nfc_cb.p_hal->close();
+
+        /* Perform final clean up */
+        llcp_cleanup ();
+
+        /* Stop the timers */
+        GKI_stop_timer (NFC_TIMER_ID);
+        GKI_stop_timer (NFC_QUICK_TIMER_ID);
+#if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
+        GKI_stop_timer (NFA_TIMER_ID);
+#endif
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_task
+**
+** Description      NFC event processing task
+**
+** Returns          nothing
+**
+*******************************************************************************/
+UINT32 nfc_task (UINT32 param)
+{
+    UINT16  event;
+    BT_HDR  *p_msg;
+    BOOLEAN free_buf;
+
+    /* Initialize the nfc control block */
+    memset (&nfc_cb, 0, sizeof (tNFC_CB));
+    nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+    NFC_TRACE_DEBUG0 ("NFC_TASK started.");
+
+    /* main loop */
+    while (TRUE)
+    {
+        event = GKI_wait (0xFFFF, 0);
+
+        /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */
+        if (event & NFC_TASK_EVT_TRANSPORT_READY)
+        {
+            NFC_TRACE_DEBUG0 ("NFC_TASK got NFC_TASK_EVT_TRANSPORT_READY.");
+
+            /* Reset the NFC controller. */
+            nfc_set_state (NFC_STATE_CORE_INIT);
+            nci_snd_core_reset (NCI_RESET_TYPE_RESET_CFG);
+        }
+
+        if (event & NFC_MBOX_EVT_MASK)
+        {
+            /* Process all incoming NCI messages */
+            while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL)
+            {
+                free_buf = TRUE;
+
+                /* Determine the input message type. */
+                switch (p_msg->event & BT_EVT_MASK)
+                {
+                    case BT_EVT_TO_NFC_NCI:
+                        free_buf = nfc_ncif_process_event (p_msg);
+                        break;
+
+                    case BT_EVT_TO_START_TIMER :
+                        /* Start nfc_task 1-sec resolution timer */
+                        GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE);
+                        break;
+
+                    case BT_EVT_TO_START_QUICK_TIMER :
+                        /* Quick-timer is required for LLCP */
+                        GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+                        break;
+
+                    case BT_EVT_TO_NFC_MSGS:
+                        nfc_main_handle_hal_evt ((tNFC_HAL_EVT_MSG*)p_msg);
+                        break;
+
+                    default:
+                        NFC_TRACE_DEBUG1 ("nfc_task: unhandle mbox message, event=%04x", p_msg->event);
+                        break;
+                }
+
+                if (free_buf)
+                {
+                    GKI_freebuf (p_msg);
+                }
+            }
+        }
+
+        /* Process gki timer tick */
+        if (event & NFC_TIMER_EVT_MASK)
+        {
+            nfc_process_timer_evt ();
+        }
+
+        /* Process quick timer tick */
+        if (event & NFC_QUICK_TIMER_EVT_MASK)
+        {
+            nfc_process_quick_timer_evt ();
+        }
+
+#if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
+        if (event & NFA_MBOX_EVT_MASK)
+        {
+            while ((p_msg = (BT_HDR *) GKI_read_mbox (NFA_MBOX_ID)) != NULL)
+            {
+                nfa_sys_event (p_msg);
+            }
+        }
+
+        if (event & NFA_TIMER_EVT_MASK)
+        {
+            nfa_sys_timer_update ();
+        }
+#endif
+
+    }
+
+
+    NFC_TRACE_DEBUG0 ("nfc_task terminated");
+
+    GKI_exit_task (GKI_get_taskid ());
+    return 0;
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_test.c b/src/nfc/nfc/nfc_test.c
new file mode 100644
index 0000000..251c888
--- /dev/null
+++ b/src/nfc/nfc/nfc_test.c
@@ -0,0 +1,72 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+
+/****************************************************************************
+** Declarations
+****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         NFC_TestLoopback
+**
+** Description      This function is called to send the given data packet
+**                  to NFCC for loopback test.
+**                  When loopback data is received from NFCC, tNFC_TEST_CBACK .
+**                  reports a NFC_LOOPBACK_TEVT.
+**
+** Parameters       p_data - the data packet
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_TestLoopback (BT_HDR *p_data)
+{
+    tNFC_STATUS     status  = NFC_STATUS_FAILED;
+    tNFC_CONN_CB    *p_cb   = nfc_find_conn_cb_by_handle (NCI_TEST_ID);
+
+    if (p_data && p_cb && (p_data->offset >= (NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE)))
+    {
+        status = nfc_ncif_send_data (p_cb, p_data);
+    }
+
+    if (status != NFC_STATUS_OK)
+        GKI_freebuf (p_data);
+
+    return status;
+}
+
+
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_utils.c b/src/nfc/nfc/nfc_utils.c
new file mode 100644
index 0000000..ef0a553
--- /dev/null
+++ b/src/nfc/nfc/nfc_utils.c
@@ -0,0 +1,213 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "nfc_api.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_int.h"
+
+
+/*******************************************************************************
+**
+** Function         nfc_alloc_conn_cb
+**
+** Description      This function is called to allocation a control block for
+**                  NCI logical connection
+**
+** Returns          The allocated control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB * nfc_alloc_conn_cb (tNFC_CONN_CBACK *p_cback)
+{
+    int xx, max = NCI_MAX_CONN_CBS;
+    tNFC_CONN_CB *p_conn_cb = NULL;
+
+    NFC_CHECK_MAX_CONN ();
+    for (xx = 0; xx < max; xx++)
+    {
+        if (nfc_cb.conn_cb[xx].conn_id == NFC_ILLEGAL_CONN_ID)
+        {
+            nfc_cb.conn_cb[xx].conn_id  = NFC_PEND_CONN_ID; /* to indicate this cb is used */
+            p_conn_cb                   = &nfc_cb.conn_cb[xx];
+            p_conn_cb->p_cback          = p_cback;
+            break;
+        }
+    }
+    return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_set_conn_id
+**
+** Description      This function is called to set the connection id to the
+**                  connection control block and the id mapping table
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_set_conn_id (tNFC_CONN_CB * p_cb, UINT8 conn_id)
+{
+    UINT8   handle;
+
+    if (p_cb == NULL)
+        return;
+
+    p_cb->conn_id           = conn_id;
+    handle                  = (UINT8) (p_cb - nfc_cb.conn_cb + 1);
+    nfc_cb.conn_id[conn_id] = handle;
+    NFC_TRACE_DEBUG2 ("nfc_set_conn_id conn_id:%d, handle:%d", conn_id, handle);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_find_conn_cb_by_handle
+**
+** Description      This function is called to locate the control block for
+**                  loopback test.
+**
+** Returns          The loopback test control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB * nfc_find_conn_cb_by_handle (UINT8 id)
+{
+    int xx;
+    tNFC_CONN_CB *p_conn_cb = NULL;
+
+    for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
+    {
+        if (nfc_cb.conn_cb[xx].id == id)
+        {
+            p_conn_cb = &nfc_cb.conn_cb[xx];
+            break;
+        }
+    }
+    return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_find_conn_cb_by_conn_id
+**
+** Description      This function is called to locate the control block for
+**                  the given connection id
+**
+** Returns          The control block or NULL
+**
+*******************************************************************************/
+tNFC_CONN_CB * nfc_find_conn_cb_by_conn_id (UINT8 conn_id)
+{
+    tNFC_CONN_CB *p_conn_cb = NULL;
+    UINT8   handle;
+    UINT8   id;
+    int     xx;
+
+    if (conn_id == NFC_PEND_CONN_ID)
+    {
+        for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++)
+        {
+            if (nfc_cb.conn_cb[xx].conn_id == NFC_PEND_CONN_ID)
+            {
+                p_conn_cb   = &nfc_cb.conn_cb[xx];
+                break;
+            }
+        }
+    }
+    else
+    {
+        id         = conn_id & NFC_CONN_ID_ID_MASK;
+        if (id < NFC_MAX_CONN_ID)
+        {
+            handle = nfc_cb.conn_id[id];
+            if (handle > 0)
+                p_conn_cb = &nfc_cb.conn_cb[handle - 1];
+        }
+    }
+
+    return p_conn_cb;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_free_conn_cb
+**
+** Description      This function is called to free the control block and
+**                  resources and id mapping table
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_free_conn_cb (tNFC_CONN_CB *p_cb)
+{
+    void    *p_buf;
+
+    if (p_cb == NULL)
+        return;
+
+    while ((p_buf = GKI_dequeue (&p_cb->rx_q)) != NULL)
+        GKI_freebuf (p_buf);
+
+    while ((p_buf = GKI_dequeue (&p_cb->tx_q)) != NULL)
+        GKI_freebuf (p_buf);
+
+    nfc_cb.conn_id[p_cb->conn_id]   = 0;
+    p_cb->p_cback                   = NULL;
+    p_cb->conn_id                   = NFC_ILLEGAL_CONN_ID;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_reset_all_conn_cbs
+**
+** Description      This function is called to free all the control blocks and
+**                  resources and id mapping table
+**
+** Returns          void
+**
+*******************************************************************************/
+NFC_API extern void nfc_reset_all_conn_cbs (void)
+{
+    int xx;
+    tNFC_CONN_CB *p_conn_cb = &nfc_cb.conn_cb[0];
+    tNFC_DEACTIVATE_DEVT    deact;
+
+    deact.status     = NFC_STATUS_NOT_INITIALIZED;
+    deact.type       = NFC_DEACTIVATE_TYPE_IDLE;
+    deact.is_ntf     = TRUE;
+    for (xx = 0; xx < NCI_MAX_CONN_CBS; xx++, p_conn_cb++)
+    {
+        if (p_conn_cb->conn_id != NFC_ILLEGAL_CONN_ID)
+        {
+            if (p_conn_cb->p_cback)
+                (*p_conn_cb->p_cback) (p_conn_cb->conn_id, NFC_DEACTIVATE_CEVT, (tNFC_CONN *) &deact);
+            nfc_free_conn_cb (p_conn_cb);
+        }
+    }
+}
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/nfc/nfc_vs.c b/src/nfc/nfc/nfc_vs.c
new file mode 100644
index 0000000..f790940
--- /dev/null
+++ b/src/nfc/nfc/nfc_vs.c
@@ -0,0 +1,146 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that NCI vendor specific interface with the
+ *  NFCC. On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_target.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_int.h"
+
+/****************************************************************************
+** Declarations
+****************************************************************************/
+
+
+
+/*******************************************************************************
+**
+** Function         NFC_RegVSCback
+**
+** Description      This function is called to register or de-register a callback
+**                  function to receive Proprietary NCI response and notification
+**                  events.
+**                  The maximum number of callback functions allowed is NFC_NUM_VS_CBACKS
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_RegVSCback (BOOLEAN          is_register,
+                            tNFC_VS_CBACK   *p_cback)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    int i;
+
+    if (is_register)
+    {
+        for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
+        {
+            /* find an empty spot to hold the callback function */
+            if (nfc_cb.p_vs_cb[i] == NULL)
+            {
+                nfc_cb.p_vs_cb[i]  = p_cback;
+                status             = NFC_STATUS_OK;
+                break;
+            }
+        }
+    }
+    else
+    {
+        for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
+        {
+            /* find the callback to de-register */
+            if (nfc_cb.p_vs_cb[i] == p_cback)
+            {
+                nfc_cb.p_vs_cb[i]  = NULL;
+                status             = NFC_STATUS_OK;
+                break;
+            }
+        }
+    }
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function         NFC_SendVsCommand
+**
+** Description      This function is called to send the given vendor specific
+**                  command to NFCC. The response from NFCC is reported to the
+**                  given tNFC_VS_CBACK as (oid).
+**
+** Parameters       oid - The opcode of the VS command.
+**                  p_data - The parameters for the VS command
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS NFC_SendVsCommand (UINT8          oid,
+                               BT_HDR        *p_data,
+                               tNFC_VS_CBACK *p_cback)
+{
+    tNFC_STATUS     status = NFC_STATUS_OK;
+    UINT8           *pp;
+
+    /* Allow VSC with 0-length payload */
+    if (p_data == NULL)
+    {
+        p_data = NCI_GET_CMD_BUF (0);
+        if (p_data)
+        {
+            p_data->offset  = NCI_VSC_MSG_HDR_SIZE;
+            p_data->len     = 0;
+        }
+    }
+
+    /* Validate parameters */
+    if ((p_data == NULL) || (p_data->offset < NCI_VSC_MSG_HDR_SIZE) || (p_data->len > NCI_MAX_VSC_SIZE))
+    {
+        NFC_TRACE_ERROR1 ("buffer offset must be >= %d", NCI_VSC_MSG_HDR_SIZE);
+        if (p_data)
+            GKI_freebuf (p_data);
+        return NFC_STATUS_INVALID_PARAM;
+    }
+
+    p_data->event           = BT_EVT_TO_NFC_NCI;
+    p_data->layer_specific  = NFC_WAIT_RSP_VSC;
+    /* save the callback function in the BT_HDR, to receive the response */
+    ((tNFC_NCI_VS_MSG *) p_data)->p_cback = p_cback;
+
+    p_data->offset -= NCI_MSG_HDR_SIZE;
+    pp              = (UINT8 *) (p_data + 1) + p_data->offset;
+    NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_PROP);
+    NCI_MSG_BLD_HDR1 (pp, oid);
+    *pp             = (UINT8) p_data->len;
+    p_data->len    += NCI_MSG_HDR_SIZE;
+    nfc_ncif_check_cmd_queue (p_data);
+    return status;
+}
+
+
+
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/ce_main.c b/src/nfc/tags/ce_main.c
new file mode 100644
index 0000000..bc73070
--- /dev/null
+++ b/src/nfc/tags/ce_main.c
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "gki.h"
+
+tCE_CB  ce_cb;
+
+/*******************************************************************************
+*******************************************************************************/
+void ce_init (void)
+{
+    memset (&ce_cb, 0, sizeof (tCE_CB));
+    ce_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+    /* Initialize tag-specific fields of ce control block */
+    ce_t3t_init ();
+}
+
+/*******************************************************************************
+**
+** Function         CE_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS CE_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    BT_HDR  *p_data;
+    UINT8   *p;
+
+    if (ce_cb.p_cback)
+    {
+        /* a valid opcode for RW */
+        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+        if (p_data)
+        {
+            p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p = (UINT8 *) (p_data + 1) + p_data->offset;
+            memcpy (p, p_raw_data, data_len);
+            p_data->len = data_len;
+            CE_TRACE_EVENT1 ("CE SENT raw frame (0x%x)", data_len);
+            status = NFC_SendData (NFC_RF_CONN_ID, p_data);
+        }
+
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         CE_SetActivatedTagType
+**
+** Description      This function selects the tag type for CE mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS CE_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, UINT16 t3t_system_code, tCE_CBACK *p_cback)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    tNFC_PROTOCOL protocol = p_activate_params->protocol;
+
+    CE_TRACE_API1 ("CE_SetActivatedTagType protocol:%d", protocol);
+
+    switch (protocol)
+    {
+    case NFC_PROTOCOL_T1T:
+    case NFC_PROTOCOL_T2T:
+        return NFC_STATUS_FAILED;
+
+    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
+        /* store callback function before NFC_SetStaticRfCback () */
+        ce_cb.p_cback  = p_cback;
+        status = ce_select_t3t (t3t_system_code, p_activate_params->rf_tech_param.param.lf.nfcid2);
+        break;
+
+    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
+        /* store callback function before NFC_SetStaticRfCback () */
+        ce_cb.p_cback  = p_cback;
+        status = ce_select_t4t ();
+        break;
+
+    default:
+        CE_TRACE_ERROR0 ("CE_SetActivatedTagType Invalid protocol");
+        return NFC_STATUS_FAILED;
+    }
+
+    if (status != NFC_STATUS_OK)
+    {
+        NFC_SetStaticRfCback (NULL);
+        ce_cb.p_cback  = NULL;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         CE_SetTraceLevel
+**
+** Description      This function sets the trace level for Card Emulation mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 CE_SetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        ce_cb.trace_level = new_level;
+
+    return (ce_cb.trace_level);
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/ce_t3t.c b/src/nfc/tags/ce_t3t.c
new file mode 100644
index 0000000..62cc1c0
--- /dev/null
+++ b/src/nfc/tags/ce_t3t.c
@@ -0,0 +1,1060 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 3 tag in Card Emulation
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+enum {
+    CE_T3T_COMMAND_INVALID,
+    CE_T3T_COMMAND_NFC_FORUM,
+    CE_T3T_COMMAND_FELICA
+};
+
+/* T3T CE states */
+enum {
+    CE_T3T_STATE_NOT_ACTIVATED,
+    CE_T3T_STATE_IDLE,
+    CE_T3T_STATE_UPDATING
+};
+
+/* Bitmasks to indicate type of UPDATE */
+#define CE_T3T_UPDATE_FL_NDEF_UPDATE_START  0x01
+#define CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT   0x02
+#define CE_T3T_UPDATE_FL_UPDATE             0x04
+
+/*******************************************************************************
+* Static constant definitions
+*******************************************************************************/
+static const UINT8 CE_DEFAULT_LF_PMM[NCI_T3T_PMM_LEN] = {0x20, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};   /* Default PMm param */
+
+/*******************************************************************************
+**
+** Function         ce_t3t_init
+**
+** Description      Initialize tag-specific fields of ce control block
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_init (void)
+{
+    memcpy (ce_cb.mem.t3t.local_pmm, CE_DEFAULT_LF_PMM, NCI_T3T_PMM_LEN);
+    ce_cb.mem.t3t.ndef_info.nbr = CE_T3T_DEFAULT_CHECK_MAXBLOCKS;
+    ce_cb.mem.t3t.ndef_info.nbw = CE_T3T_DEFAULT_UPDATE_MAXBLOCKS;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_send_to_lower
+**
+** Description      Send C-APDU to lower layer
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_send_to_lower (BT_HDR *p_msg)
+{
+    UINT8 *p;
+
+    /* Set NFC-F SoD field (payload len + 1) */
+    p_msg->offset -= 1;         /* Point to SoD field */
+    p = (UINT8 *) (p_msg+1) + p_msg->offset;
+    UINT8_TO_STREAM (p, (p_msg->len+1));
+    p_msg->len += 1;            /* Increment len to include SoD */
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispT3TagMessage (p_msg, FALSE);
+#endif
+
+    if (NFC_SendData (NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK)
+    {
+        CE_TRACE_ERROR0 ("ce_t3t_send_to_lower (): NFC_SendData () failed");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_is_valid_opcode
+**
+** Description      Valid opcode
+**
+** Returns          Type of command
+**
+*******************************************************************************/
+UINT8 ce_t3t_is_valid_opcode (UINT8 cmd_id)
+{
+    UINT8 retval = CE_T3T_COMMAND_INVALID;
+
+    if (  (cmd_id == T3T_MSG_OPC_CHECK_CMD)
+        ||(cmd_id == T3T_MSG_OPC_UPDATE_CMD)  )
+    {
+        retval = CE_T3T_COMMAND_NFC_FORUM;
+    }
+    else if (  (cmd_id == T3T_MSG_OPC_POLL_CMD)
+             ||(cmd_id == T3T_MSG_OPC_REQ_SERVICE_CMD)
+             ||(cmd_id == T3T_MSG_OPC_REQ_RESPONSE_CMD)
+             ||(cmd_id == T3T_MSG_OPC_REQ_SYSTEMCODE_CMD)  )
+    {
+        retval = CE_T3T_COMMAND_FELICA;
+    }
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         ce_t3t_get_rsp_buf
+**
+** Description      Get a buffer for sending T3T messages
+**
+** Returns          BT_HDR *
+**
+*****************************************************************************/
+BT_HDR *ce_t3t_get_rsp_buf (void)
+{
+    BT_HDR *p_cmd_buf;
+
+    if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID)) != NULL)
+    {
+        /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
+        p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+        p_cmd_buf->len = 0;
+    }
+
+    return (p_cmd_buf);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_send_rsp
+**
+** Description      Send response to reader/writer
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_send_rsp (tCE_CB *p_ce_cb, UINT8 *p_nfcid2, UINT8 opcode, UINT8 status1, UINT8 status2)
+{
+    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+    BT_HDR *p_rsp_msg;
+    UINT8 *p_dst, *p_rsp_start;
+
+    /* If p_nfcid2 is NULL, then used activated NFCID2 */
+    if (p_nfcid2 == NULL)
+    {
+        p_nfcid2 = p_cb->local_nfcid2;
+    }
+
+    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+    {
+        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+        /* Response Code */
+        UINT8_TO_STREAM (p_dst, opcode);
+
+        /* Manufacturer ID */
+        ARRAY_TO_STREAM (p_dst, p_nfcid2, NCI_RF_F_UID_LEN);
+
+        /* Status1 and Status2 */
+        UINT8_TO_STREAM (p_dst, status1);
+        UINT8_TO_STREAM (p_dst, status2);
+
+        p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+        ce_t3t_send_to_lower (p_rsp_msg);
+    }
+    else
+    {
+        CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_handle_update_cmd
+**
+** Description      Handle UPDATE command from reader/writer
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_handle_update_cmd (tCE_CB *p_ce_cb, BT_HDR *p_cmd_msg)
+{
+    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+    UINT8 *p_temp;
+    UINT8 *p_block_list = p_cb->cur_cmd.p_block_list_start;
+    UINT8 *p_block_data = p_cb->cur_cmd.p_block_data_start;
+    UINT8 i, j, bl0;
+    UINT16 block_number, service_code, checksum, checksum_rx;
+    UINT32 newlen_hiword;
+    tCE_T3T_NDEF_INFO ndef_info;
+    tNFC_STATUS nfc_status = NFC_STATUS_OK;
+    UINT8 update_flags = 0;
+    tCE_UPDATE_INFO update_info;
+
+    /* If in idle state, notify app that update is starting */
+    if (p_cb->state == CE_T3T_STATE_IDLE)
+    {
+        p_cb->state = CE_T3T_STATE_UPDATING;
+    }
+
+    for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
+    {
+        /* Read byte0 of block list */
+        STREAM_TO_UINT8 (bl0, p_block_list);
+
+        if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)
+        {
+            STREAM_TO_UINT8 (block_number, p_block_list);
+        }
+        else
+        {
+            STREAM_TO_UINT16 (block_number, p_block_list);
+        }
+
+        /* Read the block from memory */
+        service_code = p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
+
+        /* Reject UPDATE command if service code=T3T_MSG_NDEF_SC_RO */
+        if (service_code == T3T_MSG_NDEF_SC_RO)
+        {
+            /* Error: invalid block number to update */
+            CE_TRACE_ERROR0 ("CE: UPDATE request using read-only service");
+            nfc_status = NFC_STATUS_FAILED;
+            break;
+        }
+
+        /* Check for NDEF */
+        if (service_code == T3T_MSG_NDEF_SC_RW)
+        {
+            if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbw)
+            {
+                CE_TRACE_ERROR2 ("CE: Requested too many blocks to update (requested: %i, max: %i)", p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbw);
+                nfc_status = NFC_STATUS_FAILED;
+                break;
+            }
+            else if (p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+            {
+                CE_TRACE_ERROR0 ("CE: error: write-request to read-only NDEF message.");
+                nfc_status = NFC_STATUS_FAILED;
+                break;
+            }
+            else if (block_number == 0)
+            {
+                CE_TRACE_DEBUG2 ("CE: Update sc 0x%04x block %i.", service_code, block_number);
+
+                /* Special caes: NDEF block0 is the ndef attribute block */
+                p_temp = p_block_data;
+                STREAM_TO_UINT8 (ndef_info.version, p_block_data);
+                p_block_data+=8;                                    /* Ignore nbr,nbw,maxb,and reserved (reader/writer not allowed to update this) */
+                STREAM_TO_UINT8 (ndef_info.writef, p_block_data);
+                p_block_data++;                                     /* Ignore rwflag (reader/writer not allowed to update this) */
+                STREAM_TO_UINT8 (newlen_hiword, p_block_data);
+                BE_STREAM_TO_UINT16 (ndef_info.ln, p_block_data);
+                ndef_info.ln += (newlen_hiword<<16);
+                BE_STREAM_TO_UINT16 (checksum_rx, p_block_data);
+
+                checksum=0;
+                for (j=0; j<T3T_MSG_NDEF_ATTR_INFO_SIZE; j++)
+                {
+                    checksum+=p_temp[j];
+                }
+
+                /* Compare calcuated checksum with received checksum */
+                if (checksum != checksum_rx)
+                {
+                    CE_TRACE_ERROR0 ("CE: Checksum failed for NDEF attribute block.");
+                    nfc_status = NFC_STATUS_FAILED;
+                }
+                else
+                {
+                    /* Update NDEF attribute block (only allowed to update current length and writef fields) */
+                    p_cb->ndef_info.scratch_ln      = ndef_info.ln;
+                    p_cb->ndef_info.scratch_writef  = ndef_info.writef;
+
+                    /* If writef=0 indicates completion of NDEF update */
+                    if (ndef_info.writef == 0)
+                    {
+                        update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT;
+                    }
+                    /* writef=1 indicates start of NDEF update */
+                    else
+                    {
+                        update_flags |= CE_T3T_UPDATE_FL_NDEF_UPDATE_START;
+                    }
+                }
+            }
+            else
+            {
+                CE_TRACE_DEBUG2 ("CE: Udpate sc 0x%04x block %i.", service_code, block_number);
+
+                /* Verify that block_number is within NDEF memory */
+                if (block_number > p_cb->ndef_info.nmaxb)
+                {
+                    /* Error: invalid block number to update */
+                    CE_TRACE_ERROR2 ("CE: Requested invalid NDEF block number to update %i (max is %i).", block_number, p_cb->ndef_info.nmaxb);
+                    nfc_status = NFC_STATUS_FAILED;
+                    break;
+                }
+                else
+                {
+                    /* Update NDEF memory block */
+                    STREAM_TO_ARRAY ((&p_cb->ndef_info.p_scratch_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), p_block_data, T3T_MSG_BLOCKSIZE);
+                }
+
+                /* Set flag to indicate that this UPDATE contained at least one block */
+                update_flags |= CE_T3T_UPDATE_FL_UPDATE;
+            }
+        }
+        else
+        {
+            /* Error: invalid service code */
+            CE_TRACE_ERROR1 ("CE: Requested invalid service code: 0x%04x.", service_code);
+            nfc_status = NFC_STATUS_FAILED;
+            break;
+        }
+    }
+
+    /* Send appropriate response to reader/writer */
+    if (nfc_status == NFC_STATUS_OK)
+    {
+        ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, T3T_MSG_RSP_STATUS_OK, T3T_MSG_RSP_STATUS_OK);
+    }
+    else
+    {
+        ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, T3T_MSG_RSP_STATUS_ERROR, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+        p_cb->state = CE_T3T_STATE_IDLE;
+    }
+
+
+    /* Notify the app of what got updated */
+    if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_START)
+    {
+        /* NDEF attribute got updated with WriteF=TRUE */
+        p_ce_cb->p_cback (CE_T3T_NDEF_UPDATE_START_EVT, NULL);
+    }
+
+    if (update_flags & CE_T3T_UPDATE_FL_UPDATE)
+    {
+        /* UPDATE message contained at least one non-NDEF block */
+        p_ce_cb->p_cback (CE_T3T_UPDATE_EVT, NULL);
+    }
+
+
+    if (update_flags & CE_T3T_UPDATE_FL_NDEF_UPDATE_CPLT)
+    {
+        /* NDEF attribute got updated with WriteF=FALSE */
+        update_info.status = nfc_status;
+        update_info.p_data = p_cb->ndef_info.p_scratch_buf;
+        update_info.length = p_cb->ndef_info.scratch_ln;
+        p_cb->state = CE_T3T_STATE_IDLE;
+        p_ce_cb->p_cback (CE_T3T_NDEF_UPDATE_CPLT_EVT, (tCE_DATA *) &update_info);
+    }
+
+    GKI_freebuf (p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_handle_check_cmd
+**
+** Description      Handle CHECK command from reader/writer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void ce_t3t_handle_check_cmd (tCE_CB *p_ce_cb, BT_HDR *p_cmd_msg)
+{
+    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+    BT_HDR *p_rsp_msg;
+    UINT8 *p_rsp_start;
+    UINT8 *p_dst, *p_temp, *p_status;
+    UINT8 *p_src = p_cb->cur_cmd.p_block_list_start;
+    UINT8 i, bl0;
+    UINT8 ndef_writef;
+    UINT32 ndef_len;
+    UINT16 block_number, service_code, checksum;
+
+    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+    {
+        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+        /* Response Code */
+        UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_CHECK_RSP);
+
+        /* Manufacturer ID */
+        ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+        /* Save pointer to start of status field */
+        p_status = p_dst;
+
+        /* Status1 and Status2 (assume success initially */
+        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_OK);
+        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_OK);
+        UINT8_TO_STREAM (p_dst, p_cb->cur_cmd.num_blocks);
+
+        for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
+        {
+            /* Read byte0 of block list */
+            STREAM_TO_UINT8 (bl0, p_src);
+
+            if (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)
+            {
+                STREAM_TO_UINT8 (block_number, p_src);
+            }
+            else
+            {
+                STREAM_TO_UINT16 (block_number, p_src);
+            }
+
+            /* Read the block from memory */
+            service_code = p_cb->cur_cmd.service_code_list[bl0 & T3T_MSG_SERVICE_LIST_MASK];
+
+            /* Check for NDEF */
+            if ((service_code == T3T_MSG_NDEF_SC_RO) || (service_code == T3T_MSG_NDEF_SC_RW))
+            {
+                /* Verify Nbr (NDEF only) */
+                if (p_cb->cur_cmd.num_blocks > p_cb->ndef_info.nbr)
+                {
+                    /* Error: invalid number of blocks to check */
+                    CE_TRACE_ERROR2 ("CE: Requested too many blocks to check (requested: %i, max: %i)", p_cb->cur_cmd.num_blocks, p_cb->ndef_info.nbr);
+
+                    p_dst = p_status;
+                    UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
+                    UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+                    break;
+                }
+                else if (block_number == 0)
+                {
+                    /* Special caes: NDEF block0 is the ndef attribute block */
+                    p_temp = p_dst;
+
+                    /* For rw ndef, use scratch buffer's attributes (in case reader/writer had previously updated NDEF) */
+                    if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) && (p_cb->ndef_info.p_scratch_buf))
+                    {
+                        ndef_writef = p_cb->ndef_info.scratch_writef;
+                        ndef_len    = p_cb->ndef_info.scratch_ln;
+                    }
+                    else
+                    {
+                        ndef_writef = p_cb->ndef_info.writef;
+                        ndef_len    = p_cb->ndef_info.ln;
+                    }
+
+                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.version);
+                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.nbr);
+                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.nbw);
+                    UINT16_TO_BE_STREAM (p_dst, p_cb->ndef_info.nmaxb);
+                    UINT32_TO_STREAM (p_dst, 0);
+                    UINT8_TO_STREAM (p_dst, ndef_writef);
+                    UINT8_TO_STREAM (p_dst, p_cb->ndef_info.rwflag);
+                    UINT8_TO_STREAM (p_dst, (ndef_len >> 16 & 0xFF));
+                    UINT16_TO_BE_STREAM (p_dst, (ndef_len & 0xFFFF));
+
+                    checksum = 0;
+                    for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
+                    {
+                        checksum+=p_temp[i];
+                    }
+                    UINT16_TO_BE_STREAM (p_dst, checksum);
+                }
+                else
+                {
+                    /* Verify that block_number is within NDEF memory */
+                    if (block_number > p_cb->ndef_info.nmaxb)
+                    {
+                        /* Invalid block number */
+                        p_dst = p_status;
+
+                        CE_TRACE_ERROR1 ("CE: Requested block number to check %i.", block_number);
+
+                        /* Error: invalid number of blocks to check */
+                        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
+                        UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+                        break;
+                    }
+                    else
+                    {
+                        /* If card is RW, then read from the scratch buffer (so reader/write can read back what it had just written */
+                        if ((p_cb->ndef_info.rwflag == T3T_MSG_NDEF_RWFLAG_RW) && (p_cb->ndef_info.p_scratch_buf))
+                        {
+                            ARRAY_TO_STREAM (p_dst, (&p_cb->ndef_info.p_scratch_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), T3T_MSG_BLOCKSIZE);
+                        }
+                        else
+                        {
+                            ARRAY_TO_STREAM (p_dst, (&p_cb->ndef_info.p_buf[(block_number-1) * T3T_MSG_BLOCKSIZE]), T3T_MSG_BLOCKSIZE);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                /* Error: invalid service code */
+                CE_TRACE_ERROR1 ("CE: Requested invalid service code: 0x%04x.", service_code);
+
+                p_dst = p_status;
+                UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS_ERROR);
+                UINT8_TO_STREAM (p_dst, T3T_MSG_RSP_STATUS2_ERROR_MEMORY);
+                break;
+            }
+        }
+
+        p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+        ce_t3t_send_to_lower (p_rsp_msg);
+    }
+    else
+    {
+        CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
+    }
+
+    GKI_freebuf (p_cmd_msg);
+}
+
+
+/*******************************************************************************
+**
+** Function         ce_t3t_handle_non_nfc_forum_cmd
+**
+** Description      Handle POLL command from reader/writer
+**
+** Returns          Nothing
+**
+*******************************************************************************/
+void ce_t3t_handle_non_nfc_forum_cmd (tCE_CB *p_mem_cb, UINT8 cmd_id, BT_HDR *p_cmd_msg)
+{
+    tCE_T3T_MEM *p_cb = &p_mem_cb->mem.t3t;
+    BT_HDR *p_rsp_msg;
+    UINT8 *p_rsp_start;
+    UINT8 *p_dst;
+    UINT8 *p = (UINT8 *) (p_cmd_msg +1) + p_cmd_msg->offset;
+    UINT16 sc;
+    UINT8 rc;
+    BOOLEAN send_response = TRUE;
+
+    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+    {
+        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+        switch (cmd_id)
+        {
+        case T3T_MSG_OPC_POLL_CMD:
+            /* Get system code and RC */
+            /* Skip over sod and cmd_id */
+            p+=2;
+            BE_STREAM_TO_UINT16 (sc, p);
+            STREAM_TO_UINT8 (rc, p);
+
+            /* If requesting wildcard system code, or specifically our system code, then send POLL response */
+            if ((sc == 0xFFFF) || (sc == p_cb->system_code))
+            {
+                /* Response Code */
+                UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_POLL_RSP);
+
+                /* Manufacturer ID */
+                ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+                /* Manufacturer Parameter PMm */
+                ARRAY_TO_STREAM (p_dst, p_cb->local_pmm, NCI_T3T_PMM_LEN);
+
+                /* If requesting system code */
+                if (rc == T3T_POLL_RC_SC)
+                {
+                    UINT16_TO_BE_STREAM (p_dst, p_cb->system_code);
+                }
+            }
+            else
+            {
+                send_response = FALSE;
+            }
+            break;
+
+
+        case T3T_MSG_OPC_REQ_RESPONSE_CMD:
+            /* Response Code */
+            UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_REQ_RESPONSE_RSP);
+
+            /* Manufacturer ID */
+            ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+            /* Mode */
+            UINT8_TO_STREAM (p_dst, 0);
+            break;
+
+        case T3T_MSG_OPC_REQ_SYSTEMCODE_CMD:
+            /* Response Code */
+            UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_REQ_SYSTEMCODE_RSP);
+
+            /* Manufacturer ID */
+            ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+            /* Number of system codes */
+            UINT8_TO_STREAM (p_dst, 1);
+
+            /* system codes */
+            UINT16_TO_BE_STREAM (p_dst, T3T_SYSTEM_CODE_NDEF);
+            break;
+
+
+        case T3T_MSG_OPC_REQ_SERVICE_CMD:
+        default:
+            /* Unhandled command */
+            CE_TRACE_ERROR1 ("Unhandled CE opcode: %02x", cmd_id);
+            send_response = FALSE;
+            break;
+        }
+
+        if (send_response)
+        {
+            p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+            ce_t3t_send_to_lower (p_rsp_msg);
+        }
+        else
+        {
+            GKI_freebuf (p_rsp_msg);
+        }
+    }
+    else
+    {
+        CE_TRACE_ERROR0 ("CE: Unable to allocat buffer for response message");
+    }
+    GKI_freebuf (p_cmd_msg);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_data_cback (UINT8 conn_id, BT_HDR *p_msg)
+{
+    tCE_CB *p_ce_cb = &ce_cb;
+    tCE_T3T_MEM *p_cb = &p_ce_cb->mem.t3t;
+    tCE_DATA     ce_data;
+    UINT8 cmd_id, bl0, entry_len, i;
+    UINT8 *p_nfcid2 = NULL;
+    UINT8 *p = (UINT8 *) (p_msg +1) + p_msg->offset;
+    UINT8 cmd_nfcid2[NCI_RF_F_UID_LEN];
+    UINT16 block_list_start_offset, remaining;
+    BOOLEAN msg_processed = FALSE;
+    BOOLEAN block_list_ok;
+    UINT8 sod;
+    UINT8 cmd_type;
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispT3TagMessage (p_msg, TRUE);
+#endif
+
+    /* If activate system code is not NDEF, or if no local NDEF contents was set, then pass data up to the app */
+    if ((p_cb->system_code != T3T_SYSTEM_CODE_NDEF) || (!p_cb->ndef_info.initialized))
+    {
+        ce_data.raw_frame.status = NFC_STATUS_OK;
+        ce_data.raw_frame.p_data = p_msg;
+        p_ce_cb->p_cback (CE_T3T_RAW_FRAME_EVT, &ce_data);
+        return;
+    }
+
+    /* Verify that message contains at least Sod and cmd_id */
+    if (p_msg->len < 2)
+    {
+        CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid length: %i)", p_msg->len);
+    }
+    else
+    {
+
+        /* Get and validate command opcode */
+        STREAM_TO_UINT8 (sod, p);
+        STREAM_TO_UINT8 (cmd_id, p);
+
+        /* Valid command and message length */
+        cmd_type = ce_t3t_is_valid_opcode (cmd_id);
+        if (cmd_type == CE_T3T_COMMAND_INVALID)
+        {
+            CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid command: 0x%02X)", cmd_id);
+        }
+        else if (cmd_type == CE_T3T_COMMAND_FELICA)
+        {
+            ce_t3t_handle_non_nfc_forum_cmd (p_ce_cb, cmd_id, p_msg);
+            msg_processed = TRUE;
+        }
+        else
+        {
+            /* Verify that message contains at least NFCID2 and NUM services */
+            if (p_msg->len < T3T_MSG_CMD_COMMON_HDR_LEN)
+            {
+                CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid length: %i)", p_msg->len);
+            }
+            else
+            {
+                /* Handle NFC_FORUM command (UPDATE or CHECK) */
+                STREAM_TO_ARRAY (cmd_nfcid2, p, NCI_RF_F_UID_LEN);
+                STREAM_TO_UINT8 (p_cb->cur_cmd.num_services, p);
+
+                /* Calculate offset of block-list-start */
+                block_list_start_offset = T3T_MSG_CMD_COMMON_HDR_LEN + 2*p_cb->cur_cmd.num_services + 1;
+
+                if (p_cb->state == CE_T3T_STATE_NOT_ACTIVATED)
+                {
+                    CE_TRACE_ERROR2 ("CE: received command 0x%02X while in bad state (%i))", cmd_id, p_cb->state);
+                }
+                else if (memcmp (cmd_nfcid2, p_cb->local_nfcid2, NCI_RF_F_UID_LEN) != 0)
+                {
+                    CE_TRACE_ERROR0 ("CE: received invalid T3t message (invalid NFCID2)");
+                    p_nfcid2 = cmd_nfcid2;      /* respond with ERROR using the NFCID2 from the command message */
+                }
+                else if (p_msg->len < block_list_start_offset)
+                {
+                    /* Does not have minimum (including number_of_blocks field) */
+                    CE_TRACE_ERROR0 ("CE: incomplete message");
+                }
+                else
+                {
+                    /* Parse service code list */
+                    for (i = 0; i < p_cb->cur_cmd.num_services; i++)
+                    {
+                        STREAM_TO_UINT16 (p_cb->cur_cmd.service_code_list[i], p);
+                    }
+
+                    /* Verify that block list */
+                    block_list_ok = TRUE;
+                    STREAM_TO_UINT8 (p_cb->cur_cmd.num_blocks, p);
+                    remaining = p_msg->len - block_list_start_offset;
+                    p_cb->cur_cmd.p_block_list_start = p;
+                    for (i = 0; i < p_cb->cur_cmd.num_blocks; i++)
+                    {
+                        /* Each entry is at lease 2 bytes long */
+                        if (remaining < 2)
+                        {
+                            /* Unexpected end of message (while reading block-list) */
+                            CE_TRACE_ERROR0 ("CE: received invalid T3t message (unexpected end of block-list)");
+                            block_list_ok = FALSE;
+                            break;
+                        }
+
+                        /* Get byte0 of block-list entry */
+                        bl0 = *p;
+
+                        /* Validate service code index and size of block-list */
+                        if ((bl0 & T3T_MSG_SERVICE_LIST_MASK) >= p_cb->cur_cmd.num_services)
+                        {
+                            /* Invalid service code */
+                            CE_TRACE_ERROR1 ("CE: received invalid T3t message (invalid service index: %i)", (bl0 & T3T_MSG_SERVICE_LIST_MASK));
+                            block_list_ok = FALSE;
+                            break;
+                        }
+                        else if ((!(bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT)) && (remaining < 3))
+                        {
+                            /* Unexpected end of message (while reading 3-byte entry) */
+                            CE_TRACE_ERROR0 ("CE: received invalid T3t message (unexpected end of block-list)");
+                            block_list_ok = FALSE;
+                            break;
+                        }
+
+                        /* Advance pointers to next block-list entry */
+                        entry_len = (bl0 & T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT) ? 2 : 3;
+                        p+=entry_len;
+                        remaining-=entry_len;
+                    }
+
+                    /* Block list is verified. Call CHECK or UPDATE handler */
+                    if (block_list_ok)
+                    {
+                        p_cb->cur_cmd.p_block_data_start = p;
+                        if (cmd_id == T3T_MSG_OPC_CHECK_CMD)
+                        {
+                            /* This is a CHECK command. Sanity check: there shouldn't be any more data remaining after reading block list */
+                            if (remaining)
+                            {
+                                CE_TRACE_ERROR1 ("CE: unexpected data after after CHECK command (#i bytes)", remaining);
+                            }
+                            ce_t3t_handle_check_cmd (p_ce_cb, p_msg);
+                            msg_processed = TRUE;
+                        }
+                        else
+                        {
+                            /* This is an UPDATE command. See if message contains all the expected block data */
+                            if (remaining < p_cb->cur_cmd.num_blocks*T3T_MSG_BLOCKSIZE)
+                            {
+                                CE_TRACE_ERROR0 ("CE: unexpected end of block-data");
+                            }
+                            else
+                            {
+                                ce_t3t_handle_update_cmd (p_ce_cb, p_msg);
+                                msg_processed = TRUE;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if (!msg_processed)
+    {
+        ce_t3t_send_rsp (p_ce_cb, p_nfcid2, T3T_MSG_OPC_CHECK_RSP, T3T_MSG_RSP_STATUS_ERROR, T3T_MSG_RSP_STATUS2_ERROR_PROCESSING);
+        GKI_freebuf (p_msg);
+    }
+
+
+}
+
+/*******************************************************************************
+**
+** Function         ce_t3t_conn_cback
+**
+** Description      This callback function receives the events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t3t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+    CE_TRACE_DEBUG2 ("ce_t3t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
+
+    switch (event)
+    {
+    case NFC_CONN_CREATE_CEVT:
+        break;
+
+    case NFC_CONN_CLOSE_CEVT:
+        p_cb->state = CE_T3T_STATE_NOT_ACTIVATED;
+        break;
+
+    case NFC_DATA_CEVT:
+        if (p_data->data.status == NFC_STATUS_OK)
+        {
+            ce_t3t_data_cback (conn_id, p_data->data.p_data);
+        }
+        break;
+
+    case NFC_DEACTIVATE_CEVT:
+        p_cb->state = CE_T3T_STATE_NOT_ACTIVATED;
+        NFC_SetStaticRfCback (NULL);
+        break;
+
+    default:
+        break;
+
+    }
+}
+
+/*******************************************************************************
+**
+** Function         ce_select_t3t
+**
+** Description      Select Type 3 Tag
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS ce_select_t3t (UINT16 system_code, UINT8 nfcid2[NCI_RF_F_UID_LEN])
+{
+    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+    CE_TRACE_DEBUG0 ("ce_select_t3t ()");
+
+    p_cb->state = CE_T3T_STATE_IDLE;
+    p_cb->system_code = system_code;
+    memcpy (p_cb->local_nfcid2, nfcid2, NCI_RF_F_UID_LEN);
+
+    NFC_SetStaticRfCback (ce_t3t_conn_cback);
+    return NFC_STATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 3 Tag with mandatory NDEF message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSetLocalNDEFMsg (BOOLEAN read_only,
+                                   UINT32  size_max,
+                                   UINT32  size_current,
+                                   UINT8   *p_buf,
+                                   UINT8   *p_scratch_buf)
+{
+    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+    CE_TRACE_API3 ("CE_T3tSetContent: ro=%i, size_max=%i, size_current=%i", read_only, size_max, size_current);
+
+    /* Verify scratch buffer was provided if NDEF message is read/write */
+    if ((!read_only) && (!p_scratch_buf))
+    {
+        CE_TRACE_ERROR0 ("CE_T3tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not read-only");
+        return NFC_STATUS_FAILED;
+    }
+
+    /* Check if disabling the local NDEF */
+    if (!p_buf)
+    {
+        p_cb->ndef_info.initialized = FALSE;
+    }
+    /* Save ndef attributes */
+    else
+    {
+        p_cb->ndef_info.initialized = TRUE;
+        p_cb->ndef_info.ln = size_current;                          /* Current length */
+        p_cb->ndef_info.nmaxb = (UINT16) ((size_max + 15) / T3T_MSG_BLOCKSIZE);  /* Max length (in blocks) */
+        p_cb->ndef_info.rwflag = (read_only) ? T3T_MSG_NDEF_RWFLAG_RO : T3T_MSG_NDEF_RWFLAG_RW;
+        p_cb->ndef_info.writef = T3T_MSG_NDEF_WRITEF_OFF;
+        p_cb->ndef_info.version = 0x10;
+        p_cb->ndef_info.p_buf = p_buf;
+        p_cb->ndef_info.p_scratch_buf = p_scratch_buf;
+
+        /* Initiate scratch buffer with same contents as read-buffer */
+        if (p_scratch_buf)
+        {
+            p_cb->ndef_info.scratch_ln      = p_cb->ndef_info.ln;
+            p_cb->ndef_info.scratch_writef  = T3T_MSG_NDEF_WRITEF_OFF;
+            memcpy (p_scratch_buf, p_buf, p_cb->ndef_info.ln);
+        }
+    }
+
+    return (NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSetLocalNDefParams
+**
+** Description      Sets T3T-specific NDEF parameters. (Optional - if not
+**                  called, then CE will use default parameters)
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSetLocalNDefParams (UINT8 nbr, UINT8 nbw)
+{
+    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+
+    CE_TRACE_API2 ("CE_T3tSetLocalNDefParams: nbr=%i, nbw=%i", nbr, nbw);
+
+    /* Validate */
+    if ((nbr > T3T_MSG_NUM_BLOCKS_CHECK_MAX) || (nbw>T3T_MSG_NUM_BLOCKS_UPDATE_MAX) || (nbr < 1) || (nbw < 1))
+    {
+        CE_TRACE_ERROR0 ("CE_T3tSetLocalNDefParams: invalid params");
+        return NFC_STATUS_FAILED;
+    }
+
+    p_cb->ndef_info.nbr = nbr;
+    p_cb->ndef_info.nbw = nbw;
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendCheckRsp
+**
+** Description      Send CHECK response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSendCheckRsp (UINT8 status1, UINT8 status2, UINT8 num_blocks, UINT8 *p_block_data)
+{
+    tCE_T3T_MEM *p_cb = &ce_cb.mem.t3t;
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    BT_HDR *p_rsp_msg;
+    UINT8 *p_dst, *p_rsp_start;
+
+    CE_TRACE_API3 ("CE_T3tCheckRsp: status1=0x%02X, status2=0x%02X, num_blocks=%i", status1, status2, num_blocks);
+
+    /* Validate num_blocks */
+    if (num_blocks > T3T_MSG_NUM_BLOCKS_CHECK_MAX)
+    {
+        CE_TRACE_ERROR2 ("CE_T3tCheckRsp num_blocks (%i) exceeds maximum (%i)", num_blocks, T3T_MSG_NUM_BLOCKS_CHECK_MAX);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if ((p_rsp_msg = ce_t3t_get_rsp_buf ()) != NULL)
+    {
+        p_dst = p_rsp_start = (UINT8 *) (p_rsp_msg+1) + p_rsp_msg->offset;
+
+        /* Response Code */
+        UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_CHECK_RSP);
+
+        /* Manufacturer ID */
+        ARRAY_TO_STREAM (p_dst, p_cb->local_nfcid2, NCI_RF_F_UID_LEN);
+
+        /* Status1 and Status2 */
+        UINT8_TO_STREAM (p_dst, status1);
+        UINT8_TO_STREAM (p_dst, status2);
+
+        if (status1 == T3T_MSG_RSP_STATUS_OK)
+        {
+            UINT8_TO_STREAM (p_dst, num_blocks);
+            ARRAY_TO_STREAM (p_dst, p_block_data, (num_blocks * T3T_MSG_BLOCKSIZE));
+        }
+
+        p_rsp_msg->len = (UINT16) (p_dst - p_rsp_start);
+        ce_t3t_send_to_lower (p_rsp_msg);
+    }
+    else
+    {
+        CE_TRACE_ERROR0 ("CE: Unable to allocate buffer for response message");
+    }
+
+    return (retval);
+}
+
+/*******************************************************************************
+**
+** Function         CE_T3tSendUpdateRsp
+**
+** Description      Send UPDATE response message
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T3tSendUpdateRsp (UINT8 status1, UINT8 status2)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tCE_CB *p_ce_cb = &ce_cb;
+
+    CE_TRACE_API2 ("CE_T3tUpdateRsp: status1=0x%02X, status2=0x%02X", status1, status2);
+    ce_t3t_send_rsp (p_ce_cb, NULL, T3T_MSG_OPC_UPDATE_RSP, status1, status2);
+
+    return (retval);
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/ce_t4t.c b/src/nfc/tags/ce_t4t.c
new file mode 100644
index 0000000..80833dd
--- /dev/null
+++ b/src/nfc/tags/ce_t4t.c
@@ -0,0 +1,1202 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 4 tag in Card Emulation
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "ce_api.h"
+#include "ce_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+#if (CE_TEST_INCLUDED == TRUE) /* test only */
+BOOLEAN mapping_aid_test_enabled = FALSE;
+UINT8   ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+#endif
+
+/*******************************************************************************
+**
+** Function         ce_t4t_send_to_lower
+**
+** Description      Send packet to lower layer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_send_to_lower (BT_HDR *p_r_apdu)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispCET4Tags (p_r_apdu, FALSE);
+#endif
+
+    if (NFC_SendData (NFC_RF_CONN_ID, p_r_apdu) != NFC_STATUS_OK)
+    {
+        CE_TRACE_ERROR0 ("ce_t4t_send_to_lower (): NFC_SendData () failed");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_send_status
+**
+** Description      Send status on R-APDU to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_send_status (UINT16 status)
+{
+    BT_HDR      *p_r_apdu;
+    UINT8       *p;
+
+    CE_TRACE_DEBUG1 ("ce_t4t_send_status (): Status:0x%04X", status);
+
+    p_r_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID);
+
+    if (!p_r_apdu)
+    {
+        CE_TRACE_ERROR0 ("ce_t4t_send_status (): Cannot allocate buffer");
+        return FALSE;
+    }
+
+    p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+
+    UINT16_TO_BE_STREAM (p, status);
+
+    p_r_apdu->len = T4T_RSP_STATUS_WORDS_SIZE;
+
+    if (!ce_t4t_send_to_lower (p_r_apdu))
+    {
+        return FALSE;
+    }
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_select_file
+**
+** Description      Select a file
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_select_file (UINT16 file_id)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+
+    CE_TRACE_DEBUG1 ("ce_t4t_select_file (): FileID:0x%04X", file_id);
+
+    if (file_id == T4T_CC_FILE_ID)
+    {
+        CE_TRACE_DEBUG0 ("ce_t4t_select_file (): Select CC file");
+
+        p_t4t->status |= CE_T4T_STATUS_CC_FILE_SELECTED;
+        p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+
+        return TRUE;
+    }
+
+    if (file_id == CE_T4T_MANDATORY_NDEF_FILE_ID)
+    {
+        CE_TRACE_DEBUG3 ("ce_t4t_select_file (): NLEN:0x%04X, MaxFileSize:0x%04X, WriteAccess:%s",
+                          p_t4t->nlen,
+                          p_t4t->max_file_size,
+                          (p_t4t->status & CE_T4T_STATUS_NDEF_FILE_READ_ONLY ? "RW" : "RO"));
+
+        p_t4t->status |= CE_T4T_STATUS_NDEF_SELECTED;
+        p_t4t->status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+
+        return TRUE;
+    }
+    else
+    {
+        CE_TRACE_ERROR1 ("ce_t4t_select_file (): Cannot find file ID (0x%04X)", file_id);
+
+        p_t4t->status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+        p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_read_binary
+**
+** Description      Read data from selected file and send R-APDU to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_read_binary (UINT16 offset, UINT8 length)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       *p_src = NULL, *p_dst;
+    BT_HDR      *p_r_apdu;
+
+    CE_TRACE_DEBUG3 ("ce_t4t_read_binary (): Offset:0x%04X, Length:0x%04X, selected status = 0x%02X",
+                      offset, length, p_t4t->status);
+
+    if (p_t4t->status & CE_T4T_STATUS_CC_FILE_SELECTED)
+    {
+        p_src = p_t4t->cc_file;
+    }
+    else if (p_t4t->status & CE_T4T_STATUS_NDEF_SELECTED)
+    {
+        if (p_t4t->p_scratch_buf)
+            p_src = p_t4t->p_scratch_buf;
+        else
+            p_src = p_t4t->p_ndef_msg;
+    }
+
+    if (p_src)
+    {
+        p_r_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID);
+
+        if (!p_r_apdu)
+        {
+            CE_TRACE_ERROR0 ("ce_t4t_read_binary (): Cannot allocate buffer");
+            return FALSE;
+        }
+
+        p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+        p_dst = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+
+        p_r_apdu->len = length;
+
+        /* add NLEN before NDEF message and adjust offset             */
+        /* if NDEF file is selected and offset < T4T_FILE_LENGTH_SIZE */
+        if ((p_t4t->status & CE_T4T_STATUS_NDEF_SELECTED) && (length > 0))
+        {
+            if (offset == 0)
+            {
+                UINT16_TO_BE_STREAM (p_dst, p_t4t->nlen);
+
+                if (length == 1)
+                {
+                    length = 0;
+                    p_dst--;
+                }
+                else /* length >= 2 */
+                    length -= T4T_FILE_LENGTH_SIZE;
+            }
+            else if (offset == 1)
+            {
+                UINT8_TO_BE_STREAM (p_dst, (UINT8) (p_t4t->nlen));
+
+                offset = 0;
+                length--;
+            }
+            else
+            {
+                offset -= T4T_FILE_LENGTH_SIZE;
+            }
+        }
+
+        if (length > 0)
+        {
+            memcpy (p_dst, p_src + offset, length);
+            p_dst += length;
+        }
+
+        UINT16_TO_BE_STREAM (p_dst, T4T_RSP_CMD_CMPLTED);
+        p_r_apdu->len += T4T_RSP_STATUS_WORDS_SIZE;
+
+        if (!ce_t4t_send_to_lower (p_r_apdu))
+        {
+            return FALSE;
+        }
+        return TRUE;
+    }
+    else
+    {
+        CE_TRACE_ERROR0 ("ce_t4t_read_binary (): No selected file");
+
+        if (!ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED))
+        {
+            return FALSE;
+        }
+        return TRUE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_update_binary
+**
+** Description      Update file and send R-APDU to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_update_binary (UINT16 offset, UINT8 length, UINT8 *p_data)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       *p;
+    UINT8        file_length[2];
+    UINT16       starting_offset, status_words;
+    tCE_DATA     ce_data;
+
+    CE_TRACE_DEBUG3 ("ce_t4t_update_binary (): Offset:0x%04X, Length:0x%04X, selected status = 0x%02X",
+                      offset, length, p_t4t->status);
+
+    starting_offset = offset;
+
+    /* update file size (NLEN) */
+    if ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0))
+    {
+        p = file_length;
+        UINT16_TO_BE_STREAM (p, p_t4t->nlen);
+
+        while ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0))
+        {
+            *(file_length + offset++) = *(p_data++);
+            length--;
+        }
+
+        p = file_length;
+        BE_STREAM_TO_UINT16 (p_t4t->nlen, p);
+    }
+
+    if (length > 0)
+        memcpy (p_t4t->p_scratch_buf + offset - T4T_FILE_LENGTH_SIZE, p_data, length);
+
+    status_words = T4T_RSP_CMD_CMPLTED;
+
+    /* if this is the last step: writing non-zero length in NLEN */
+    if ((starting_offset == 0) && (p_t4t->nlen > 0))
+    {
+        nfc_stop_quick_timer (&p_t4t->timer);
+
+        if (ce_cb.p_cback)
+        {
+            ce_data.update_info.status = NFC_STATUS_OK;
+            ce_data.update_info.length = p_t4t->nlen;
+            ce_data.update_info.p_data = p_t4t->p_scratch_buf;
+
+            (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_CPLT_EVT, &ce_data);
+            CE_TRACE_DEBUG0 ("ce_t4t_update_binary (): Sent CE_T4T_NDEF_UPDATE_CPLT_EVT");
+        }
+
+        p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_UPDATING);
+    }
+    else if (!(p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING))
+    {
+        /* starting of updating */
+        p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_UPDATING;
+
+        nfc_start_quick_timer (&p_t4t->timer, NFC_TTYPE_CE_T4T_UPDATE,
+                               (CE_T4T_TOUT_UPDATE * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+        if (ce_cb.p_cback)
+            (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_START_EVT, NULL);
+    }
+
+    if (!ce_t4t_send_status (status_words))
+    {
+        return FALSE;
+    }
+
+    if (status_words == T4T_RSP_CMD_CMPLTED)
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_set_version_in_cc
+**
+** Description      update version in CC file
+**                  If reader selects NDEF Tag Application with V1.0 AID then
+**                  set V1.0 into CC file.
+**                  If reader selects NDEF Tag Application with V2.0 AID then
+**                  set V2.0 into CC file.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void ce_t4t_set_version_in_cc (UINT8 version)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       *p;
+
+    CE_TRACE_DEBUG1 ("ce_t4t_set_version_in_cc (): version = 0x%02X", version);
+
+    p = p_t4t->cc_file + T4T_VERSION_OFFSET_IN_CC;
+
+    UINT8_TO_BE_STREAM (p, version);
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_process_select_file_cmd
+**
+** Description      This function processes Select Command by file ID.
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN ce_t4t_process_select_file_cmd (UINT8 *p_cmd)
+{
+    UINT8  data_len;
+    UINT16 file_id, status_words;
+
+    CE_TRACE_DEBUG0 ("ce_t4t_process_select_file_cmd ()");
+
+    p_cmd++; /* skip P2 */
+
+    /* Lc Byte */
+    BE_STREAM_TO_UINT8 (data_len, p_cmd);
+
+    if (data_len == T4T_FILE_ID_SIZE)
+    {
+        /* File ID */
+        BE_STREAM_TO_UINT16 (file_id, p_cmd);
+
+        if (ce_t4t_select_file (file_id))
+        {
+            status_words = T4T_RSP_CMD_CMPLTED;
+        }
+        else
+        {
+            status_words = T4T_RSP_NOT_FOUND;
+        }
+    }
+    else
+    {
+        status_words = T4T_RSP_WRONG_LENGTH;
+    }
+
+    if (!ce_t4t_send_status (status_words))
+    {
+        return FALSE;
+    }
+
+    if (status_words == T4T_RSP_CMD_CMPLTED)
+    {
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_process_select_app_cmd
+**
+** Description      This function processes Select Command by AID.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void ce_t4t_process_select_app_cmd (UINT8 *p_cmd, BT_HDR *p_c_apdu)
+{
+    UINT8    data_len;
+    UINT16   status_words = 0x0000; /* invalid status words */
+    tCE_DATA ce_data;
+    UINT8    xx;
+
+    CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd ()");
+
+    p_cmd++; /* skip P2 */
+
+    /* Lc Byte */
+    BE_STREAM_TO_UINT8 (data_len, p_cmd);
+
+#if (CE_TEST_INCLUDED == TRUE)
+    if (mapping_aid_test_enabled)
+    {
+        if (  (data_len == T4T_V20_NDEF_TAG_AID_LEN)
+            &&(!memcmp(p_cmd, ce_test_tag_app_id, data_len))
+            &&(ce_cb.mem.t4t.p_ndef_msg)  )
+        {
+            GKI_freebuf (p_c_apdu);
+            ce_t4t_send_status ((UINT16) T4T_RSP_CMD_CMPLTED);
+            return;
+        }
+    }
+#endif
+
+    /*
+    ** Compare AIDs registered by applications
+    ** if found, use callback of the application
+    ** otherwise, return error and maintain the same status
+    */
+    ce_cb.mem.t4t.selected_aid_idx = CE_T4T_MAX_REG_AID;
+    for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++)
+    {
+        if (  (ce_cb.mem.t4t.reg_aid[xx].aid_len > 0)
+            &&(ce_cb.mem.t4t.reg_aid[xx].aid_len == data_len)
+            &&(!(memcmp(ce_cb.mem.t4t.reg_aid[xx].aid, p_cmd, data_len)))  )
+        {
+            ce_cb.mem.t4t.selected_aid_idx = xx;
+            break;
+        }
+    }
+
+    /* if found matched AID */
+    if (ce_cb.mem.t4t.selected_aid_idx < CE_T4T_MAX_REG_AID)
+    {
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_T4T_APP_SELECTED);
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_WILDCARD_AID_SELECTED);
+        ce_cb.mem.t4t.status |= CE_T4T_STATUS_REG_AID_SELECTED;
+
+        CE_TRACE_DEBUG4 ("ce_t4t_process_select_app_cmd (): Registered AID[%02X%02X%02X%02X...] is selected",
+                         ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[0],
+                         ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[1],
+                         ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[2],
+                         ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].aid[3]);
+
+        ce_data.raw_frame.status = NFC_STATUS_OK;
+        ce_data.raw_frame.p_data = p_c_apdu;
+        ce_data.raw_frame.aid_handle = ce_cb.mem.t4t.selected_aid_idx;
+
+        p_c_apdu = NULL;
+
+        (*(ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].p_cback)) (CE_T4T_RAW_FRAME_EVT, &ce_data);
+    }
+    else if (  (data_len == T4T_V20_NDEF_TAG_AID_LEN)
+             &&(!memcmp(p_cmd, t4t_v20_ndef_tag_aid, data_len - 1))
+             &&(ce_cb.mem.t4t.p_ndef_msg)  )
+    {
+        p_cmd += data_len - 1;
+
+        /* adjust version if possible */
+        if ((*p_cmd) == 0x00)
+        {
+            ce_t4t_set_version_in_cc (T4T_VERSION_1_0);
+            status_words = T4T_RSP_CMD_CMPLTED;
+        }
+        else if ((*p_cmd) == 0x01)
+        {
+            ce_t4t_set_version_in_cc (T4T_VERSION_2_0);
+            status_words = T4T_RSP_CMD_CMPLTED;
+        }
+        else
+        {
+            CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd (): Not found matched AID");
+            status_words = T4T_RSP_NOT_FOUND;
+        }
+    }
+    else if (ce_cb.mem.t4t.p_wildcard_aid_cback)
+    {
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_T4T_APP_SELECTED);
+        ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_REG_AID_SELECTED);
+        ce_cb.mem.t4t.status |= CE_T4T_STATUS_WILDCARD_AID_SELECTED;
+
+        ce_data.raw_frame.status = NFC_STATUS_OK;
+        ce_data.raw_frame.p_data = p_c_apdu;
+        ce_data.raw_frame.aid_handle = CE_T4T_WILDCARD_AID_HANDLE;
+        p_c_apdu = NULL;
+
+        CE_TRACE_DEBUG0 ("CET4T: Forward raw frame (SELECT APP) to wildcard AID handler");
+        (*(ce_cb.mem.t4t.p_wildcard_aid_cback)) (CE_T4T_RAW_FRAME_EVT, &ce_data);
+    }
+    else
+    {
+        CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd (): Not found matched AID or not listening T4T NDEF");
+        status_words = T4T_RSP_NOT_FOUND;
+    }
+
+    if (status_words)
+    {
+        /* if T4T CE can support */
+        if (status_words == T4T_RSP_CMD_CMPLTED)
+        {
+            ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_CC_FILE_SELECTED);
+            ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_NDEF_SELECTED);
+            ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_REG_AID_SELECTED);
+            ce_cb.mem.t4t.status &= ~ (CE_T4T_STATUS_WILDCARD_AID_SELECTED);
+            ce_cb.mem.t4t.status |= CE_T4T_STATUS_T4T_APP_SELECTED;
+
+            CE_TRACE_DEBUG0 ("ce_t4t_process_select_app_cmd (): T4T CE App selected");
+        }
+
+        ce_t4t_send_status (status_words);
+        GKI_freebuf (p_c_apdu);
+    }
+    /* if status_words is not set then upper layer will send R-APDU */
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void ce_t4t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    tCE_DATA     ce_data;
+
+    CE_TRACE_DEBUG1 ("ce_t4t_process_timeout () event=%d", p_tle->event);
+
+    if (p_tle->event == NFC_TTYPE_CE_T4T_UPDATE)
+    {
+        if (p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING)
+        {
+            ce_data.status = NFC_STATUS_TIMEOUT;
+
+            if (ce_cb.p_cback)
+                (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_ABORT_EVT, &ce_data);
+
+            p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_UPDATING);
+        }
+    }
+    else
+    {
+        CE_TRACE_ERROR1 ("ce_t4t_process_timeout () unknown event=%d", p_tle->event);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         ce_t4t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void ce_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    BT_HDR  *p_c_apdu = (BT_HDR *) p_data->data.p_data;
+    UINT8   *p_cmd;
+    UINT8    cla, instruct, select_type = 0, length;
+    UINT16   offset, max_file_size;
+    tCE_DATA ce_data;
+
+    if (event == NFC_DEACTIVATE_CEVT)
+    {
+        NFC_SetStaticRfCback (NULL);
+        return;
+    }
+    if (event != NFC_DATA_CEVT)
+    {
+        return;
+    }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispCET4Tags (p_c_apdu, TRUE);
+#endif
+
+    CE_TRACE_DEBUG1 ("ce_t4t_data_cback (): conn_id = 0x%02X", conn_id);
+
+    p_cmd = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+    /* Class Byte */
+    BE_STREAM_TO_UINT8 (cla, p_cmd);
+
+    /* Don't check class if registered AID has been selected */
+    if (  (cla != T4T_CMD_CLASS)
+        &&((ce_cb.mem.t4t.status & CE_T4T_STATUS_REG_AID_SELECTED) == 0)  )
+    {
+        CE_TRACE_ERROR1 ("CET4T: Unsupported Class byte (0x%02X)", cla);
+        GKI_freebuf (p_c_apdu);
+        ce_t4t_send_status (T4T_RSP_CLASS_NOT_SUPPORTED);
+        return;
+    }
+
+    /* Instruction Byte */
+    BE_STREAM_TO_UINT8 (instruct, p_cmd);
+
+    if ((cla == T4T_CMD_CLASS) && (instruct == T4T_CMD_INS_SELECT))
+    {
+        /* P1 Byte */
+        BE_STREAM_TO_UINT8 (select_type, p_cmd);
+
+        if (select_type == T4T_CMD_P1_SELECT_BY_NAME)
+        {
+            ce_t4t_process_select_app_cmd (p_cmd, p_c_apdu);
+            return;
+        }
+    }
+
+    /* if registered AID is selected */
+    if (ce_cb.mem.t4t.status & CE_T4T_STATUS_REG_AID_SELECTED)
+    {
+        CE_TRACE_DEBUG0 ("CET4T: Forward raw frame to registered AID");
+
+        /* forward raw frame to upper layer */
+        if (ce_cb.mem.t4t.selected_aid_idx < NFC_MAX_AID_LEN)
+        {
+            ce_data.raw_frame.status = NFC_STATUS_OK;
+            ce_data.raw_frame.p_data = p_c_apdu;
+            ce_data.raw_frame.aid_handle = ce_cb.mem.t4t.selected_aid_idx;
+            p_c_apdu = NULL;
+
+            (*(ce_cb.mem.t4t.reg_aid[ce_cb.mem.t4t.selected_aid_idx].p_cback)) (CE_T4T_RAW_FRAME_EVT, &ce_data);
+        }
+        else
+        {
+            GKI_freebuf (p_c_apdu);
+            ce_t4t_send_status (T4T_RSP_NOT_FOUND);
+        }
+    }
+    else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_WILDCARD_AID_SELECTED)
+    {
+        CE_TRACE_DEBUG0 ("CET4T: Forward raw frame to wildcard AID handler");
+
+        /* forward raw frame to upper layer */
+        ce_data.raw_frame.status = NFC_STATUS_OK;
+        ce_data.raw_frame.p_data = p_c_apdu;
+        ce_data.raw_frame.aid_handle = CE_T4T_WILDCARD_AID_HANDLE;
+        p_c_apdu = NULL;
+
+        (*(ce_cb.mem.t4t.p_wildcard_aid_cback)) (CE_T4T_RAW_FRAME_EVT, &ce_data);
+    }
+    else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_T4T_APP_SELECTED)
+    {
+        if (instruct == T4T_CMD_INS_SELECT)
+        {
+            /* P1 Byte is already parsed */
+            if (select_type == T4T_CMD_P1_SELECT_BY_FILE_ID)
+            {
+                ce_t4t_process_select_file_cmd (p_cmd);
+            }
+            else
+            {
+                CE_TRACE_ERROR1 ("CET4T: Bad P1 byte (0x%02X)", select_type);
+                ce_t4t_send_status (T4T_RSP_WRONG_PARAMS);
+            }
+        }
+        else if (instruct == T4T_CMD_INS_READ_BINARY)
+        {
+            if (  (ce_cb.mem.t4t.status & CE_T4T_STATUS_CC_FILE_SELECTED)
+                ||(ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_SELECTED)  )
+            {
+                if (ce_cb.mem.t4t.status & CE_T4T_STATUS_CC_FILE_SELECTED)
+                {
+                    max_file_size = T4T_FC_TLV_OFFSET_IN_CC + T4T_FILE_CONTROL_TLV_SIZE;
+                }
+                else
+                {
+                    max_file_size = ce_cb.mem.t4t.max_file_size;
+                }
+
+                BE_STREAM_TO_UINT16 (offset, p_cmd); /* Offset */
+                BE_STREAM_TO_UINT8 (length, p_cmd); /* Le     */
+
+                /* check if valid parameters */
+                if (length <= CE_T4T_MAX_LE)
+                {
+                    /* CE allows to read more than current file size but not max file size */
+                    if (length + offset > max_file_size)
+                    {
+                        if (offset < max_file_size)
+                        {
+                            length = (UINT8) (max_file_size - offset);
+
+                            CE_TRACE_DEBUG2 ("CET4T: length is reduced to %d by max_file_size (%d)",
+                                              length, max_file_size);
+                        }
+                        else
+                        {
+                            CE_TRACE_ERROR2 ("CET4T: offset (%d) must be less than max_file_size (%d)",
+                                              offset, max_file_size);
+                            length = 0;
+                        }
+                    }
+                }
+                else
+                {
+                    CE_TRACE_ERROR2 ("CET4T: length (%d) must be less than MLe (%d)",
+                                      length, CE_T4T_MAX_LE);
+                    length = 0;
+                }
+
+                if (length > 0)
+                    ce_t4t_read_binary (offset, length);
+                else
+                    ce_t4t_send_status (T4T_RSP_WRONG_PARAMS);
+            }
+            else
+            {
+                CE_TRACE_ERROR0 ("CET4T: File has not been selected");
+                ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+            }
+        }
+        else if (instruct == T4T_CMD_INS_UPDATE_BINARY)
+        {
+            if (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_FILE_READ_ONLY)
+            {
+                CE_TRACE_ERROR0 ("CET4T: No access right");
+                ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+            }
+            else if (ce_cb.mem.t4t.status & CE_T4T_STATUS_NDEF_SELECTED)
+            {
+                BE_STREAM_TO_UINT16 (offset, p_cmd); /* Offset */
+                BE_STREAM_TO_UINT8 (length, p_cmd); /* Lc     */
+
+                /* check if valid parameters */
+                if (length <= CE_T4T_MAX_LC)
+                {
+                    if (length + offset > ce_cb.mem.t4t.max_file_size)
+                    {
+                        CE_TRACE_ERROR3 ("CET4T: length (%d) + offset (%d) must be less than max_file_size (%d)",
+                                          length, offset, ce_cb.mem.t4t.max_file_size);
+                        length = 0;
+                    }
+                }
+                else
+                {
+                    CE_TRACE_ERROR2 ("CET4T: length (%d) must be less than MLc (%d)",
+                                      length, CE_T4T_MAX_LC);
+                    length = 0;
+                }
+
+                if (length > 0)
+                    ce_t4t_update_binary (offset, length, p_cmd);
+                else
+                    ce_t4t_send_status (T4T_RSP_WRONG_PARAMS);
+            }
+            else
+            {
+                CE_TRACE_ERROR0 ("CET4T: NDEF File has not been selected");
+                ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+            }
+        }
+        else
+        {
+            CE_TRACE_ERROR1 ("CET4T: Unsupported Instruction byte (0x%02X)", instruct);
+            ce_t4t_send_status (T4T_RSP_INSTR_NOT_SUPPORTED);
+        }
+    }
+    else
+    {
+        CE_TRACE_ERROR0 ("CET4T: Application has not been selected");
+        ce_t4t_send_status (T4T_RSP_CMD_NOT_ALLOWED);
+    }
+
+    if (p_c_apdu)
+        GKI_freebuf (p_c_apdu);
+}
+
+/*******************************************************************************
+**
+** Function         ce_select_t4t
+**
+** Description      Select Type 4 Tag
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS ce_select_t4t (void)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+
+    CE_TRACE_DEBUG0 ("ce_select_t4t ()");
+
+    nfc_stop_quick_timer (&p_t4t->timer);
+
+    /* clear other than read-only flag */
+    p_t4t->status &= CE_T4T_STATUS_NDEF_FILE_READ_ONLY;
+
+    NFC_SetStaticRfCback (ce_t4t_data_cback);
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4tSetLocalNDEFMsg
+**
+** Description      Initialise CE Type 4 Tag with mandatory NDEF message
+**
+**                  The following event may be returned
+**                      CE_T4T_UPDATE_START_EVT for starting update
+**                      CE_T4T_UPDATE_CPLT_EVT for complete update
+**                      CE_T4T_UPDATE_ABORT_EVT for failure of update
+**                      CE_T4T_RAW_FRAME_EVT for raw frame
+**
+**                  read_only:      TRUE if read only
+**                  ndef_msg_max:   Max NDEF message size
+**                  ndef_msg_len:   NDEF message size
+**                  p_ndef_msg:     NDEF message (excluding NLEN)
+**                  p_scratch_buf:  temp storage for update
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4tSetLocalNDEFMsg (BOOLEAN    read_only,
+                                   UINT16     ndef_msg_max,
+                                   UINT16     ndef_msg_len,
+                                   UINT8      *p_ndef_msg,
+                                   UINT8      *p_scratch_buf)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       *p;
+
+    CE_TRACE_API3 ("CE_T4tSetLocalNDEFMsg () read_only=%d, ndef_msg_max=%d, ndef_msg_len=%d",
+                   read_only, ndef_msg_max, ndef_msg_len);
+
+    if (!p_ndef_msg)
+    {
+        p_t4t->p_ndef_msg = NULL;
+
+        CE_TRACE_DEBUG0 ("CE_T4tSetLocalNDEFMsg (): T4T is disabled");
+        return NFC_STATUS_OK;
+    }
+
+    if ((!read_only) && (!p_scratch_buf))
+    {
+        CE_TRACE_ERROR0 ("CE_T4tSetLocalNDEFMsg (): p_scratch_buf cannot be NULL if not read-only");
+        return NFC_STATUS_FAILED;
+    }
+
+#if (CE_TEST_INCLUDED == TRUE)
+    mapping_aid_test_enabled = FALSE;
+#endif
+
+    /* Initialise CC file */
+    p = p_t4t->cc_file;
+
+    UINT16_TO_BE_STREAM (p, T4T_CC_FILE_MIN_LEN);
+    UINT8_TO_BE_STREAM (p, T4T_MY_VERSION);
+    UINT16_TO_BE_STREAM (p, CE_T4T_MAX_LE);
+    UINT16_TO_BE_STREAM (p, CE_T4T_MAX_LC);
+
+    /* Mandatory NDEF File Control TLV */
+    UINT8_TO_BE_STREAM (p, T4T_NDEF_FILE_CONTROL_TYPE);            /* type */
+    UINT8_TO_BE_STREAM (p, T4T_FILE_CONTROL_LENGTH);               /* length */
+    UINT16_TO_BE_STREAM (p, CE_T4T_MANDATORY_NDEF_FILE_ID);         /* file ID */
+    UINT16_TO_BE_STREAM (p, ndef_msg_max + T4T_FILE_LENGTH_SIZE);   /* max NDEF file size */
+    UINT8_TO_BE_STREAM (p, T4T_FC_READ_ACCESS);                    /* read access */
+
+    if (read_only)
+    {
+        UINT8_TO_BE_STREAM (p, T4T_FC_NO_WRITE_ACCESS);    /* read only */
+        p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_READ_ONLY;
+    }
+    else
+    {
+        UINT8_TO_BE_STREAM (p, T4T_FC_WRITE_ACCESS);       /* write access */
+        p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_READ_ONLY);
+    }
+
+    /* set mandatory NDEF file */
+    p_t4t->p_ndef_msg    = p_ndef_msg;
+    p_t4t->nlen          = ndef_msg_len;
+    p_t4t->max_file_size = ndef_msg_max + T4T_FILE_LENGTH_SIZE;
+
+    /* Initialize scratch buffer */
+    p_t4t->p_scratch_buf = p_scratch_buf;
+
+    if (p_scratch_buf)
+    {
+        memcpy (p_scratch_buf, p_ndef_msg, ndef_msg_len);
+    }
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4tRegisterAID
+**
+** Description      Register AID in CE T4T
+**
+**                  aid_len: length of AID (up to NFC_MAX_AID_LEN)
+**                  p_aid:   AID
+**                  p_cback: Raw frame will be forwarded with CE_RAW_FRAME_EVT
+**
+** Returns          tCE_T4T_AID_HANDLE if successful,
+**                  CE_T4T_AID_HANDLE_INVALID otherwisse
+**
+*******************************************************************************/
+tCE_T4T_AID_HANDLE CE_T4tRegisterAID (UINT8 aid_len, UINT8 *p_aid, tCE_CBACK *p_cback)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       xx;
+
+    /* Handle registering callback for wildcard AID (all AIDs) */
+    if (aid_len == 0)
+    {
+        CE_TRACE_API0 ("CE_T4tRegisterAID (): registering callback for wildcard AID ");
+
+        /* Check if a wildcard callback is already registered (only one is allowed) */
+        if (p_t4t->p_wildcard_aid_cback != NULL)
+        {
+            CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): only one wildcard AID can be registered at time.");
+            return CE_T4T_AID_HANDLE_INVALID;
+        }
+
+        CE_TRACE_DEBUG1 ("CE_T4tRegisterAID (): handle 0x%02x registered (for wildcard AID)", CE_T4T_WILDCARD_AID_HANDLE);
+        p_t4t->p_wildcard_aid_cback = p_cback;
+        return CE_T4T_WILDCARD_AID_HANDLE;
+    }
+
+
+    CE_TRACE_API5 ("CE_T4tRegisterAID () AID [%02X%02X%02X%02X...], %d bytes",
+                   *p_aid, *(p_aid+1), *(p_aid+2), *(p_aid+3), aid_len);
+
+    if (aid_len > NFC_MAX_AID_LEN)
+    {
+        CE_TRACE_ERROR1 ("CE_T4tRegisterAID (): AID is up to %d bytes", NFC_MAX_AID_LEN);
+        return CE_T4T_AID_HANDLE_INVALID;
+    }
+
+    if (p_cback == NULL)
+    {
+        CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): callback must be provided");
+        return CE_T4T_AID_HANDLE_INVALID;
+    }
+
+    for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++)
+    {
+        if (  (p_t4t->reg_aid[xx].aid_len == aid_len)
+            &&(!(memcmp(p_t4t->reg_aid[xx].aid, p_aid, aid_len)))  )
+        {
+            CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): already registered");
+            return CE_T4T_AID_HANDLE_INVALID;
+        }
+    }
+
+    for (xx = 0; xx < CE_T4T_MAX_REG_AID; xx++)
+    {
+        if (p_t4t->reg_aid[xx].aid_len == 0)
+        {
+            p_t4t->reg_aid[xx].aid_len = aid_len;
+            p_t4t->reg_aid[xx].p_cback = p_cback;
+            memcpy (p_t4t->reg_aid[xx].aid, p_aid, aid_len);
+            break;
+        }
+    }
+
+    if (xx >= CE_T4T_MAX_REG_AID)
+    {
+        CE_TRACE_ERROR0 ("CE_T4tRegisterAID (): No resource");
+        return CE_T4T_AID_HANDLE_INVALID;
+    }
+    else
+    {
+        CE_TRACE_DEBUG1 ("CE_T4tRegisterAID (): handle 0x%02x registered", xx);
+    }
+
+    return (xx);
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4tDeregisterAID
+**
+** Description      Deregister AID in CE T4T
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+NFC_API extern void CE_T4tDeregisterAID (tCE_T4T_AID_HANDLE aid_handle)
+{
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+
+    CE_TRACE_API1 ("CE_T4tDeregisterAID () handle 0x%02x", aid_handle);
+
+    /* Check if deregistering wildcard AID */
+    if (aid_handle == CE_T4T_WILDCARD_AID_HANDLE)
+    {
+        if (p_t4t->p_wildcard_aid_cback != NULL)
+        {
+            p_t4t->p_wildcard_aid_cback = NULL;
+        }
+        else
+        {
+            CE_TRACE_ERROR0 ("CE_T4tDeregisterAID (): Invalid handle");
+        }
+        return;
+    }
+
+    /* Deregister AID */
+    if ((aid_handle >= CE_T4T_MAX_REG_AID) || (p_t4t->reg_aid[aid_handle].aid_len==0))
+    {
+        CE_TRACE_ERROR0 ("CE_T4tDeregisterAID (): Invalid handle");
+    }
+    else
+    {
+        p_t4t->reg_aid[aid_handle].aid_len = 0;
+        p_t4t->reg_aid[aid_handle].p_cback = NULL;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetCC
+**
+** Description      Set fields in Capability Container File for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4TTestSetCC (UINT16 cc_len,
+                             UINT8  version,
+                             UINT16 max_le,
+                             UINT16 max_lc)
+{
+#if (CE_TEST_INCLUDED == TRUE)
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       *p;
+
+    CE_TRACE_DEBUG4 ("CE_T4TTestSetCC (): CCLen:0x%04X, Ver:0x%02X, MaxLe:0x%04X, MaxLc:0x%04X",
+                      cc_len, version, max_le, max_lc);
+
+    /* CC file */
+    p = p_t4t->cc_file;
+
+    if (cc_len != 0xFFFF)
+    {
+        UINT16_TO_BE_STREAM (p, cc_len);
+    }
+    else
+        p += 2;
+
+    if (version != 0xFF)
+    {
+        mapping_aid_test_enabled = TRUE;
+        if (version == T4T_VERSION_1_0)
+            ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x00;
+        else if (version == T4T_VERSION_2_0)
+            ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x01;
+        else /* Undefined version */
+            ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0xFF;
+
+        UINT8_TO_BE_STREAM (p, version);
+    }
+    else
+    {
+        mapping_aid_test_enabled = FALSE;
+        p += 1;
+    }
+
+    if (max_le != 0xFFFF)
+    {
+        UINT16_TO_BE_STREAM (p, max_le);
+    }
+    else
+        p += 2;
+
+    if (max_lc != 0xFFFF)
+    {
+        UINT16_TO_BE_STREAM (p, max_lc);
+    }
+    else
+        p += 2;
+
+    return NFC_STATUS_OK;
+#else
+    return NFC_STATUS_FAILED;
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         CE_T4TTestSetNDEFCtrlTLV
+**
+** Description      Set fields in NDEF File Control TLV for testing
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS CE_T4TTestSetNDEFCtrlTLV (UINT8  type,
+                                      UINT8  length,
+                                      UINT16 file_id,
+                                      UINT16 max_file_size,
+                                      UINT8  read_access,
+                                      UINT8  write_access)
+{
+#if (CE_TEST_INCLUDED == TRUE)
+    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
+    UINT8       *p;
+
+    CE_TRACE_DEBUG6 ("CE_T4TTestSetNDEFCtrlTLV (): type:0x%02X, len:0x%02X, FileID:0x%04X, MaxFile:0x%04X, RdAcc:0x%02X, WrAcc:0x%02X",
+                      type, length, file_id, max_file_size, read_access, write_access);
+
+    /* NDEF File control TLV */
+    p = p_t4t->cc_file + T4T_FC_TLV_OFFSET_IN_CC;
+
+    if (type != 0xFF)
+    {
+        UINT8_TO_BE_STREAM (p, type);
+    }
+    else
+        p += 1;
+
+    if (length != 0xFF)
+    {
+        UINT8_TO_BE_STREAM (p, length);
+    }
+    else
+        p += 1;
+
+    if (file_id != 0xFFFF)
+    {
+        UINT16_TO_BE_STREAM (p, file_id);
+    }
+    else
+        p += 2;
+
+    if (max_file_size != 0xFFFF)
+    {
+        UINT16_TO_BE_STREAM (p, max_file_size);
+    }
+    else
+        p += 2;
+
+    if (read_access != 0xFF)
+    {
+        UINT8_TO_BE_STREAM (p, read_access);
+    }
+    else
+        p += 1;
+
+    if (write_access != 0xFF)
+    {
+        UINT8_TO_BE_STREAM (p, write_access);
+    }
+    else
+        p += 1;
+
+    return NFC_STATUS_OK;
+#else
+    return NFC_STATUS_FAILED;
+#endif
+}
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/rw_i93.c b/src/nfc/tags/rw_i93.c
new file mode 100644
index 0000000..35102c5
--- /dev/null
+++ b/src/nfc/tags/rw_i93.c
@@ -0,0 +1,3840 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for ISO 15693 in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#if (NFC_INCLUDED == TRUE)
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+
+#define RW_I93_TOUT_RESP                        1000    /* Response timeout     */
+#define RW_I93_TOUT_STAY_QUIET                  200     /* stay quiet timeout   */
+#define RW_I93_READ_MULTI_BLOCK_SIZE            128     /* max reading data if read multi block is supported */
+#define RW_I93_FORMAT_DATA_LEN                  8       /* CC, zero length NDEF, Terminator TLV              */
+
+/* main state */
+enum
+{
+    RW_I93_STATE_NOT_ACTIVATED,         /* ISO15693 is not activated            */
+    RW_I93_STATE_IDLE,                  /* waiting for upper layer API          */
+    RW_I93_STATE_BUSY,                  /* waiting for response from tag        */
+
+    RW_I93_STATE_DETECT_NDEF,           /* performing NDEF detection precedure  */
+    RW_I93_STATE_READ_NDEF,             /* performing read NDEF procedure       */
+    RW_I93_STATE_UPDATE_NDEF,           /* performing update NDEF procedure     */
+    RW_I93_STATE_FORMAT,                /* performing format procedure          */
+    RW_I93_STATE_SET_READ_ONLY,         /* performing set read-only procedure   */
+
+    RW_I93_STATE_PRESENCE_CHECK         /* checking presence of tag             */
+};
+
+/* sub state */
+enum
+{
+    RW_I93_SUBSTATE_WAIT_UID,               /* waiting for response of inventory    */
+    RW_I93_SUBSTATE_WAIT_SYS_INFO,          /* waiting for response of get sys info */
+    RW_I93_SUBSTATE_WAIT_CC,                /* waiting for reading CC               */
+    RW_I93_SUBSTATE_SEARCH_NDEF_TLV,        /* searching NDEF TLV                   */
+    RW_I93_SUBSTATE_CHECK_LOCK_STATUS,      /* check if any NDEF TLV is locked      */
+
+    RW_I93_SUBSTATE_RESET_LEN,              /* set length to 0 to update NDEF TLV   */
+    RW_I93_SUBSTATE_WRITE_NDEF,             /* writing NDEF and Terminator TLV      */
+    RW_I93_SUBSTATE_UPDATE_LEN,             /* set length into NDEF TLV             */
+
+    RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI,   /* reset DSFID and AFI                  */
+    RW_I93_SUBSTATE_CHECK_READ_ONLY,        /* check if any block is locked         */
+    RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV,      /* write CC and empty NDEF/Terminator TLV */
+
+    RW_I93_SUBSTATE_WAIT_UPDATE_CC,         /* updating CC as read-only             */
+    RW_I93_SUBSTATE_LOCK_NDEF_TLV,          /* lock blocks of NDEF TLV              */
+    RW_I93_SUBSTATE_WAIT_LOCK_CC            /* lock block of CC                     */
+};
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_i93_get_state_name (UINT8 state);
+static char *rw_i93_get_sub_state_name (UINT8 sub_state);
+#endif
+
+static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+void rw_i93_handle_error (tNFC_STATUS status);
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_product_version
+**
+** Description      Get product version from UID
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_get_product_version (UINT8 *p_uid)
+{
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+    if (!memcmp (p_i93->uid, p_uid, I93_UID_BYTE_LEN))
+    {
+        return;
+    }
+
+    RW_TRACE_DEBUG0 ("rw_i93_get_product_version ()");
+
+    memcpy (p_i93->uid, p_uid, I93_UID_BYTE_LEN);
+
+    if (p_uid[1] == I93_UID_IC_MFG_CODE_NXP)
+    {
+        if (p_uid[2] == I93_UID_ICODE_SLI)
+            p_i93->product_version = RW_I93_ICODE_SLI;
+        else if (p_uid[2] == I93_UID_ICODE_SLI_S)
+            p_i93->product_version = RW_I93_ICODE_SLI_S;
+        else if (p_uid[2] == I93_UID_ICODE_SLI_L)
+            p_i93->product_version = RW_I93_ICODE_SLI_L;
+        else
+            p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+    }
+    else if (p_uid[1] == I93_UID_IC_MFG_CODE_TI)
+    {
+        if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_INLAY)
+            p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_INLAY;
+        else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PLUS_CHIP)
+            p_i93->product_version = RW_I93_TAG_IT_HF_I_PLUS_CHIP;
+        else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
+            p_i93->product_version = RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY;
+        else if ((p_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)
+            p_i93->product_version = RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY;
+        else
+            p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+    }
+    else
+    {
+        p_i93->product_version = RW_I93_UNKNOWN_PRODUCT;
+    }
+
+    RW_TRACE_DEBUG1 ("product_version = %d", p_i93->product_version);
+
+    switch (p_i93->product_version)
+    {
+    case RW_I93_ICODE_SLI:
+    case RW_I93_ICODE_SLI_S:
+    case RW_I93_ICODE_SLI_L:
+    case RW_I93_TAG_IT_HF_I_PLUS_INLAY:
+    case RW_I93_TAG_IT_HF_I_PLUS_CHIP:
+        /* All of ICODE supports Get System Information Command */
+        /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */
+        break;
+    case RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY:
+    case RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY:
+        /* these don't support Get System Information Command */
+        /* these support only Inventory, Stay Quiet, Read Single Block, Write Single Block, Lock Block */
+        p_i93->block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
+        p_i93->num_block  = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_NUM_USER_BLK;
+        break;
+    default: /* RW_I93_UNKNOWN_PRODUCT */
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_to_upper
+**
+** Description      Send response to upper layer
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_send_to_upper (BT_HDR *p_resp)
+{
+    UINT8      *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
+    UINT16     length = p_resp->len;
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    tRW_DATA   rw_data;
+    UINT8      event = RW_I93_MAX_EVT;
+    UINT8      flags;
+    BT_HDR     *p_buff;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_to_upper ()");
+
+    STREAM_TO_UINT8 (flags, p);
+    length--;
+
+    if (flags & I93_FLAG_ERROR_DETECTED)
+    {
+        /* notify error to upper layer */
+        rw_data.i93_cmd_cmpl.status  = NFC_STATUS_FAILED;
+        rw_data.i93_cmd_cmpl.command = p_i93->sent_cmd;
+        STREAM_TO_UINT8 (rw_data.i93_cmd_cmpl.error_code, p);
+
+        rw_cb.tcb.i93.sent_cmd = 0;
+        (*(rw_cb.p_cback)) (RW_I93_CMD_CMPL_EVT, &rw_data);
+        return;
+    }
+
+    switch (p_i93->sent_cmd)
+    {
+    case I93_CMD_INVENTORY:
+
+        /* forward inventory response */
+        rw_data.i93_inventory.status = NFC_STATUS_OK;
+        STREAM_TO_UINT8 (rw_data.i93_inventory.dsfid, p);
+
+        p_uid = rw_data.i93_inventory.uid;
+        STREAM_TO_ARRAY8 (p_uid, p);
+
+        /* store UID and get product version */
+        rw_i93_get_product_version (p_uid);
+
+        event = RW_I93_INVENTORY_EVT;
+        break;
+
+    case I93_CMD_READ_SINGLE_BLOCK:
+    case I93_CMD_READ_MULTI_BLOCK:
+    case I93_CMD_GET_MULTI_BLK_SEC:
+
+        /* forward tag data or security status */
+        p_buff = (BT_HDR*) GKI_getbuf ((UINT16) (length + BT_HDR_SIZE));
+
+        if (p_buff)
+        {
+            p_buff->offset = 0;
+            p_buff->len    = length;
+
+            memcpy ((p_buff + 1), p, length);
+
+            rw_data.i93_data.status  = NFC_STATUS_OK;
+            rw_data.i93_data.command = p_i93->sent_cmd;
+            rw_data.i93_data.p_data  = p_buff;
+
+            event = RW_I93_DATA_EVT;
+        }
+        else
+        {
+            rw_data.i93_cmd_cmpl.status     = NFC_STATUS_NO_BUFFERS;
+            rw_data.i93_cmd_cmpl.command    = p_i93->sent_cmd;
+            rw_data.i93_cmd_cmpl.error_code = 0;
+
+            event = RW_I93_CMD_CMPL_EVT;
+        }
+        break;
+
+    case I93_CMD_WRITE_SINGLE_BLOCK:
+    case I93_CMD_LOCK_BLOCK:
+    case I93_CMD_WRITE_MULTI_BLOCK:
+    case I93_CMD_SELECT:
+    case I93_CMD_RESET_TO_READY:
+    case I93_CMD_WRITE_AFI:
+    case I93_CMD_LOCK_AFI:
+    case I93_CMD_WRITE_DSFID:
+    case I93_CMD_LOCK_DSFID:
+
+        /* notify the complete of command */
+        rw_data.i93_cmd_cmpl.status     = NFC_STATUS_OK;
+        rw_data.i93_cmd_cmpl.command    = p_i93->sent_cmd;
+        rw_data.i93_cmd_cmpl.error_code = 0;
+
+        event = RW_I93_CMD_CMPL_EVT;
+        break;
+
+    case I93_CMD_GET_SYS_INFO:
+
+        rw_data.i93_cmd_cmpl.status = NFC_STATUS_OK;
+
+        STREAM_TO_UINT8 (rw_data.i93_sys_info.info_flags, p);
+        p_i93->info_flags = rw_data.i93_sys_info.info_flags;
+
+        p_uid = rw_data.i93_sys_info.uid;
+        STREAM_TO_ARRAY8 (p_uid, p);
+
+        /* store UID and get product version */
+        rw_i93_get_product_version (p_uid);
+
+        if (rw_data.i93_sys_info.info_flags & I93_INFO_FLAG_DSFID)
+        {
+            STREAM_TO_UINT8 (rw_data.i93_sys_info.dsfid, p);
+            p_i93->dsfid = rw_data.i93_sys_info.dsfid;
+        }
+        if (rw_data.i93_sys_info.info_flags & I93_INFO_FLAG_AFI)
+        {
+            STREAM_TO_UINT8 (rw_data.i93_sys_info.afi, p);
+            p_i93->afi = rw_data.i93_sys_info.afi;
+        }
+        if (rw_data.i93_sys_info.info_flags & I93_INFO_FLAG_MEM_SIZE)
+        {
+            STREAM_TO_UINT8 (rw_data.i93_sys_info.num_block, p);
+            /* it is one less than actual number of bytes */
+            rw_data.i93_sys_info.num_block += 1;
+
+            STREAM_TO_UINT8 (rw_data.i93_sys_info.block_size, p);
+            /* it is one less than actual number of blocks */
+            rw_data.i93_sys_info.block_size = (rw_data.i93_sys_info.block_size & 0x1F) + 1;
+
+            p_i93->num_block  = rw_data.i93_sys_info.num_block;
+            p_i93->block_size = rw_data.i93_sys_info.block_size;
+        }
+        if (rw_data.i93_sys_info.info_flags & I93_INFO_FLAG_IC_REF)
+        {
+            STREAM_TO_UINT8 (rw_data.i93_sys_info.IC_reference, p);
+
+            p_i93->ic_reference = rw_data.i93_sys_info.IC_reference;
+
+            if (  (p_i93->uid[0] == I93_UID_FIRST_BYTE)
+                &&(p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP)
+                &&(p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)  )
+            {
+                p_i93->num_block  = 8;
+                p_i93->block_size = 4;
+            }
+        }
+
+        event = RW_I93_SYS_INFO_EVT;
+        break;
+
+    default:
+        break;
+    }
+
+    rw_cb.tcb.i93.sent_cmd = 0;
+    if (event != RW_I93_MAX_EVT)
+    {
+        (*(rw_cb.p_cback)) (event, &rw_data);
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_to_upper (): Invalid response");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_to_lower
+**
+** Description      Send Request frame to lower layer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+BOOLEAN rw_i93_send_to_lower (BT_HDR *p_msg)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispRWI93Tag (p_msg, FALSE, 0x00);
+#endif
+
+    if (NFC_SendData (NFC_RF_CONN_ID, p_msg) != NFC_STATUS_OK)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_to_lower (): NFC_SendData () failed");
+        return FALSE;
+    }
+
+    nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
+                           (RW_I93_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC)/1000);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_inventory
+**
+** Description      Send Inventory Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_inventory (UINT8 *p_uid, UINT8 afi)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG1 ("rw_i93_send_cmd_inventory () AFI:0x%02X", afi);
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_inventory (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 4;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_SLOT_ONE | I93_FLAG_INVENTORY_SET | I93_FLAG_AFI_PRESENT | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_INVENTORY);
+
+    /* Parameters */
+    UINT8_TO_STREAM (p, afi);    /* Optional AFI */
+
+    if (p_uid)
+    {
+        UINT8_TO_STREAM  (p, I93_UID_BYTE_LEN*8);         /* Mask Length */
+        ARRAY8_TO_STREAM (p, p_uid);                      /* UID */
+        p_cmd->len += I93_UID_BYTE_LEN;
+    }
+    else
+    {
+        UINT8_TO_STREAM (p, 0x00);   /* Mask Length */
+    }
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_INVENTORY;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_stay_quiet
+**
+** Description      Send Stay Quiet Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_stay_quiet (void)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_stay_quiet ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_stay_quiet (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 10;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_STAY_QUIET);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_STAY_QUIET;
+
+        /* restart timer for stay quiet */
+        nfc_start_quick_timer (&rw_cb.tcb.i93.timer, NFC_TTYPE_RW_I93_RESPONSE,
+                               (RW_I93_TOUT_STAY_QUIET * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_read_single_block
+**
+** Description      Send Read Single Block Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_read_single_block (UINT8 block_number, BOOLEAN read_security)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_single_block ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_single_block (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 11;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    if (read_security)
+    {
+        UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+    }
+    else
+    {
+        UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+    }
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_READ_SINGLE_BLOCK);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);     /* UID */
+    UINT8_TO_STREAM (p, block_number);          /* Block number */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_READ_SINGLE_BLOCK;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_single_block
+**
+** Description      Send Write Single Block Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_single_block (UINT8 block_number, UINT8 *p_data)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_single_block ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_single_block (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 11 + rw_cb.tcb.i93.block_size;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    if (  (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+    {
+        /* Option must be set for TI tag */
+        UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+    }
+    else
+    {
+        UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+    }
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_WRITE_SINGLE_BLOCK);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+    UINT8_TO_STREAM (p, block_number);         /* Block number */
+
+    /* Data */
+    ARRAY_TO_STREAM (p, p_data, rw_cb.tcb.i93.block_size);
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_WRITE_SINGLE_BLOCK;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_lock_block
+**
+** Description      Send Lock Block Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_block (UINT8 block_number)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_block ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_block (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 11;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    if (  (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+    {
+        /* Option must be set for TI tag */
+        UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | I93_FLAG_OPTION_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+    }
+    else
+    {
+        UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+    }
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_LOCK_BLOCK);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+    UINT8_TO_STREAM (p, block_number);         /* Block number */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_LOCK_BLOCK;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_read_multi_blocks
+**
+** Description      Send Read Multiple Blocks Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_read_multi_blocks (UINT8 first_block_number, UINT16 number_blocks)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_read_multi_blocks ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_read_multi_blocks (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 12;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_READ_MULTI_BLOCK);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+    UINT8_TO_STREAM (p, first_block_number);   /* First block number */
+    UINT8_TO_STREAM (p, number_blocks - 1);    /* Number of blocks, 0x00 to read one block */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_READ_MULTI_BLOCK;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_multi_blocks
+**
+** Description      Send Write Multiple Blocks Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_multi_blocks (UINT8  first_block_number,
+                                                UINT16 number_blocks,
+                                                UINT8 *p_data)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_multi_blocks ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_multi_blocks (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 12 + number_blocks * rw_cb.tcb.i93.block_size;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_WRITE_MULTI_BLOCK);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);   /* UID */
+    UINT8_TO_STREAM (p, first_block_number);   /* First block number */
+    UINT8_TO_STREAM (p, number_blocks - 1);    /* Number of blocks, 0x00 to read one block */
+
+    /* Data */
+    ARRAY_TO_STREAM (p, p_data, number_blocks * rw_cb.tcb.i93.block_size);
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_WRITE_MULTI_BLOCK;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_select
+**
+** Description      Send Select Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_select (UINT8 *p_uid)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_select ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_select (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 10 ;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_SELECT);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, p_uid);    /* UID */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_SELECT;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_reset_to_ready
+**
+** Description      Send Reset to Ready Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_reset_to_ready (void)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_reset_to_ready ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_reset_to_ready (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 10 ;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_RESET_TO_READY);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_RESET_TO_READY;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_afi
+**
+** Description      Send Write AFI Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_afi (UINT8 afi)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_afi ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_afi (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 11;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_WRITE_AFI);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+    UINT8_TO_STREAM (p, afi);                  /* AFI */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_WRITE_AFI;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_lock_afi
+**
+** Description      Send Lock AFI Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_afi (void)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_afi ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_afi (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 10;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_LOCK_AFI);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_LOCK_AFI;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_write_dsfid
+**
+** Description      Send Write DSFID Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_write_dsfid (UINT8 dsfid)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_write_dsfid ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_write_dsfid (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 11;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_WRITE_DSFID);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+    UINT8_TO_STREAM (p, dsfid);                /* DSFID */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_WRITE_DSFID;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_lock_dsfid
+**
+** Description      Send Lock DSFID Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_lock_dsfid (void)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_lock_dsfid ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_lock_dsfid (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 10;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_LOCK_DSFID);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_LOCK_DSFID;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_get_sys_info
+**
+** Description      Send Get System Information Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_get_sys_info (UINT8 *p_uid)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_sys_info ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_sys_info (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 10;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_GET_SYS_INFO);
+
+    /* Parameters */
+    if (p_uid)
+    {
+        ARRAY8_TO_STREAM (p, p_uid);               /* UID */
+    }
+    else
+    {
+        ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);   /* UID */
+    }
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_GET_SYS_INFO;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_send_cmd_get_multi_block_sec
+**
+** Description      Send Get Multiple Block Security Status Request to VICC
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_send_cmd_get_multi_block_sec (UINT8  first_block_number,
+                                                 UINT16 number_blocks)
+{
+    BT_HDR      *p_cmd;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG0 ("rw_i93_send_cmd_get_multi_block_sec ()");
+
+    p_cmd = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_cmd)
+    {
+        RW_TRACE_ERROR0 ("rw_i93_send_cmd_get_multi_block_sec (): Cannot allocate buffer");
+        return NFC_STATUS_NO_BUFFERS;
+    }
+
+    p_cmd->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p_cmd->len    = 12;
+    p = (UINT8 *) (p_cmd + 1) + p_cmd->offset;
+
+    /* Flags */
+    UINT8_TO_STREAM (p, (I93_FLAG_ADDRESS_SET | RW_I93_FLAG_SUB_CARRIER | RW_I93_FLAG_DATA_RATE));
+
+    /* Command Code */
+    UINT8_TO_STREAM (p, I93_CMD_GET_MULTI_BLK_SEC);
+
+    /* Parameters */
+    ARRAY8_TO_STREAM (p, rw_cb.tcb.i93.uid);    /* UID */
+    UINT8_TO_STREAM (p, first_block_number);   /* First block number */
+    UINT8_TO_STREAM (p, number_blocks - 1);    /* Number of blocks, 0x00 to read one block */
+
+    if (rw_i93_send_to_lower (p_cmd))
+    {
+        rw_cb.tcb.i93.sent_cmd  = I93_CMD_GET_MULTI_BLK_SEC;
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_next_blocks
+**
+** Description      Read as many blocks as possible (up to RW_I93_READ_MULTI_BLOCK_SIZE)
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_get_next_blocks (UINT16 offset)
+{
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    UINT8      first_block;
+    UINT16     num_block;
+
+    first_block = (UINT8) (offset / p_i93->block_size);
+
+    /* more blocks, more efficent but more error rate */
+
+    if (p_i93->intl_flags & RW_I93_FLAG_READ_MULTI_BLOCK)
+    {
+        num_block = RW_I93_READ_MULTI_BLOCK_SIZE / p_i93->block_size;
+
+        if (num_block + first_block > p_i93->num_block)
+            num_block = p_i93->num_block - first_block;
+
+        return rw_i93_send_cmd_read_multi_blocks (first_block, num_block);
+    }
+    else
+    {
+        return rw_i93_send_cmd_read_single_block (first_block, FALSE);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_detect_ndef
+**
+** Description      Process NDEF detection procedure
+**
+**                  1. Get UID if not having yet
+**                  2. Get System Info if not having yet
+**                  3. Read first block for CC
+**                  4. Search NDEF Type and length
+**                  5. Get block status to get max NDEF size and read-only status
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_detect_ndef (BT_HDR *p_resp)
+{
+    UINT8      *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
+    UINT8       flags, u8 = 0, cc[4], first_block, last_block;
+    UINT16      length = p_resp->len;
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    tRW_DATA    rw_data;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_i93_sm_detect_ndef () sub_state:%s (0x%x)",
+                      rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_i93_sm_detect_ndef () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+    STREAM_TO_UINT8 (flags, p);
+    length--;
+
+    if (flags & I93_FLAG_ERROR_DETECTED)
+    {
+        RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
+        rw_i93_handle_error (NFC_STATUS_FAILED);
+        return;
+    }
+
+    switch (p_i93->sub_state)
+    {
+    case RW_I93_SUBSTATE_WAIT_UID:
+
+        STREAM_TO_UINT8 (u8, p); /* DSFID */
+        p_uid = p_i93->uid;
+        STREAM_TO_ARRAY8 (p_uid, p);
+
+        if (u8 != I93_DFS_UNSUPPORTED)
+        {
+            /* if Data Storage Format is unknown */
+            RW_TRACE_DEBUG1 ("Got unknown DSFID (0x%02x)", u8);
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        else
+        {
+            /* get system information to get memory size */
+            if (rw_i93_send_cmd_get_sys_info (NULL) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+
+        STREAM_TO_UINT8 (p_i93->info_flags, p);  /* info_flags */
+
+        p_uid = p_i93->uid;
+        STREAM_TO_ARRAY8 (p_uid, p);
+
+        if (p_i93->info_flags & I93_INFO_FLAG_DSFID)
+        {
+            STREAM_TO_UINT8 (p_i93->dsfid, p);
+        }
+        if (p_i93->info_flags & I93_INFO_FLAG_AFI)
+        {
+            STREAM_TO_UINT8 (p_i93->afi, p);
+        }
+        if (p_i93->info_flags & I93_INFO_FLAG_MEM_SIZE)
+        {
+            STREAM_TO_UINT8 (p_i93->num_block, p);
+            /* it is one less than actual number of bytes */
+            p_i93->num_block += 1;
+
+            STREAM_TO_UINT8 (p_i93->block_size, p);
+            /* it is one less than actual number of blocks */
+            p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
+
+            status = NFC_STATUS_OK;
+        }
+        if (p_i93->info_flags & I93_INFO_FLAG_IC_REF)
+        {
+            STREAM_TO_UINT8 (p_i93->ic_reference, p);
+
+            /* I-CODE SLI-L/SLIX-L */
+            if (  (p_i93->uid[0] == I93_UID_FIRST_BYTE)
+                &&(p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP)
+                &&(p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L)  )
+            {
+                p_i93->num_block  = 8;
+                p_i93->block_size = 4;
+                status = NFC_STATUS_OK;
+            }
+        }
+
+        if (status != NFC_STATUS_OK)
+        {
+            RW_TRACE_DEBUG0 ("Unable to get tag memory size");
+            rw_i93_handle_error (status);
+        }
+        else
+        {
+            /* read CC in the first block */
+            if (rw_i93_send_cmd_read_single_block (0x00, FALSE) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WAIT_CC:
+
+        /* assume block size is more than 4 */
+        STREAM_TO_ARRAY (cc, p, 4);
+
+        status = NFC_STATUS_FAILED;
+
+        /*
+        ** Capability Container (CC)
+        **
+        ** CC[0] : magic number (0xE1)
+        ** CC[1] : Bit 7-6:Major version number
+        **       : Bit 5-4:Minor version number
+        **       : Bit 3-2:Read access condition    (00b: read access granted without any security)
+        **       : Bit 1-0:Write access condition   (00b: write access granted without any security)
+        ** CC[2] : Memory size in 8 bytes (Ex. 0x04 is 32 bytes)
+        ** CC[3] : Bit 0:Read multiple blocks is supported
+        */
+
+        RW_TRACE_DEBUG4 ("rw_i93_sm_detect_ndef (): cc: 0x%02X 0x%02X 0x%02X 0x%02X", cc[0], cc[1], cc[2], cc[3]);
+        RW_TRACE_DEBUG2 ("rw_i93_sm_detect_ndef (): Total blocks:0x%04X, Block size:0x%02X", p_i93->num_block, p_i93->block_size );
+
+        if (  (cc[0] == I93_ICODE_CC_MAGIC_NUMER)
+            &&((cc[2] * 8) == (p_i93->num_block * p_i93->block_size))  )
+        {
+            if ((cc[1] & I93_ICODE_CC_READ_ACCESS_MASK) == I93_ICODE_CC_READ_ACCESS_GRANTED)
+            {
+                if ((cc[1] & I93_ICODE_CC_WRITE_ACCESS_MASK) != I93_ICODE_CC_WRITE_ACCESS_GRANTED)
+                {
+                    /* read-only or password required to write */
+                    p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+                }
+                if (cc[3] & I93_ICODE_CC_MBREAD_MASK)
+                {
+                    /* tag supports read multi blocks command */
+                    p_i93->intl_flags |= RW_I93_FLAG_READ_MULTI_BLOCK;
+                }
+                status = NFC_STATUS_OK;
+            }
+        }
+
+        if (status == NFC_STATUS_OK)
+        {
+            /* seach NDEF TLV from offset 4 */
+            p_i93->rw_offset = 4;
+
+            if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state        = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
+                p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
+
+        /* search TLV within read blocks */
+        for (u8 = 0; u8 < length; u8++)
+        {
+            /* if looking for type */
+            if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_TYPE)
+            {
+                if (*(p+u8) == I93_ICODE_TLV_TYPE_NULL)
+                {
+                    continue;
+                }
+                else if (  (*(p+u8) == I93_ICODE_TLV_TYPE_NDEF)
+                         ||(*(p+u8) == I93_ICODE_TLV_TYPE_PROP)  )
+                {
+                    /* store found type and get length field */
+                    p_i93->tlv_type = *(p+u8);
+                    p_i93->ndef_tlv_start_offset = p_i93->rw_offset + u8;
+
+                    p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_1;
+                }
+                else if (*(p+u8) == I93_ICODE_TLV_TYPE_TERM)
+                {
+                    /* no NDEF TLV found */
+                    p_i93->tlv_type = I93_ICODE_TLV_TYPE_TERM;
+                    break;
+                }
+                else
+                {
+                    RW_TRACE_DEBUG1 ("Invalid type: 0x%02x", *(p+u8));
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                    return;
+                }
+            }
+            else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_1)
+            {
+                /* if 3 bytes length field */
+                if (*(p+u8) == 0xFF)
+                {
+                    /* need 2 more bytes for length field */
+                    p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_2;
+                }
+                else
+                {
+                    p_i93->tlv_length = *(p+u8);
+                    p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
+
+                    if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
+                    {
+                        p_i93->ndef_tlv_last_offset = p_i93->ndef_tlv_start_offset + 1 + p_i93->tlv_length;
+                        break;
+                    }
+                }
+            }
+            else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_2)
+            {
+                /* the second byte of 3 bytes length field */
+                p_i93->tlv_length = *(p+u8);
+                p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_LENGTH_3;
+            }
+            else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_LENGTH_3)
+            {
+                /* the last byte of 3 bytes length field */
+                p_i93->tlv_length = (p_i93->ndef_length << 8) + *(p+u8);
+                p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_VALUE;
+
+                if (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
+                {
+                    p_i93->ndef_tlv_last_offset = p_i93->ndef_tlv_start_offset + 3 + p_i93->tlv_length;
+                    break;
+                }
+            }
+            else if (p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)
+            {
+                /* this is other than NDEF TLV */
+                if (p_i93->tlv_length <= length - u8)
+                {
+                    /* skip value field */
+                    u8 += (UINT8)p_i93->tlv_length;
+                    p_i93->tlv_detect_state = RW_I93_TLV_DETECT_STATE_TYPE;
+                }
+                else
+                {
+                    /* read more data */
+                    p_i93->tlv_length -= (length - u8);
+                    break;
+                }
+            }
+        }
+
+        /* found NDEF TLV and read length field */
+        if (  (p_i93->tlv_type == I93_ICODE_TLV_TYPE_NDEF)
+            &&(p_i93->tlv_detect_state == RW_I93_TLV_DETECT_STATE_VALUE)  )
+        {
+            p_i93->ndef_length = p_i93->tlv_length;
+
+            /* get lock status to see if read-only */
+            if (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+                ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
+                ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))  )
+            {
+                /* these doesn't support GetMultiBlockSecurityStatus */
+
+                p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
+                first_block = (UINT8) (p_i93->ndef_tlv_start_offset / p_i93->block_size);
+
+                /* read block to get lock status */
+                rw_i93_send_cmd_read_single_block (first_block, TRUE);
+                p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
+            }
+            else
+            {
+                if (rw_i93_send_cmd_get_multi_block_sec (0, p_i93->num_block) == NFC_STATUS_OK)
+                {
+                    p_i93->sub_state = RW_I93_SUBSTATE_CHECK_LOCK_STATUS;
+                }
+                else
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                }
+            }
+        }
+        else
+        {
+            /* read more data */
+            p_i93->rw_offset += length;
+
+            if (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+            else if (rw_i93_get_next_blocks (p_i93->rw_offset) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_SEARCH_NDEF_TLV;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        break;
+
+    case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
+
+        if (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+            ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
+            ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))  )
+        {
+            /* these doesn't support GetMultiBlockSecurityStatus */
+
+            u8 = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+            last_block  = (UINT8) (p_i93->ndef_tlv_last_offset / p_i93->block_size);
+
+            if ((*p) & I93_BLOCK_LOCKED)
+            {
+                if (u8 <= last_block)
+                {
+                    p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+                }
+            }
+            else
+            {
+                /* if we need to check more user blocks */
+                if (u8 + 1 < p_i93->num_block)
+                {
+                    p_i93->rw_offset += p_i93->block_size;
+
+                    /* read block to get lock status */
+                    rw_i93_send_cmd_read_single_block ((UINT8) (p_i93->rw_offset / p_i93->block_size), TRUE);
+                    break;
+                }
+            }
+
+            p_i93->max_ndef_length = p_i93->ndef_length
+                                     /* add available bytes including the last block of NDEF TLV */
+                                     + (p_i93->block_size * (u8 - last_block) + 1)
+                                     - (p_i93->ndef_tlv_last_offset % p_i93->block_size)
+                                     - 1;
+        }
+        else
+        {
+            p_i93->max_ndef_length = p_i93->ndef_length
+                                     /* add available bytes in the last block of NDEF TLV */
+                                     + p_i93->block_size
+                                     - (p_i93->ndef_tlv_last_offset % p_i93->block_size)
+                                     - 1;
+
+            first_block = (UINT8) (p_i93->ndef_tlv_start_offset / p_i93->block_size);
+            last_block  = (UINT8) (p_i93->ndef_tlv_last_offset / p_i93->block_size);
+
+            for (u8 = first_block; u8 < p_i93->num_block; u8++)
+            {
+                /* if any block of NDEF TLV is locked */
+                if (u8 <= last_block)
+                {
+                    if (*(p+u8) & I93_BLOCK_LOCKED)
+                    {
+                        p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+                        break;
+                    }
+                }
+                else
+                {
+                    if (*(p+u8) & I93_BLOCK_LOCKED)
+                    {
+                        /* no more consecutive unlocked block */
+                        if (  (p_i93->ndef_length < 0xFF)
+                            &&(p_i93->max_ndef_length >= 0xFF)  )
+                        {
+                            /* 3 bytes length field must be used */
+                            p_i93->max_ndef_length -= 2;
+                        }
+                        break;
+                    }
+                    else
+                    {
+                        /* add block size if not locked */
+                        p_i93->max_ndef_length += p_i93->block_size;
+                    }
+                }
+            }
+        }
+
+        rw_data.ndef.status     = NFC_STATUS_OK;
+        rw_data.ndef.protocol   = NFC_PROTOCOL_15693;
+        rw_data.ndef.flags      = 0;
+        rw_data.ndef.flags      |= RW_NDEF_FL_SUPPORTED;
+        rw_data.ndef.flags      |= RW_NDEF_FL_FORMATED;
+        rw_data.ndef.flags      |= RW_NDEF_FL_FORMATABLE;
+        rw_data.ndef.cur_size   = p_i93->ndef_length;
+
+        if (p_i93->intl_flags & RW_I93_FLAG_READ_ONLY)
+        {
+            rw_data.ndef.flags    |= RW_NDEF_FL_READ_ONLY;
+            rw_data.ndef.max_size  = p_i93->ndef_length;
+        }
+        else
+        {
+            rw_data.ndef.flags    |= RW_NDEF_FL_HARD_LOCKABLE;
+            rw_data.ndef.max_size  = p_i93->max_ndef_length;
+        }
+
+        p_i93->state    = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+
+        RW_TRACE_DEBUG3 ("NDEF cur_size(%d),max_size (%d), flags (0x%x)",
+                         rw_data.ndef.cur_size,
+                         rw_data.ndef.max_size,
+                         rw_data.ndef.flags);
+
+        (*(rw_cb.p_cback)) (RW_I93_NDEF_DETECT_EVT, &rw_data);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_read_ndef
+**
+** Description      Process NDEF read procedure
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_read_ndef (BT_HDR *p_resp)
+{
+    UINT8      *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
+    UINT8       flags;
+    UINT16      offset, length = p_resp->len;
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    tRW_DATA    rw_data;
+
+    RW_TRACE_DEBUG0 ("rw_i93_sm_read_ndef ()");
+
+    STREAM_TO_UINT8 (flags, p);
+    length--;
+
+    if (flags & I93_FLAG_ERROR_DETECTED)
+    {
+        RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
+        rw_i93_handle_error (NFC_STATUS_FAILED);
+        return;
+    }
+
+    /* if this is the first block */
+    if (p_i93->rw_length == 0)
+    {
+        /* get start of NDEF in the first block */
+        offset = p_i93->ndef_tlv_start_offset % p_i93->block_size;
+
+        if (p_i93->ndef_length < 0xFF)
+        {
+            offset += 2;
+        }
+        else
+        {
+            offset += 4;
+        }
+
+        /* adjust offset if read more blocks because the first block doesn't have NDEF */
+        offset -= (p_i93->rw_offset - p_i93->ndef_tlv_start_offset);
+    }
+    else
+    {
+        offset = 0;
+    }
+
+    /* if read enough data to skip type and length field for the beginning */
+    if (offset < length)
+    {
+        offset++; /* flags */
+        p_resp->offset += offset;
+        p_resp->len    -= offset;
+
+        rw_data.data.status = NFC_STATUS_OK;
+        rw_data.data.p_data = p_resp;
+
+        p_i93->rw_length += p_resp->len;
+    }
+
+    /* if read all of NDEF data */
+    if (p_i93->rw_length >= p_i93->ndef_length)
+    {
+        /* remove extra btyes in the last block */
+        p_resp->len -= (p_i93->rw_length - p_i93->ndef_length);
+
+        p_i93->state    = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+
+        RW_TRACE_DEBUG2 ("NDEF read complete read (%d)/total (%d)",
+                         p_resp->len,
+                         p_i93->ndef_length);
+
+        (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_CPLT_EVT, &rw_data);
+    }
+    else
+    {
+        RW_TRACE_DEBUG2 ("NDEF read segment read (%d)/total (%d)",
+                         p_resp->len,
+                         p_i93->ndef_length);
+
+        (*(rw_cb.p_cback)) (RW_I93_NDEF_READ_EVT, &rw_data);
+
+        /* this will make read data from next block */
+        p_i93->rw_offset += length;
+
+        if (rw_i93_get_next_blocks (p_i93->rw_offset) != NFC_STATUS_OK)
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_update_ndef
+**
+** Description      Process NDEF update procedure
+**
+**                  1. Set length field to zero
+**                  2. Write NDEF and Terminator TLV
+**                  3. Set length field to NDEF length
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_update_ndef (BT_HDR *p_resp)
+{
+    UINT8      *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
+    UINT8       flags, xx, length_offset, block_number, buff[I93_MAX_BLOCK_LENGH];
+    UINT16      length = p_resp->len;
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_i93_sm_update_ndef () sub_state:%s (0x%x)",
+                      rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_i93_sm_update_ndef () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+    STREAM_TO_UINT8 (flags, p);
+    length--;
+
+    if (flags & I93_FLAG_ERROR_DETECTED)
+    {
+        if (  (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+                                         &&
+              (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)  )
+        {
+            /* ignore error */
+        }
+        else
+        {
+            RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+    switch (p_i93->sub_state)
+    {
+    case RW_I93_SUBSTATE_RESET_LEN:
+
+        /* get offset of length field */
+        length_offset = (p_i93->ndef_tlv_start_offset + 1) % p_i93->block_size;
+
+        /* set length to zero */
+        *(p + length_offset) = 0x00;
+
+        if (p_i93->ndef_length > 0)
+        {
+            /* if 3 bytes length field is needed */
+            if (p_i93->ndef_length >= 0xFF)
+            {
+                xx = length_offset + 3;
+            }
+            else
+            {
+                xx = length_offset + 1;
+            }
+
+            /* write the first part of NDEF in the same block */
+            for ( ; xx < p_i93->block_size; xx++)
+            {
+                if (p_i93->rw_length < p_i93->ndef_length)
+                {
+                    *(p + xx) = *(p_i93->p_update_data + p_i93->rw_length++);
+                }
+                else
+                {
+                    *(p + xx) = I93_ICODE_TLV_TYPE_NULL;
+                }
+            }
+        }
+
+        block_number = (UINT8) ((p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size);
+
+        if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
+        {
+            /* update next writing offset */
+            p_i93->rw_offset = (block_number + 1) * p_i93->block_size;
+            p_i93->sub_state = RW_I93_SUBSTATE_WRITE_NDEF;
+        }
+        else
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WRITE_NDEF:
+
+        /* if it's not the end of tag memory */
+        if (p_i93->rw_offset < p_i93->block_size * p_i93->num_block)
+        {
+            block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+            /* if we have more data to write */
+            if (p_i93->rw_length < p_i93->ndef_length)
+            {
+                p = p_i93->p_update_data + p_i93->rw_length;
+
+                p_i93->rw_offset += p_i93->block_size;
+                p_i93->rw_length += p_i93->block_size;
+
+                /* if this is the last block of NDEF TLV */
+                if (p_i93->rw_length > p_i93->ndef_length)
+                {
+                    /* length of NDEF TLV in the block */
+                    xx = (UINT8) (p_i93->block_size - (p_i93->rw_length - p_i93->ndef_length));
+
+                    /* set NULL TLV in the unused part of block */
+                    memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
+                    memcpy (buff, p, xx);
+                    p = buff;
+
+                    /* if it's the end of tag memory */
+                    if (  (p_i93->rw_offset >= p_i93->block_size * p_i93->num_block)
+                        &&(xx < p_i93->block_size)  )
+                    {
+                        buff[xx] = I93_ICODE_TLV_TYPE_TERM;
+                    }
+
+                    p_i93->ndef_tlv_last_offset = p_i93->rw_offset - p_i93->block_size + xx - 1;
+                }
+
+                if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                }
+            }
+            else
+            {
+                /* if this is the very next block of NDEF TLV */
+                if (block_number == (p_i93->ndef_tlv_last_offset / p_i93->block_size) + 1)
+                {
+                    p_i93->rw_offset += p_i93->block_size;
+
+                    /* write Terminator TLV and NULL TLV */
+                    memset (buff, I93_ICODE_TLV_TYPE_NULL, p_i93->block_size);
+                    buff[0] = I93_ICODE_TLV_TYPE_TERM;
+                    p = buff;
+
+                    if (rw_i93_send_cmd_write_single_block (block_number, p) != NFC_STATUS_OK)
+                    {
+                        rw_i93_handle_error (NFC_STATUS_FAILED);
+                    }
+                }
+                else
+                {
+                    /* finished writing NDEF and Terminator TLV */
+                    /* read length field to update length       */
+                    block_number = (UINT8) ((p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size);
+
+                    if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
+                    {
+                        /* set offset to length field */
+                        p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
+
+                        /* get size of length field */
+                        if (p_i93->ndef_length >= 0xFF)
+                        {
+                            p_i93->rw_length = 3;
+                        }
+                        else if (p_i93->ndef_length > 0)
+                        {
+                            p_i93->rw_length = 1;
+                        }
+                        else
+                        {
+                            p_i93->rw_length = 0;
+                        }
+
+                        p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
+                    }
+                    else
+                    {
+                        rw_i93_handle_error (NFC_STATUS_FAILED);
+                    }
+                }
+            }
+        }
+        else
+        {
+            /* if we have no more data to write */
+            if (p_i93->rw_length >= p_i93->ndef_length)
+            {
+                /* finished writing NDEF and Terminator TLV */
+                /* read length field to update length       */
+                block_number = (UINT8) ((p_i93->ndef_tlv_start_offset + 1) / p_i93->block_size);
+
+                if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
+                {
+                    /* set offset to length field */
+                    p_i93->rw_offset = p_i93->ndef_tlv_start_offset + 1;
+
+                    /* get size of length field */
+                    if (p_i93->ndef_length >= 0xFF)
+                    {
+                        p_i93->rw_length = 3;
+                    }
+                    else if (p_i93->ndef_length > 0)
+                    {
+                        p_i93->rw_length = 1;
+                    }
+                    else
+                    {
+                        p_i93->rw_length = 0;
+                    }
+
+                    p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
+                    break;
+                }
+            }
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_UPDATE_LEN:
+
+        /* if we have more length field to write */
+        if (p_i93->rw_length > 0)
+        {
+            /* if we got ack for writing, read next block to update rest of length field */
+            if (length == 0)
+            {
+                block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+                if (rw_i93_send_cmd_read_single_block (block_number, FALSE) != NFC_STATUS_OK)
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                }
+            }
+            else
+            {
+                length_offset = p_i93->rw_offset % p_i93->block_size;
+
+                /* update length field within the read block */
+                for (xx = length_offset; xx < p_i93->block_size; xx++)
+                {
+                    if (p_i93->rw_length == 3)
+                        *(p + xx) = 0xFF;
+                    else if (p_i93->rw_length == 2)
+                        *(p + xx) = (UINT8) ((p_i93->ndef_length >> 8) & 0xFF);
+                    else if (p_i93->rw_length == 1)
+                        *(p + xx) = (UINT8) (p_i93->ndef_length & 0xFF);
+
+                    p_i93->rw_length--;
+                    if (p_i93->rw_length == 0)
+                        break;
+                }
+
+                block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+                if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
+                {
+                    /* set offset to the beginning of next block */
+                    p_i93->rw_offset += p_i93->block_size - (p_i93->rw_offset % p_i93->block_size);
+                }
+                else
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                }
+            }
+        }
+        else
+        {
+            RW_TRACE_DEBUG3 ("NDEF update complete, %d bytes, (%d-%d)",
+                             p_i93->ndef_length,
+                             p_i93->ndef_tlv_start_offset,
+                             p_i93->ndef_tlv_last_offset);
+
+            p_i93->state         = RW_I93_STATE_IDLE;
+            p_i93->sent_cmd      = 0;
+            p_i93->p_update_data = NULL;
+
+            rw_data.status = NFC_STATUS_OK;
+            (*(rw_cb.p_cback)) (RW_I93_NDEF_UPDATE_CPLT_EVT, &rw_data);
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_format
+**
+** Description      Process format procedure
+**
+**                  1. Get UID
+**                  2. Get sys info for memory size (reset AFI/DSFID)
+**                  3. Get block status to get read-only status
+**                  4. Write CC and empty NDEF
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_format (BT_HDR *p_resp)
+{
+    UINT8      *p = (UINT8 *) (p_resp + 1) + p_resp->offset, *p_uid;
+    UINT8       flags, u8 = 0, block_number;
+    UINT16      length = p_resp->len;
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    tRW_DATA    rw_data;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_i93_sm_format () sub_state:%s (0x%x)",
+                      rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_i93_sm_format () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+    STREAM_TO_UINT8 (flags, p);
+    length--;
+
+    if (flags & I93_FLAG_ERROR_DETECTED)
+    {
+        if (  (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+                                         &&
+              (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)  )
+        {
+            /* ignore error */
+        }
+        else
+        {
+            RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+    switch (p_i93->sub_state)
+    {
+    case RW_I93_SUBSTATE_WAIT_UID:
+
+        p++; /* skip DSFID */
+        p_uid = p_i93->uid;
+        STREAM_TO_ARRAY8 (p_uid, p);     /* store UID */
+
+        /* get system information to get memory size */
+        if (rw_i93_send_cmd_get_sys_info (NULL) == NFC_STATUS_OK)
+        {
+            p_i93->sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
+        }
+        else
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+
+        STREAM_TO_UINT8 (flags, p);  /* info_flags */
+        p_uid = p_i93->uid;
+        STREAM_TO_ARRAY8 (p_uid, p);  /* store UID */
+
+        if (flags & I93_INFO_FLAG_DSFID)
+        {
+            /* DSFID, if any DSFID then reset */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8 != I93_DFS_UNSUPPORTED)
+            {
+                p_i93->intl_flags |= RW_I93_FLAG_RESET_DSFID;
+            }
+        }
+        if (flags & I93_INFO_FLAG_AFI)
+        {
+            /* AFI, reset to 0 */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8 != 0x00)
+            {
+                p_i93->intl_flags |= RW_I93_FLAG_RESET_AFI;
+            }
+        }
+        if (flags & I93_INFO_FLAG_MEM_SIZE)
+        {
+            STREAM_TO_UINT8 (p_i93->num_block, p);
+            /* it is one less than actual number of bytes */
+            p_i93->num_block += 1;
+
+            STREAM_TO_UINT8 (p_i93->block_size, p);
+            /* it is one less than actual number of blocks */
+            p_i93->block_size = (p_i93->block_size & 0x1F) + 1;
+
+            status = NFC_STATUS_OK;
+        }
+        if (flags & I93_INFO_FLAG_IC_REF)
+        {
+            STREAM_TO_UINT8 (p_i93->ic_reference, p);
+
+            /* I-CODE SLI-L/SLIX-L */
+            if ((p_i93->product_version == RW_I93_ICODE_SLI_L) && (p_i93->ic_reference == I93_IC_REF_ICODE_SLI_L))
+            {
+                p_i93->num_block  = 8;
+                p_i93->block_size = 4;
+                status = NFC_STATUS_OK;
+            }
+        }
+
+        if (status != NFC_STATUS_OK)
+        {
+            RW_TRACE_DEBUG1 ("Unable to get tag memory size", u8);
+            rw_i93_handle_error (status);
+        }
+        else if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
+        {
+            if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
+        {
+            if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else
+        {
+            /* get lock status to see if read-only */
+            if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
+            {
+                /* these doesn't support GetMultiBlockSecurityStatus */
+
+                rw_cb.tcb.i93.rw_offset = 0;
+
+                /* read blocks with option flag to get block security status */
+                if (rw_i93_send_cmd_read_single_block (0x00, TRUE) == NFC_STATUS_OK)
+                {
+                    p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+                }
+                else
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                }
+            }
+            else if (rw_i93_send_cmd_get_multi_block_sec (0, p_i93->num_block) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+
+        break;
+
+    case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
+
+        if (p_i93->sent_cmd == I93_CMD_WRITE_DSFID)
+        {
+            p_i93->intl_flags &= ~RW_I93_FLAG_RESET_DSFID;
+        }
+        else if (p_i93->sent_cmd == I93_CMD_WRITE_AFI)
+        {
+            p_i93->intl_flags &= ~RW_I93_FLAG_RESET_AFI;
+        }
+
+        if (p_i93->intl_flags & RW_I93_FLAG_RESET_DSFID)
+        {
+            if (rw_i93_send_cmd_write_dsfid (I93_DFS_UNSUPPORTED) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else if (p_i93->intl_flags & RW_I93_FLAG_RESET_AFI)
+        {
+            if (rw_i93_send_cmd_write_afi (0x00) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else
+        {
+            /* get lock status to see if read-only */
+            if ((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))
+            {
+                /* these doesn't support GetMultiBlockSecurityStatus */
+
+                rw_cb.tcb.i93.rw_offset = 0;
+
+                /* read blocks with option flag to get block security status */
+                if (rw_i93_send_cmd_read_single_block (0x00, TRUE) == NFC_STATUS_OK)
+                {
+                    p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+                }
+                else
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                }
+            }
+            else if (rw_i93_send_cmd_get_multi_block_sec (0, p_i93->num_block) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        break;
+
+    case RW_I93_SUBSTATE_CHECK_READ_ONLY:
+
+        if (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+            ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)
+            ||((p_i93->uid[1] == I93_UID_IC_MFG_CODE_NXP) && (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK))  )
+        {
+            if ((*p) & I93_BLOCK_LOCKED)
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+                break;
+            }
+
+            /* if we checked all of user blocks */
+            if ((p_i93->rw_offset / p_i93->block_size) + 1 == p_i93->num_block)
+            {
+                if (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+                    ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+                {
+                    /* read the block which has AFI */
+                    p_i93->rw_offset = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
+                    rw_i93_send_cmd_read_single_block ((UINT8) (p_i93->rw_offset/p_i93->block_size), TRUE);
+                    break;
+                }
+            }
+            else if (p_i93->rw_offset == I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION)
+            {
+                /* no block is locked */
+            }
+            else
+            {
+                p_i93->rw_offset += p_i93->block_size;
+                rw_i93_send_cmd_read_single_block ((UINT8) (p_i93->rw_offset/p_i93->block_size), TRUE);
+                break;
+            }
+        }
+        else
+        {
+            /* if any block is locked, we cannot format it */
+            for (u8 = 0; u8 < p_i93->num_block; u8++)
+            {
+                if (*(p+u8) & I93_BLOCK_LOCKED)
+                {
+                    rw_i93_handle_error (NFC_STATUS_FAILED);
+                    break;
+                }
+            }
+        }
+
+        /* get buffer to store CC, zero length NDEF TLV and Terminator TLV */
+        p_i93->p_update_data = (UINT8*) GKI_getbuf (RW_I93_FORMAT_DATA_LEN);
+
+        if (!p_i93->p_update_data)
+        {
+            RW_TRACE_ERROR0 ("rw_i93_sm_format (): Cannot allocate buffer");
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+            break;
+        }
+
+        p = p_i93->p_update_data;
+
+        /* Capability Container */
+        *(p++) = I93_ICODE_CC_MAGIC_NUMER;                      /* magic number */
+        *(p++) = 0x40;                                          /* version 1.0, read/write */
+        *(p++) = (UINT8) ((p_i93->num_block * p_i93->block_size) / 8);    /* memory size */
+
+        if (  (p_i93->product_version == RW_I93_ICODE_SLI)
+            ||(p_i93->product_version == RW_I93_ICODE_SLI_S)
+            ||(p_i93->product_version == RW_I93_ICODE_SLI_L)  )
+        {
+            if (p_i93->ic_reference & I93_ICODE_IC_REF_MBREAD_MASK)
+                *(p++) = I93_ICODE_CC_IPREAD_MASK;  /* IPREAD */
+            else
+                *(p++) = I93_ICODE_CC_MBREAD_MASK;  /* MBREAD, read multi block command supported */
+        }
+        else if (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+                 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)  )
+        {
+            *(p++) = I93_ICODE_CC_MBREAD_MASK;      /* MBREAD, read multi block command supported */
+        }
+        else if (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+                 ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+        {
+            *(p++) = 0;
+        }
+        else
+        {
+            *(p++) = I93_ICODE_CC_MBREAD_MASK;      /* Broadcom supports read multi block command */
+        }
+
+        /* zero length NDEF and Terminator TLV */
+        *(p++) = I93_ICODE_TLV_TYPE_NDEF;
+        *(p++) = 0x00;
+        *(p++) = I93_ICODE_TLV_TYPE_TERM;
+        *(p++) = I93_ICODE_TLV_TYPE_NULL;
+
+        /* start from block 0 */
+        p_i93->rw_offset = 0;
+
+        if (rw_i93_send_cmd_write_single_block (0, p_i93->p_update_data) == NFC_STATUS_OK)
+        {
+            p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
+            p_i93->rw_offset += p_i93->block_size;
+        }
+        else
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
+
+        /* if we have more data to write */
+        if (p_i93->rw_offset < RW_I93_FORMAT_DATA_LEN)
+        {
+            block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+            p = p_i93->p_update_data + p_i93->rw_offset;
+
+            if (rw_i93_send_cmd_write_single_block (block_number, p) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV;
+                p_i93->rw_offset += p_i93->block_size;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else
+        {
+            GKI_freebuf (p_i93->p_update_data);
+            p_i93->p_update_data = NULL;
+
+            p_i93->state = RW_I93_STATE_IDLE;
+            p_i93->sent_cmd = 0;
+
+            rw_data.status = NFC_STATUS_OK;
+            (*(rw_cb.p_cback)) (RW_I93_FORMAT_CPLT_EVT, &rw_data);
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_sm_set_read_only
+**
+** Description      Process read-only procedure
+**
+**                  1. Update CC as read-only
+**                  2. Lock all block of NDEF TLV
+**                  3. Lock block of CC
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_i93_sm_set_read_only (BT_HDR *p_resp)
+{
+    UINT8      *p = (UINT8 *) (p_resp + 1) + p_resp->offset;
+    UINT8       flags, block_number;
+    UINT16      length = p_resp->len;
+    tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_i93_sm_set_read_only () sub_state:%s (0x%x)",
+                      rw_i93_get_sub_state_name (p_i93->sub_state), p_i93->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_i93_sm_set_read_only () sub_state:0x%x", p_i93->sub_state);
+#endif
+
+    STREAM_TO_UINT8 (flags, p);
+    length--;
+
+    if (flags & I93_FLAG_ERROR_DETECTED)
+    {
+        if (  (  (p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_INLAY)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PLUS_CHIP)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+               ||(p_i93->product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+                                         &&
+              (*p == I93_ERROR_CODE_BLOCK_FAIL_TO_WRITE)  )
+        {
+            /* ignore error */
+        }
+        else
+        {
+            RW_TRACE_DEBUG1 ("Got error flags (0x%02x)", flags);
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+            return;
+        }
+    }
+
+    switch (p_i93->sub_state)
+    {
+    case RW_I93_SUBSTATE_WAIT_CC:
+
+        /* mark CC as read-only */
+        *(p+1) |= I93_ICODE_CC_READ_ONLY;
+
+        if (rw_i93_send_cmd_write_single_block (0, p) == NFC_STATUS_OK)
+        {
+            p_i93->sub_state = RW_I93_SUBSTATE_WAIT_UPDATE_CC;
+        }
+        else
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
+
+        /* successfully write CC then lock all blocks of NDEF TLV */
+        p_i93->rw_offset = p_i93->ndef_tlv_start_offset;
+        block_number     = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+        if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
+        {
+            p_i93->rw_offset += p_i93->block_size;
+            p_i93->sub_state = RW_I93_SUBSTATE_LOCK_NDEF_TLV;
+        }
+        else
+        {
+            rw_i93_handle_error (NFC_STATUS_FAILED);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
+
+        /* if we need to lock more blocks */
+        if (p_i93->rw_offset < p_i93->ndef_tlv_last_offset)
+        {
+            /* get the next block of NDEF TLV */
+            block_number = (UINT8) (p_i93->rw_offset / p_i93->block_size);
+
+            if (rw_i93_send_cmd_lock_block (block_number) == NFC_STATUS_OK)
+            {
+                p_i93->rw_offset += p_i93->block_size;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        /* if the first block of NDEF TLV is different from block of CC */
+        else if (p_i93->ndef_tlv_start_offset / p_i93->block_size != 0)
+        {
+            /* lock block of CC */
+            if (rw_i93_send_cmd_lock_block (0) == NFC_STATUS_OK)
+            {
+                p_i93->sub_state = RW_I93_SUBSTATE_WAIT_LOCK_CC;
+            }
+            else
+            {
+                rw_i93_handle_error (NFC_STATUS_FAILED);
+            }
+        }
+        else
+        {
+            p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+            p_i93->state       = RW_I93_STATE_IDLE;
+            p_i93->sent_cmd    = 0;
+
+            rw_data.status = NFC_STATUS_OK;
+            (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
+        }
+        break;
+
+    case RW_I93_SUBSTATE_WAIT_LOCK_CC:
+
+        p_i93->intl_flags |= RW_I93_FLAG_READ_ONLY;
+        p_i93->state      = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd   = 0;
+
+        rw_data.status = NFC_STATUS_OK;
+        (*(rw_cb.p_cback)) (RW_I93_SET_TAG_RO_EVT, &rw_data);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_handle_error
+**
+** Description      notify error to application and clean up
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_i93_handle_error (tNFC_STATUS status)
+{
+    tRW_I93_CB *p_i93  = &rw_cb.tcb.i93;
+    tRW_DATA    rw_data;
+    tRW_EVENT   event;
+
+    RW_TRACE_DEBUG2 ("rw_i93_handle_error (): status:0x%02X, state:0x%X",
+                      status, p_i93->state);
+
+    nfc_stop_quick_timer (&p_i93->timer);
+
+    if (rw_cb.p_cback)
+    {
+        rw_data.status = status;
+
+        switch (p_i93->state)
+        {
+        case RW_I93_STATE_IDLE:   /* in case of RawFrame */
+            event = RW_I93_INTF_ERROR_EVT;
+            break;
+
+        case RW_I93_STATE_BUSY:
+            if (p_i93->sent_cmd == I93_CMD_STAY_QUIET)
+            {
+                /* There is no response to Stay Quiet command */
+                rw_data.i93_cmd_cmpl.status     = NFC_STATUS_OK;
+                rw_data.i93_cmd_cmpl.command    = I93_CMD_STAY_QUIET;
+                rw_data.i93_cmd_cmpl.error_code = 0;
+                event = RW_I93_CMD_CMPL_EVT;
+            }
+            else
+            {
+                event = RW_I93_INTF_ERROR_EVT;
+            }
+            break;
+
+        case RW_I93_STATE_DETECT_NDEF:
+            rw_data.ndef.protocol = NFC_PROTOCOL_15693;
+            rw_data.ndef.cur_size = 0;
+            rw_data.ndef.max_size = 0;
+            rw_data.ndef.flags    = 0;
+            rw_data.ndef.flags   |= RW_NDEF_FL_FORMATABLE;
+            rw_data.ndef.flags   |= RW_NDEF_FL_UNKNOWN;
+            event = RW_I93_NDEF_DETECT_EVT;
+            break;
+
+        case RW_I93_STATE_READ_NDEF:
+            event = RW_I93_NDEF_READ_FAIL_EVT;
+            break;
+
+        case RW_I93_STATE_UPDATE_NDEF:
+            p_i93->p_update_data = NULL;
+            event = RW_I93_NDEF_UPDATE_FAIL_EVT;
+            break;
+
+        case RW_I93_STATE_FORMAT:
+            if (p_i93->p_update_data)
+            {
+                GKI_freebuf (p_i93->p_update_data);
+                p_i93->p_update_data = NULL;
+            }
+            event = RW_I93_FORMAT_CPLT_EVT;
+            break;
+
+        case RW_I93_STATE_SET_READ_ONLY:
+            event = RW_I93_SET_TAG_RO_EVT;
+            break;
+
+        case RW_I93_STATE_PRESENCE_CHECK:
+            event = RW_I93_PRESENCE_CHECK_EVT;
+            break;
+
+        default:
+            event = RW_I93_MAX_EVT;
+            break;
+        }
+
+        p_i93->state    = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+
+        if (event != RW_I93_MAX_EVT)
+        {
+            (*(rw_cb.p_cback)) (event, &rw_data);
+        }
+    }
+    else
+    {
+        p_i93->state = RW_I93_STATE_IDLE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_i93_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    RW_TRACE_DEBUG1 ("rw_i93_process_timeout () event=%d", p_tle->event);
+
+    if (p_tle->event == NFC_TTYPE_RW_I93_RESPONSE)
+    {
+        rw_i93_handle_error (NFC_STATUS_TIMEOUT);
+    }
+    else
+    {
+        RW_TRACE_ERROR1 ("rw_i93_process_timeout () unknown event=%d", p_tle->event);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_i93_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tRW_I93_CB *p_i93  = &rw_cb.tcb.i93;
+    BT_HDR     *p_resp = (BT_HDR *) p_data->data.p_data;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    UINT8  begin_state   = p_i93->state;
+#endif
+
+    RW_TRACE_DEBUG1 ("rw_i93_data_cback () event = 0x%X", event);
+
+    if (  (event == NFC_DEACTIVATE_CEVT)
+        ||(event == NFC_ERROR_CEVT)  )
+    {
+        nfc_stop_quick_timer (&p_i93->timer);
+
+        if (event == NFC_ERROR_CEVT)
+        {
+            rw_i93_handle_error ((tNFC_STATUS) (*(UINT8*) p_data));
+        }
+        else
+        {
+            NFC_SetStaticRfCback (NULL);
+            p_i93->state = RW_I93_STATE_NOT_ACTIVATED;
+        }
+        return;
+    }
+
+    if (event != NFC_DATA_CEVT)
+    {
+        return;
+    }
+
+    nfc_stop_quick_timer (&p_i93->timer);
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispRWI93Tag (p_resp, TRUE, p_i93->sent_cmd);
+#endif
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("RW I93 state: <%s (%d)>",
+                        rw_i93_get_state_name (p_i93->state), p_i93->state);
+#else
+    RW_TRACE_DEBUG1 ("RW I93 state: %d", p_i93->state);
+#endif
+
+    switch (p_i93->state)
+    {
+    case RW_I93_STATE_IDLE:
+        /* Unexpected Response from VICC, it should be raw frame response */
+        /* forward to upper layer without parsing */
+        p_i93->sent_cmd = 0;
+        if (rw_cb.p_cback)
+        {
+            rw_data.raw_frame.status = NFC_STATUS_OK;
+            rw_data.raw_frame.p_data = p_resp;
+            (*(rw_cb.p_cback)) (RW_I93_RAW_FRAME_EVT, &rw_data);
+            p_resp = NULL;
+        }
+        else
+        {
+            GKI_freebuf (p_resp);
+        }
+        break;
+    case RW_I93_STATE_BUSY:
+        p_i93->state = RW_I93_STATE_IDLE;
+        rw_i93_send_to_upper (p_resp);
+        GKI_freebuf (p_resp);
+        break;
+
+    case RW_I93_STATE_DETECT_NDEF:
+        rw_i93_sm_detect_ndef (p_resp);
+        GKI_freebuf (p_resp);
+        break;
+
+    case RW_I93_STATE_READ_NDEF:
+        rw_i93_sm_read_ndef (p_resp);
+        /* p_resp may send upper lyaer */
+        break;
+
+    case RW_I93_STATE_UPDATE_NDEF:
+        rw_i93_sm_update_ndef (p_resp);
+        GKI_freebuf (p_resp);
+        break;
+
+    case RW_I93_STATE_FORMAT:
+        rw_i93_sm_format (p_resp);
+        GKI_freebuf (p_resp);
+        break;
+
+    case RW_I93_STATE_SET_READ_ONLY:
+        rw_i93_sm_set_read_only (p_resp);
+        GKI_freebuf (p_resp);
+        break;
+
+    case RW_I93_STATE_PRESENCE_CHECK:
+        p_i93->state    = RW_I93_STATE_IDLE;
+        p_i93->sent_cmd = 0;
+
+        /* if any response, send presence check with ok */
+        rw_data.status  = NFC_STATUS_OK;
+        (*(rw_cb.p_cback)) (RW_I93_PRESENCE_CHECK_EVT, &rw_data);
+        GKI_freebuf (p_resp);
+        break;
+
+    default:
+        RW_TRACE_ERROR1 ("rw_i93_data_cback (): invalid state=%d", p_i93->state);
+        GKI_freebuf (p_resp);
+        break;
+    }
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    if (begin_state != p_i93->state)
+    {
+        RW_TRACE_DEBUG2 ("RW I93 state changed:<%s> -> <%s>",
+                          rw_i93_get_state_name (begin_state),
+                          rw_i93_get_state_name (p_i93->state));
+    }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_select
+**
+** Description      Initialise ISO 15693 RW
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS rw_i93_select (void)
+{
+    tRW_I93_CB  *p_i93 = &rw_cb.tcb.i93;
+
+    RW_TRACE_DEBUG0 ("rw_i93_select ()");
+
+    NFC_SetStaticRfCback (rw_i93_data_cback);
+
+    p_i93->state = RW_I93_STATE_IDLE;
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93Inventory
+**
+** Description      This function send Inventory command
+**                  If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93Inventory (UINT8 afi, UINT8 *p_uid)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API1 ("RW_I93Inventory (), AFI:0x%02X", afi);
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93Inventory ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    if (p_uid)
+    {
+        status = rw_i93_send_cmd_inventory (p_uid, afi);
+    }
+    else
+    {
+        status = rw_i93_send_cmd_inventory (NULL, afi);
+    }
+
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93StayQuiet
+**
+** Description      This function send Inventory command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93StayQuiet (void)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93StayQuiet ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93StayQuiet ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_stay_quiet ();
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadSingleBlock
+**
+** Description      This function send Read Single Block command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadSingleBlock (UINT8 block_number)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API1 ("RW_I93ReadSingleBlock () block_number:0x%02X", block_number);
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93ReadSingleBlock ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_read_single_block (block_number, FALSE);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteSingleBlock
+**
+** Description      This function send Write Single Block command
+**                  Application must get block size first by calling RW_I93GetSysInfo().
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteSingleBlock (UINT8 block_number,
+                                    UINT8 *p_data)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93WriteSingleBlock ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93WriteSingleBlock ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    if (rw_cb.tcb.i93.block_size == 0)
+    {
+        RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
+        return NFC_STATUS_FAILED;
+    }
+
+    status = rw_i93_send_cmd_write_single_block (block_number, p_data);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93LockBlock
+**
+** Description      This function send Lock Block command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockBlock (UINT8 block_number)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93LockBlock ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93LockBlock ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_lock_block (block_number);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadMultipleBlocks
+**
+** Description      This function send Read Multiple Blocks command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadMultipleBlocks (UINT8  first_block_number,
+                                      UINT16 number_blocks)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93ReadMultipleBlocks ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93ReadMultipleBlocks ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_read_multi_blocks (first_block_number, number_blocks);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteMultipleBlocks
+**
+** Description      This function send Write Multiple Blocks command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteMultipleBlocks (UINT8  first_block_number,
+                                       UINT16 number_blocks,
+                                       UINT8  *p_data)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93WriteMultipleBlocks ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93WriteMultipleBlocks ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    if (rw_cb.tcb.i93.block_size == 0)
+    {
+        RW_TRACE_ERROR0 ("RW_I93WriteSingleBlock ():Block size is unknown");
+        return NFC_STATUS_FAILED;
+    }
+
+    status = rw_i93_send_cmd_write_multi_blocks (first_block_number, number_blocks, p_data);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93Select
+**
+** Description      This function send Select command
+**
+**                  UID[0]: 0xE0, MSB
+**                  UID[1]: IC Mfg Code
+**                  ...
+**                  UID[7]: LSB
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93Select (UINT8 *p_uid)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93Select ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93Select ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    if (p_uid)
+    {
+        status = rw_i93_send_cmd_select (p_uid);
+        if (status == NFC_STATUS_OK)
+        {
+            rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+        }
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("RW_I93Select ():UID shall be provided");
+        status = NFC_STATUS_FAILED;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ResetToReady
+**
+** Description      This function send Reset To Ready command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ResetToReady (void)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93ResetToReady ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93ResetToReady ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_reset_to_ready ();
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteAFI
+**
+** Description      This function send Write AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteAFI (UINT8 afi)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93WriteAFI ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93WriteAFI ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_write_afi (afi);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93LockAFI
+**
+** Description      This function send Lock AFI command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockAFI (void)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93LockAFI ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93LockAFI ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_lock_afi ();
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93WriteDSFID
+**
+** Description      This function send Write DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93WriteDSFID (UINT8 dsfid)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93WriteDSFID ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93WriteDSFID ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_write_dsfid (dsfid);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93LockDSFID
+**
+** Description      This function send Lock DSFID command
+**
+**                  RW_I93_CMD_CMPL_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93LockDSFID (void)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93LockDSFID ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93LockDSFID ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_lock_dsfid ();
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93GetSysInfo
+**
+** Description      This function send Get System Information command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93GetSysInfo (UINT8 *p_uid)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93GetSysInfo ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93GetSysInfo ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    if (p_uid)
+    {
+        status = rw_i93_send_cmd_get_sys_info (p_uid);
+    }
+    else
+    {
+        status = rw_i93_send_cmd_get_sys_info (NULL);
+    }
+
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93GetMultiBlockSecurityStatus
+**
+** Description      This function send Get Multiple Block Security Status command
+**
+**                  RW_I93_RESPONSE_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_NO_BUFFERS if out of buffer
+**                  NFC_STATUS_BUSY if busy
+**                  NFC_STATUS_FAILED if other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93GetMultiBlockSecurityStatus (UINT8  first_block_number,
+                                               UINT16 number_blocks)
+{
+    tNFC_STATUS status;
+
+    RW_TRACE_API0 ("RW_I93GetMultiBlockSecurityStatus ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93GetMultiBlockSecurityStatus ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_BUSY;
+    }
+
+    status = rw_i93_send_cmd_get_multi_block_sec (first_block_number, number_blocks);
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state = RW_I93_STATE_BUSY;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93DetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_I93_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93DetectNDef (void)
+{
+    tNFC_STATUS status;
+    tRW_I93_RW_SUBSTATE sub_state;
+
+    RW_TRACE_API0 ("RW_I93DetectNDef ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93DetectNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    if (rw_cb.tcb.i93.uid[0] != I93_UID_FIRST_BYTE)
+    {
+        status = rw_i93_send_cmd_inventory (NULL, 0x00);
+        sub_state = RW_I93_SUBSTATE_WAIT_UID;
+    }
+    else if (  (rw_cb.tcb.i93.num_block == 0)
+             ||(rw_cb.tcb.i93.block_size == 0)  )
+    {
+        status = rw_i93_send_cmd_get_sys_info (rw_cb.tcb.i93.uid);
+        sub_state = RW_I93_SUBSTATE_WAIT_SYS_INFO;
+    }
+    else
+    {
+        /* read CC in the first block */
+        status = rw_i93_send_cmd_read_single_block (0x00, FALSE);
+        sub_state = RW_I93_SUBSTATE_WAIT_CC;
+    }
+
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state      = RW_I93_STATE_DETECT_NDEF;
+        rw_cb.tcb.i93.sub_state  = sub_state;
+        rw_cb.tcb.i93.intl_flags = 0;
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93ReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_I93DetectNDef () must be called before using this
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_I93_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+**                      RW_I93_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93ReadNDef (void)
+{
+    RW_TRACE_API0 ("RW_I93ReadNDef ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93ReadNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    if (  (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
+        &&(rw_cb.tcb.i93.ndef_length > 0)  )
+    {
+        rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset;
+        rw_cb.tcb.i93.rw_length = 0;
+
+        if (rw_i93_get_next_blocks (rw_cb.tcb.i93.rw_offset) == NFC_STATUS_OK)
+        {
+            rw_cb.tcb.i93.state = RW_I93_STATE_READ_NDEF;
+        }
+        else
+        {
+            return NFC_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
+        return NFC_STATUS_FAILED;
+    }
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93UpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_I93DetectNDef () must be called before using this
+**                        Updating data must not be removed until returning event
+**
+**                  The following event will be returned
+**                      RW_I93_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_I93_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93UpdateNDef (UINT16 length, UINT8 *p_data)
+{
+    UINT8 block_number;
+
+    RW_TRACE_API1 ("RW_I93UpdateNDef () length:%d", length);
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93UpdateNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
+    {
+        if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
+        {
+            RW_TRACE_ERROR0 ("RW_I93UpdateNDef ():NDEF is read-only");
+            return NFC_STATUS_FAILED;
+        }
+        if (rw_cb.tcb.i93.max_ndef_length < length)
+        {
+            RW_TRACE_ERROR2 ("RW_I93UpdateNDef ():data (%d bytes) is more than max NDEF length (%d)",
+                              length, rw_cb.tcb.i93.max_ndef_length);
+            return NFC_STATUS_FAILED;
+        }
+
+        rw_cb.tcb.i93.ndef_length   = length;
+        rw_cb.tcb.i93.p_update_data = p_data;
+
+        /* read length field */
+        rw_cb.tcb.i93.rw_offset = rw_cb.tcb.i93.ndef_tlv_start_offset + 1;
+        rw_cb.tcb.i93.rw_length = 0;
+
+        block_number = (UINT8) (rw_cb.tcb.i93.rw_offset / rw_cb.tcb.i93.block_size);
+
+        if (rw_i93_send_cmd_read_single_block (block_number, FALSE) == NFC_STATUS_OK)
+        {
+            rw_cb.tcb.i93.state     = RW_I93_STATE_UPDATE_NDEF;
+            rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_RESET_LEN;
+        }
+        else
+        {
+            return NFC_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("RW_I93ReadNDef ():No NDEF detected");
+        return NFC_STATUS_FAILED;
+    }
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93FormatNDef
+**
+** Description      This function performs formatting procedure
+**
+**                  RW_I93_FORMAT_CPLT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93FormatNDef (void)
+{
+    tNFC_STATUS status;
+    tRW_I93_RW_SUBSTATE sub_state;
+
+    RW_TRACE_API0 ("RW_I93FormatNDef ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93FormatNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    if (  (rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_STD_CHIP_INLAY)
+        ||(rw_cb.tcb.i93.product_version == RW_I93_TAG_IT_HF_I_PRO_CHIP_INLAY)  )
+    {
+        /* These don't support GetSystemInformation and GetMultiBlockSecurityStatus */
+        rw_cb.tcb.i93.rw_offset = 0;
+
+        /* read blocks with option flag to get block security status */
+        status = rw_i93_send_cmd_read_single_block (0x00, TRUE);
+        sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+    }
+    else
+    {
+        status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, 0x00);
+        sub_state = RW_I93_SUBSTATE_WAIT_UID;
+    }
+
+    if (status == NFC_STATUS_OK)
+    {
+        rw_cb.tcb.i93.state      = RW_I93_STATE_FORMAT;
+        rw_cb.tcb.i93.sub_state  = sub_state;
+        rw_cb.tcb.i93.intl_flags = 0;
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_I93SetTagReadOnly
+**
+** Description      This function performs NDEF read-only procedure
+**                  Note: RW_I93DetectNDef () must be called before using this
+**                        Updating data must not be removed until returning event
+**
+**                  The RW_I93_SET_TAG_RO_EVT event will be returned.
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if I93 is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_I93SetTagReadOnly (void)
+{
+    RW_TRACE_API0 ("RW_I93SetTagReadOnly ()");
+
+    if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_I93SetTagReadOnly ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.i93.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    if (rw_cb.tcb.i93.tlv_type == I93_ICODE_TLV_TYPE_NDEF)
+    {
+        if (rw_cb.tcb.i93.intl_flags & RW_I93_FLAG_READ_ONLY)
+        {
+            RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():NDEF is already read-only");
+            return NFC_STATUS_FAILED;
+        }
+
+        /* get CC in the first block */
+        if (rw_i93_send_cmd_read_single_block (0, FALSE) == NFC_STATUS_OK)
+        {
+            rw_cb.tcb.i93.state     = RW_I93_STATE_SET_READ_ONLY;
+            rw_cb.tcb.i93.sub_state = RW_I93_SUBSTATE_WAIT_CC;
+        }
+        else
+        {
+            return NFC_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("RW_I93SetTagReadOnly ():No NDEF detected");
+        return NFC_STATUS_FAILED;
+    }
+
+    return NFC_STATUS_OK;
+}
+
+/*****************************************************************************
+**
+** Function         RW_I93PresenceCheck
+**
+** Description      Check if the tag is still in the field.
+**
+**                  The RW_I93_PRESENCE_CHECK_EVT w/ status is used to indicate
+**                  presence or non-presence.
+**
+** Returns          NFC_STATUS_OK, if raw data frame sent
+**                  NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**                  NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_I93PresenceCheck (void)
+{
+
+    tNFC_STATUS status;
+    tRW_DATA    evt_data;
+
+    RW_TRACE_API0 ("RW_I93PresenceCheck ()");
+
+    if (!rw_cb.p_cback)
+    {
+        return NFC_STATUS_FAILED;
+    }
+    else if (rw_cb.tcb.i93.state == RW_I93_STATE_NOT_ACTIVATED)
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+        (*rw_cb.p_cback) (RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
+
+        return NFC_STATUS_OK;
+    }
+    else if (rw_cb.tcb.i93.state != RW_I93_STATE_IDLE)
+    {
+        return NFC_STATUS_BUSY;
+    }
+    else
+    {
+        status = rw_i93_send_cmd_inventory (rw_cb.tcb.i93.uid, 0x00);
+
+        if (status == NFC_STATUS_OK)
+        {
+            rw_cb.tcb.i93.state = RW_I93_STATE_PRESENCE_CHECK;
+        }
+    }
+
+    return (status);
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         rw_i93_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_i93_get_state_name (UINT8 state)
+{
+    switch (state)
+    {
+    case RW_I93_STATE_NOT_ACTIVATED:
+        return ("NOT_ACTIVATED");
+    case RW_I93_STATE_IDLE:
+        return ("IDLE");
+    case RW_I93_STATE_BUSY:
+        return ("BUSY");
+
+    case RW_I93_STATE_DETECT_NDEF:
+        return ("NDEF_DETECTION");
+    case RW_I93_STATE_READ_NDEF:
+        return ("READ_NDEF");
+    case RW_I93_STATE_UPDATE_NDEF:
+        return ("UPDATE_NDEF");
+    case RW_I93_STATE_FORMAT:
+        return ("FORMAT");
+    case RW_I93_STATE_SET_READ_ONLY:
+        return ("SET_READ_ONLY");
+
+    case RW_I93_STATE_PRESENCE_CHECK:
+        return ("PRESENCE_CHECK");
+    default:
+        return ("???? UNKNOWN STATE");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_i93_get_sub_state_name
+**
+** Description      This function returns the sub_state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_i93_get_sub_state_name (UINT8 sub_state)
+{
+    switch (sub_state)
+    {
+    case RW_I93_SUBSTATE_WAIT_UID:
+        return ("WAIT_UID");
+    case RW_I93_SUBSTATE_WAIT_SYS_INFO:
+        return ("WAIT_SYS_INFO");
+    case RW_I93_SUBSTATE_WAIT_CC:
+        return ("WAIT_CC");
+    case RW_I93_SUBSTATE_SEARCH_NDEF_TLV:
+        return ("SEARCH_NDEF_TLV");
+    case RW_I93_SUBSTATE_CHECK_LOCK_STATUS:
+        return ("CHECK_LOCK_STATUS");
+    case RW_I93_SUBSTATE_RESET_LEN:
+        return ("RESET_LEN");
+    case RW_I93_SUBSTATE_WRITE_NDEF:
+        return ("WRITE_NDEF");
+    case RW_I93_SUBSTATE_UPDATE_LEN:
+        return ("UPDATE_LEN");
+    case RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI:
+        return ("WAIT_RESET_DSFID_AFI");
+    case RW_I93_SUBSTATE_CHECK_READ_ONLY:
+        return ("CHECK_READ_ONLY");
+    case RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV:
+        return ("WRITE_CC_NDEF_TLV");
+    case RW_I93_SUBSTATE_WAIT_UPDATE_CC:
+        return ("WAIT_UPDATE_CC");
+    case RW_I93_SUBSTATE_LOCK_NDEF_TLV:
+        return ("LOCK_NDEF_TLV");
+    case RW_I93_SUBSTATE_WAIT_LOCK_CC:
+        return ("WAIT_LOCK_CC");
+    default:
+        return ("???? UNKNOWN SUBSTATE");
+    }
+}
+#endif
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_main.c b/src/nfc/tags/rw_main.c
new file mode 100644
index 0000000..fe42d78
--- /dev/null
+++ b/src/nfc/tags/rw_main.c
@@ -0,0 +1,301 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains functions that interface with the NFC NCI transport.
+ *  On the receive side, it routes events to the appropriate handler
+ *  (callback). On the transmit side, it manages the command transmission.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+
+tRW_CB rw_cb;
+/*******************************************************************************
+*******************************************************************************/
+void rw_init (void)
+{
+    memset (&rw_cb, 0, sizeof (tRW_CB));
+    rw_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
+
+}
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+/*******************************************************************************
+* Internal functions for statistics
+*******************************************************************************/
+/*******************************************************************************
+**
+** Function         rw_main_reset_stats
+**
+** Description      Reset counters for statistics
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_reset_stats (void)
+{
+    memset (&rw_cb.stats, 0, sizeof (tRW_STATS));
+
+    /* Get current tick count */
+    rw_cb.stats.start_tick = GKI_get_tick_count ();
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_tx_stats
+**
+** Description      Update stats for tx
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_tx_stats (UINT32 num_bytes, BOOLEAN is_retry)
+{
+    rw_cb.stats.bytes_sent+=num_bytes;
+    rw_cb.stats.num_ops++;
+
+    if (is_retry)
+        rw_cb.stats.num_retries++;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_fail_stats
+**
+** Description      Increment failure count
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_fail_stats (void)
+{
+    rw_cb.stats.num_fail++;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_crc_error_stats
+**
+** Description      Increment crc error count
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_crc_error_stats (void)
+{
+    rw_cb.stats.num_crc++;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_trans_error_stats
+**
+** Description      Increment trans error count
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_trans_error_stats (void)
+{
+    rw_cb.stats.num_trans_err++;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_update_rx_stats
+**
+** Description      Update stats for rx
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_update_rx_stats (UINT32 num_bytes)
+{
+    rw_cb.stats.bytes_received+=num_bytes;
+}
+
+/*******************************************************************************
+**
+** Function         rw_main_log_stats
+**
+** Description      Dump stats
+**
+** Returns          void
+**
+*******************************************************************************/
+void rw_main_log_stats (void)
+{
+    UINT32 ticks, elapsed_ms;
+
+    ticks = GKI_get_tick_count () - rw_cb.stats.start_tick;
+    elapsed_ms = GKI_TICKS_TO_MS (ticks);
+
+    RW_TRACE_DEBUG5 ("NFC tx stats: cmds:%i, retries:%i, aborted: %i, tx_errs: %i, bytes sent:%i", rw_cb.stats.num_ops, rw_cb.stats.num_retries, rw_cb.stats.num_fail, rw_cb.stats.num_trans_err, rw_cb.stats.bytes_sent);
+    RW_TRACE_DEBUG2 ("    rx stats: rx-crc errors %i, bytes received: %i", rw_cb.stats.num_crc, rw_cb.stats.bytes_received);
+    RW_TRACE_DEBUG1 ("    time activated %i ms", elapsed_ms);
+}
+#endif  /* RW_STATS_INCLUDED */
+
+
+/*******************************************************************************
+**
+** Function         RW_SendRawFrame
+**
+** Description      This function sends a raw frame to the peer device.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_SendRawFrame (UINT8 *p_raw_data, UINT16 data_len)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    BT_HDR  *p_data;
+    UINT8   *p;
+
+    if (rw_cb.p_cback)
+    {
+        /* a valid opcode for RW - remove */
+        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+        if (p_data)
+        {
+            p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p = (UINT8 *) (p_data + 1) + p_data->offset;
+            memcpy (p, p_raw_data, data_len);
+            p_data->len = data_len;
+
+            RW_TRACE_EVENT1 ("RW SENT raw frame (0x%x)", data_len);
+            status = NFC_SendData (NFC_RF_CONN_ID, p_data);
+        }
+
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_SetActivatedTagType
+**
+** Description      This function selects the tag type for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_SetActivatedTagType (tNFC_ACTIVATE_DEVT *p_activate_params, tRW_CBACK *p_cback)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    /* check for null cback here / remove checks from rw_t?t */
+    RW_TRACE_DEBUG3 ("RW_SetActivatedTagType protocol:%d, technology:%d, SAK:%d", p_activate_params->protocol, p_activate_params->rf_tech_param.mode, p_activate_params->rf_tech_param.param.pa.sel_rsp);
+
+    if (p_cback == NULL)
+    {
+        RW_TRACE_ERROR0 ("RW_SetActivatedTagType called with NULL callback");
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Reset tag-specific area of control block */
+    memset (&rw_cb.tcb, 0, sizeof (tRW_TCB));
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Reset RW stats */
+    rw_main_reset_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+    rw_cb.p_cback = p_cback;
+    switch (p_activate_params->protocol)
+    {
+    /* not a tag NFC_PROTOCOL_NFCIP1:   NFCDEP/LLCP - NFC-A or NFC-F */
+    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
+        if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)
+        {
+            status = rw_t1t_select (p_activate_params->intf_param.intf_param.frame.param,
+                                    p_activate_params->rf_tech_param.param.pa.nfcid1);
+        }
+        break;
+
+    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
+        if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)
+        {
+            if (p_activate_params->rf_tech_param.param.pa.sel_rsp == NFC_SEL_RES_NFC_FORUM_T2T)
+                status      = rw_t2t_select ();
+        }
+        break;
+
+    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
+        if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F)
+        {
+            status = rw_t3t_select (p_activate_params->rf_tech_param.param.pf.nfcid2,
+                                    p_activate_params->rf_tech_param.param.pf.mrti_check,
+                                    p_activate_params->rf_tech_param.param.pf.mrti_update);
+        }
+        break;
+
+    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
+        if (  (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B)
+            ||(p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)  )
+        {
+            status          = rw_t4t_select ();
+        }
+        break;
+
+    case NFC_PROTOCOL_15693:     /* ISO 15693 */
+        if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_ISO15693)
+        {
+            status          = rw_i93_select ();
+        }
+        break;
+    /* TODO set up callback for proprietary protocol */
+
+    default:
+        RW_TRACE_ERROR0 ("RW_SetActivatedTagType Invalid protocol");
+    }
+
+    if (status != NFC_STATUS_OK)
+        rw_cb.p_cback = NULL;
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_SetTraceLevel
+**
+** Description      This function sets the trace level for Reader/Writer mode.
+**                  If called with a value of 0xFF,
+**                  it simply returns the current trace level.
+**
+** Returns          The new or current trace level
+**
+*******************************************************************************/
+UINT8 RW_SetTraceLevel (UINT8 new_level)
+{
+    if (new_level != 0xFF)
+        rw_cb.trace_level = new_level;
+
+    return (rw_cb.trace_level);
+}
+
+#endif /* NFC_INCLUDED == TRUE */
diff --git a/src/nfc/tags/rw_t1t.c b/src/nfc/tags/rw_t1t.c
new file mode 100644
index 0000000..0d98546
--- /dev/null
+++ b/src/nfc/tags/rw_t1t.c
@@ -0,0 +1,1147 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 1 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+/* Local Functions */
+static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt);
+static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+static void rw_t1t_process_frame_error (void);
+static void rw_t1t_process_error (void);
+static void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status);
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_t1t_get_state_name (UINT8 state);
+static char *rw_t1t_get_sub_state_name (UINT8 sub_state);
+static char *rw_t1t_get_event_name (UINT8 event);
+#endif
+
+/*******************************************************************************
+**
+** Function         rw_t1t_data_cback
+**
+** Description      This callback function handles data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tRW_T1T_CB              *p_t1t      = &rw_cb.tcb.t1t;
+    tRW_EVENT               rw_event    = RW_RAW_FRAME_EVT;
+    BOOLEAN                 b_notify    = TRUE;
+    tRW_DATA                evt_data;
+    BT_HDR                  *p_pkt;
+    UINT8                   *p;
+    tT1T_CMD_RSP_INFO       *p_cmd_rsp_info     = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+
+    p_pkt = (BT_HDR *) (p_data->data.p_data);
+    if (p_pkt == NULL)
+        return;
+    /* Assume the data is just the response byte sequence */
+    p = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_t1t_data_cback (): state:%s (%d)", rw_t1t_get_state_name (p_t1t->state), p_t1t->state);
+#else
+    RW_TRACE_DEBUG1 ("rw_t1t_data_cback (): state=%d", p_t1t->state);
+#endif
+
+    evt_data.status = NFC_STATUS_OK;
+
+    if(  (p_t1t->state == RW_T1T_STATE_IDLE)
+       ||(!p_cmd_rsp_info)  )
+    {
+        /* If previous command was retransmitted and if response is pending to previous command retransmission,
+         * check if lenght and ADD/ADD8/ADDS field matches the expected value of previous
+         * retransmited command response. However, ignore ADD field if the command was RALL/RID
+         */
+        if (  (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+            &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len)
+            &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p))  )
+        {
+            /* Response to previous command retransmission */
+            RW_TRACE_ERROR2 ("T1T Response to previous command in Idle state. command=0x%02x, Remaining max retx rsp:0x%02x ", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
+            p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
+            GKI_freebuf (p_pkt);
+        }
+        else
+        {
+            /* Raw frame event */
+            evt_data.data.p_data = p_pkt;
+            (*rw_cb.p_cback) (RW_T1T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
+        }
+        return;
+    }
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Update rx stats */
+    rw_main_update_rx_stats (p_pkt->len);
+#endif  /* RW_STATS_INCLUDED */
+
+
+    if (  (p_pkt->len != p_cmd_rsp_info->rsp_len)
+        ||((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID) && (*p != p_t1t->addr))  )
+
+    {
+        /* If previous command was retransmitted and if response is pending to previous command retransmission,
+         * then check if lenght and ADD/ADD8/ADDS field matches the expected value of previous
+         * retransmited command response. However, ignore ADD field if the command was RALL/RID
+         */
+        if (  (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+            &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len)
+            &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p))  )
+        {
+            RW_TRACE_ERROR2 ("T1T Response to previous command. command=0x%02x, Remaining max retx rsp:0x%02x", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1);
+            p_t1t->prev_cmd_rsp_info.pend_retx_rsp--;
+        }
+        else
+        {
+            /* Stop timer as some response to current command is received */
+            nfc_stop_quick_timer (&p_t1t->timer);
+            /* Retrasmit the last sent command if retry-count < max retry */
+#if (BT_TRACE_VERBOSE == TRUE)
+            RW_TRACE_ERROR2 ("T1T Frame error. state=%s command (opcode) = 0x%02x", rw_t1t_get_state_name (p_t1t->state), p_cmd_rsp_info->opcode);
+#else
+            RW_TRACE_ERROR2 ("T1T Frame error. state=0x%02x command = 0x%02x ", p_t1t->state, p_cmd_rsp_info->opcode);
+#endif
+            rw_t1t_process_frame_error ();
+        }
+        GKI_freebuf (p_pkt);
+        return;
+    }
+
+    /* Stop timer as response to current command is received */
+    nfc_stop_quick_timer (&p_t1t->timer);
+
+    RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+    /* If we did not receive response to all retransmitted previous command,
+     * dont expect that as response have come for the current command itself.
+     */
+    if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp)
+        memset (&(p_t1t->prev_cmd_rsp_info), 0, sizeof (tRW_T1T_PREV_CMD_RSP_INFO));
+
+    if (rw_cb.cur_retry)
+    {
+    /* If the current command was retransmitted to get this response, we might get
+       response later to all or some of the retrasnmission of the current command
+     */
+        p_t1t->prev_cmd_rsp_info.addr          = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID))? p_t1t->addr:0;
+        p_t1t->prev_cmd_rsp_info.rsp_len       = p_cmd_rsp_info->rsp_len;
+        p_t1t->prev_cmd_rsp_info.op_code       = p_cmd_rsp_info->opcode;
+        p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (UINT8) rw_cb.cur_retry;
+    }
+
+    rw_cb.cur_retry = 0;
+
+    if (p_cmd_rsp_info->opcode == T1T_CMD_RID)
+    {
+        rw_event = rw_t1t_handle_rid_rsp (p_pkt);
+    }
+    else
+    {
+        rw_event = rw_t1t_handle_rsp (p_cmd_rsp_info, &b_notify, p, &evt_data.status);
+    }
+
+    if (b_notify)
+    {
+        if(  (p_t1t->state != RW_T1T_STATE_READ)
+           &&(p_t1t->state != RW_T1T_STATE_WRITE)  )
+        {
+            GKI_freebuf (p_pkt);
+            evt_data.data.p_data = NULL;
+        }
+        else
+        {
+            evt_data.data.p_data = p_pkt;
+        }
+        rw_t1t_handle_op_complete ();
+        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
+    }
+    else
+        GKI_freebuf (p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_conn_cback
+**
+** Description      This callback function receives the events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t1t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tRW_T1T_CB          *p_t1t  = &rw_cb.tcb.t1t;
+    tRW_READ_DATA       evt_data;
+
+    RW_TRACE_DEBUG2 ("rw_t1t_conn_cback: conn_id=%i, evt=0x%x", conn_id, event);
+    /* Only handle static conn_id */
+    if (conn_id != NFC_RF_CONN_ID)
+    {
+        RW_TRACE_WARNING1 ("rw_t1t_conn_cback - Not static connection id: =%i", conn_id);
+        return;
+    }
+
+    switch (event)
+    {
+    case NFC_CONN_CREATE_CEVT:
+    case NFC_CONN_CLOSE_CEVT:
+        break;
+
+    case NFC_DEACTIVATE_CEVT:
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        /* Display stats */
+        rw_main_log_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+        /* Stop t1t timer (if started) */
+        nfc_stop_quick_timer (&p_t1t->timer);
+
+        /* Free cmd buf for retransmissions */
+        if (p_t1t->p_cur_cmd_buf)
+        {
+            GKI_freebuf (p_t1t->p_cur_cmd_buf);
+            p_t1t->p_cur_cmd_buf = NULL;
+        }
+
+        p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
+        NFC_SetStaticRfCback (NULL);
+        break;
+
+    case NFC_DATA_CEVT:
+        if (  (p_data != NULL)
+            &&(p_data->data.status == NFC_STATUS_OK)  )
+        {
+            rw_t1t_data_cback (conn_id, event, p_data);
+            break;
+        }
+        /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+    case NFC_ERROR_CEVT:
+        if (  (p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED)
+            ||(p_t1t->state == RW_T1T_STATE_IDLE)  )
+        {
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            rw_main_update_trans_error_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+            if (event == NFC_ERROR_CEVT)
+                evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+            else if (p_data)
+                evt_data.status = p_data->status;
+            else
+                evt_data.status = NFC_STATUS_FAILED;
+
+            evt_data.p_data = NULL;
+            (*rw_cb.p_cback) (RW_T1T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
+            break;
+        }
+        nfc_stop_quick_timer (&p_t1t->timer);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        rw_main_update_trans_error_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+        if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
+        {
+            rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
+        }
+        else
+        {
+            rw_t1t_process_error ();
+        }
+        break;
+
+    default:
+        break;
+
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_static_cmd
+**
+** Description      This function composes a Type 1 Tag command for static
+**                  memory and send through NCI to NFCC.
+**
+** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
+**                  otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_send_static_cmd (UINT8 opcode, UINT8 add, UINT8 dat)
+{
+    tNFC_STATUS             status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
+    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
+    BT_HDR                  *p_data;
+    UINT8                   *p;
+
+    if (p_cmd_rsp_info)
+    {
+        /* a valid opcode for RW */
+        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+        if (p_data)
+        {
+            p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
+            p_t1t->addr             = add;
+            p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p                       = (UINT8 *) (p_data + 1) + p_data->offset;
+            UINT8_TO_BE_STREAM (p, opcode);
+            UINT8_TO_BE_STREAM (p, add);
+            UINT8_TO_BE_STREAM (p, dat);
+
+            ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
+            p_data->len     = p_cmd_rsp_info->cmd_len;
+
+            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+            rw_cb.cur_retry = 0;
+            memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            /* Update stats */
+            rw_main_update_tx_stats (p_data->len, FALSE);
+#endif  /* RW_STATS_INCLUDED */
+
+            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
+            {
+                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+            }
+        }
+        else
+        {
+            status = NFC_STATUS_NO_BUFFERS;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_dyn_cmd
+**
+** Description      This function composes a Type 1 Tag command for dynamic memory
+**                  and send through NCI to NFCC.
+**
+** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
+**                  otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_send_dyn_cmd (UINT8 opcode, UINT8 add, UINT8 *p_dat)
+{
+    tNFC_STATUS             status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
+    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info = t1t_cmd_to_rsp_info (opcode);
+    BT_HDR                  *p_data;
+    UINT8                   *p;
+
+    if (p_cmd_rsp_info)
+    {
+        /* a valid opcode for RW */
+        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+        if (p_data)
+        {
+            p_t1t->p_cmd_rsp_info   = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info;
+            p_t1t->addr             = add;
+            p_data->offset          = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p                       = (UINT8 *) (p_data + 1) + p_data->offset;
+            UINT8_TO_BE_STREAM (p, opcode);
+            UINT8_TO_BE_STREAM (p, add);
+
+            if (p_dat)
+            {
+                ARRAY_TO_STREAM (p, p_dat, 8);
+            }
+            else
+            {
+                memset (p, 0, 8);
+                p += 8;
+            }
+            ARRAY_TO_STREAM (p, p_t1t->mem, T1T_CMD_UID_LEN);
+            p_data->len     = p_cmd_rsp_info->cmd_len;
+
+            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+            rw_cb.cur_retry = 0;
+            memcpy (p_t1t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            /* Update stats */
+            rw_main_update_tx_stats (p_data->len, FALSE);
+#endif  /* RW_STATS_INCLUDED */
+
+            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
+            {
+                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+            }
+        }
+        else
+        {
+            status = NFC_STATUS_NO_BUFFERS;
+        }
+    }
+    return status;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_rid_rsp
+**
+** Description      Handles response to RID: Collects HR, UID, notify up the
+**                  stack
+**
+** Returns          event to notify application
+**
+*****************************************************************************/
+static tRW_EVENT rw_t1t_handle_rid_rsp (BT_HDR *p_pkt)
+{
+    tRW_T1T_CB  *p_t1t   = &rw_cb.tcb.t1t;
+    tRW_DATA    evt_data;
+    UINT8       *p_rid_rsp;
+
+    evt_data.status      = NFC_STATUS_OK;
+    evt_data.data.p_data = p_pkt;
+
+    /* Assume the data is just the response byte sequence */
+    p_rid_rsp = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
+
+    /* Response indicates tag is present */
+    if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
+    {
+        /* If checking for the presence of the tag then just notify */
+        return RW_T1T_PRESENCE_CHECK_EVT;
+    }
+
+    /* Extract HR and UID from response */
+    STREAM_TO_ARRAY (p_t1t->hr,  p_rid_rsp, T1T_HR_LEN);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("hr0:0x%x, hr1:0x%x", p_t1t->hr[0], p_t1t->hr[1]);
+    RW_TRACE_DEBUG4 ("rw_t1t_handle_rid_rsp (): UID0-3=%02x%02x%02x%02x", p_rid_rsp[0], p_rid_rsp[1], p_rid_rsp[2], p_rid_rsp[3]);
+#else
+    RW_TRACE_DEBUG0 ("rw_t1t_handle_rid_rsp ()");
+#endif
+
+    /* Fetch UID0-3 from RID response message */
+    STREAM_TO_ARRAY (p_t1t->mem,  p_rid_rsp, T1T_CMD_UID_LEN);
+
+    /* Notify RID response Event */
+    return RW_T1T_RID_EVT;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_select
+**
+** Description      This function will set the callback function to
+**                  receive data from lower layers and also send rid command
+**
+** Returns          none
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_select (UINT8 hr[T1T_HR_LEN], UINT8 uid[T1T_CMD_UID_LEN])
+{
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+
+    p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED;
+
+    /* Alloc cmd buf for retransmissions */
+    if (p_t1t->p_cur_cmd_buf ==  NULL)
+    {
+        if ((p_t1t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+        {
+            RW_TRACE_ERROR0 ("rw_t1t_select: unable to allocate buffer for retransmission");
+            return status;
+        }
+    }
+
+    memcpy (p_t1t->hr, hr, T1T_HR_LEN);
+    memcpy (p_t1t->mem, uid, T1T_CMD_UID_LEN);
+
+    NFC_SetStaticRfCback (rw_t1t_conn_cback);
+
+    p_t1t->state    = RW_T1T_STATE_IDLE;
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t1t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    tRW_T1T_CB        *p_t1t  = &rw_cb.tcb.t1t;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_ERROR2 ("T1T timeout. state=%s command (opcode)=0x%02x ", rw_t1t_get_state_name (p_t1t->state), (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
+#else
+    RW_TRACE_ERROR2 ("T1T timeout. state=0x%02x command=0x%02x ", p_t1t->state, (rw_cb.tcb.t1t.p_cmd_rsp_info)->opcode);
+#endif
+
+    if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE)
+    {
+        /* Tag has moved from range */
+        rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED);
+    }
+    else if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        rw_t1t_process_error ();
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t1t_process_frame_error
+**
+** Description      Process frame crc error
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t1t_process_frame_error (void)
+{
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Update stats */
+    rw_main_update_crc_error_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+    /* Process the error */
+    rw_t1t_process_error ();
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_process_error
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t1t_process_error (void)
+{
+    tRW_READ_DATA           evt_data;
+    tRW_EVENT               rw_event;
+    BT_HDR                  *p_cmd_buf;
+    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
+    tT1T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+    tRW_DETECT_NDEF_DATA    ndef_data;
+
+    RW_TRACE_DEBUG1 ("rw_t1t_process_error () State: %u", p_t1t->state);
+
+    /* Retry sending command if retry-count < max */
+    if (rw_cb.cur_retry < RW_MAX_RETRIES)
+    {
+        /* retry sending the command */
+        rw_cb.cur_retry++;
+
+        RW_TRACE_DEBUG2 ("T1T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
+
+        /* allocate a new buffer for message */
+        if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+        {
+            memcpy (p_cmd_buf, p_t1t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t1t->p_cur_cmd_buf->offset + p_t1t->p_cur_cmd_buf->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            /* Update stats */
+            rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
+#endif  /* RW_STATS_INCLUDED */
+
+            if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
+            {
+                /* Start timer for waiting for response */
+                nfc_start_quick_timer (&p_t1t->timer, NFC_TTYPE_RW_T1T_RESPONSE,
+                                       (RW_T1T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC)/1000);
+
+                return;
+            }
+        }
+    }
+    else
+    {
+    /* we might get response later to all or some of the retrasnmission
+     * of the current command, update previous command response information */
+        RW_TRACE_DEBUG1 ("T1T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
+        p_t1t->prev_cmd_rsp_info.addr          = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID))? p_t1t->addr:0;
+        p_t1t->prev_cmd_rsp_info.rsp_len       = p_cmd_rsp_info->rsp_len;
+        p_t1t->prev_cmd_rsp_info.op_code       = p_cmd_rsp_info->opcode;
+        p_t1t->prev_cmd_rsp_info.pend_retx_rsp = RW_MAX_RETRIES;
+    }
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* update failure count */
+    rw_main_update_fail_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+    rw_event        = rw_t1t_info_to_event (p_cmd_rsp_info);
+    if (p_t1t->state != RW_T1T_STATE_NOT_ACTIVATED)
+        rw_t1t_handle_op_complete ();
+
+    evt_data.status = NFC_STATUS_TIMEOUT;
+    if (rw_event == RW_T2T_NDEF_DETECT_EVT)
+    {
+        ndef_data.status    = evt_data.status;
+        ndef_data.protocol  = NFC_PROTOCOL_T1T;
+        ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
+        ndef_data.max_size  = 0;
+        ndef_data.cur_size  = 0;
+        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
+    }
+    else
+    {
+        evt_data.p_data = NULL;
+        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
+    }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_presence_check_rsp
+**
+** Description      Handle response to presence check
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t1t_handle_presence_check_rsp (tNFC_STATUS status)
+{
+    tRW_READ_DATA   evt_data;
+
+    /* Notify, Tag is present or not */
+    evt_data.status = status;
+    rw_t1t_handle_op_complete ();
+
+    (*(rw_cb.p_cback)) (RW_T1T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_op_complete
+**
+** Description      Reset to IDLE state
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t1t_handle_op_complete (void)
+{
+    tRW_T1T_CB      *p_t1t  = &rw_cb.tcb.t1t;
+
+    p_t1t->state    = RW_T1T_STATE_IDLE;
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+    p_t1t->substate = RW_T1T_SUBSTATE_NONE;
+#endif
+    return;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T1T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tPresenceCheck (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_DATA evt_data;
+    tRW_CB *p_rw_cb = &rw_cb;
+
+    RW_TRACE_API0 ("RW_T1tPresenceCheck");
+
+    /* If RW_SelectTagType was not called (no conn_callback) return failure */
+    if (!p_rw_cb->p_cback)
+    {
+        retval = NFC_STATUS_FAILED;
+    }
+    /* If we are not activated, then RW_T1T_PRESENCE_CHECK_EVT status=FAIL */
+    else if (p_rw_cb->tcb.t1t.state == RW_T1T_STATE_NOT_ACTIVATED)
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+        (*p_rw_cb->p_cback) (RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    /* If command is pending, assume tag is still present */
+    else if (p_rw_cb->tcb.t1t.state != RW_T1T_STATE_IDLE)
+    {
+        evt_data.status = NFC_STATUS_OK;
+        (*p_rw_cb->p_cback) (RW_T1T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    else
+    {
+        /* IDLE state: send a RID command to the tag to see if it responds */
+        if((retval = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
+        {
+            p_rw_cb->tcb.t1t.state = RW_T1T_STATE_CHECK_PRESENCE;
+        }
+    }
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tRid
+**
+** Description
+**      This function sends a RID command for Reader/Writer mode.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tRid (void)
+{
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+
+    RW_TRACE_API0 ("RW_T1tRid");
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tRid - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    /* send a RID command */
+    if((status = rw_t1t_send_static_cmd (T1T_CMD_RID, 0, 0))== NFC_STATUS_OK)
+    {
+        p_t1t->state = RW_T1T_STATE_READ;
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadAll
+**
+** Description      This function sends a RALL command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadAll (void)
+{
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+
+    RW_TRACE_API0 ("RW_T1tReadAll");
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tReadAll - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    /* send RALL command */
+    if ((status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0)) == NFC_STATUS_OK)
+    {
+        p_t1t->state = RW_T1T_STATE_READ;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead
+**
+** Description      This function sends a READ command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tRead (UINT8 block, UINT8 byte)
+{
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    UINT8       addr;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tRead - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    /* send READ command */
+    RW_T1T_BLD_ADD ((addr), (block), (byte));
+    if ((status = rw_t1t_send_static_cmd (T1T_CMD_READ, addr, 0)) == NFC_STATUS_OK)
+    {
+        p_t1t->state = RW_T1T_STATE_READ;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase
+**
+** Description      This function sends a WRITE-E command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteErase (UINT8 block, UINT8 byte, UINT8 new_byte)
+{
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    UINT8       addr;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteErase - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+        &&(block != T1T_CC_BLOCK)
+        &&(byte  != T1T_CC_RWA_OFFSET)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
+        return (NFC_STATUS_REFUSED);
+    }
+    if (  (block >= T1T_STATIC_BLOCKS)
+        ||(byte  >= T1T_BLOCK_SIZE   )  )
+    {
+        RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
+        return (NFC_STATUS_REFUSED);
+    }
+    if(  (block == T1T_UID_BLOCK)
+       ||(block == T1T_RES_BLOCK)  )
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteErase - Cannot write to Locked block: %u", block);
+        return (NFC_STATUS_REFUSED);
+    }
+    /* send WRITE-E command */
+    RW_T1T_BLD_ADD ((addr), (block), (byte));
+    if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, new_byte)) == NFC_STATUS_OK)
+    {
+        p_t1t->state = RW_T1T_STATE_WRITE;
+        if (block < T1T_BLOCKS_PER_SEGMENT)
+        {
+            p_t1t->b_update = FALSE;
+            p_t1t->b_rseg   = FALSE;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase
+**
+** Description      This function sends a WRITE-NE command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNoErase (UINT8 block, UINT8 byte, UINT8 new_byte)
+{
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    UINT8       addr;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+        &&(block != T1T_CC_BLOCK)
+        &&(byte  != T1T_CC_RWA_OFFSET)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tWriteErase - Tag is in Read only state");
+        return (NFC_STATUS_REFUSED);
+    }
+    if (  (block >= T1T_STATIC_BLOCKS)
+        ||(byte  >= T1T_BLOCK_SIZE   )  )
+    {
+        RW_TRACE_ERROR2 ("RW_T1tWriteErase - Invalid Block/byte: %u / %u", block, byte);
+        return (NFC_STATUS_REFUSED);
+    }
+    if(  (block == T1T_UID_BLOCK)
+       ||(block == T1T_RES_BLOCK)  )
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase - Cannot write to Locked block: %u", block);
+        return (NFC_STATUS_REFUSED);
+    }
+    /* send WRITE-NE command */
+    RW_T1T_BLD_ADD ((addr), (block), (byte));
+    if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, new_byte)) == NFC_STATUS_OK)
+    {
+        p_t1t->state = RW_T1T_STATE_WRITE;
+        if (block < T1T_BLOCKS_PER_SEGMENT)
+        {
+            p_t1t->b_update = FALSE;
+            p_t1t->b_rseg   = FALSE;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadSeg
+**
+** Description      This function sends a RSEG command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadSeg (UINT8 segment)
+{
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    UINT8       adds;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tReadSeg - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+    if (segment >=  T1T_MAX_SEGMENTS)
+    {
+        RW_TRACE_ERROR1 ("RW_T1tReadSeg - Invalid Segment: %u", segment);
+        return (NFC_STATUS_REFUSED);
+    }
+    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0)
+    {
+        /* send RSEG command */
+        RW_T1T_BLD_ADDS ((adds), (segment));
+        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
+        {
+            p_t1t->state = RW_T1T_STATE_READ;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tRead8
+**
+** Description      This function sends a READ8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tRead8 (UINT8 block)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tRead8 - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+    {
+        /* send READ8 command */
+        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, block, NULL)) == NFC_STATUS_OK)
+        {
+            p_t1t->state = RW_T1T_STATE_READ;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteErase8
+**
+** Description      This function sends a WRITE-E8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteErase8 (UINT8 block, UINT8 *p_new_dat)
+{
+    tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+        &&(block != T1T_CC_BLOCK)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tWriteErase8 - Tag is in Read only state");
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if(  (block == T1T_UID_BLOCK)
+       ||(block == T1T_RES_BLOCK)  )
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteErase8 - Cannot write to Locked block: %u", block);
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+    {
+        /* send WRITE-E8 command */
+        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_new_dat)) == NFC_STATUS_OK)
+        {
+            p_t1t->state = RW_T1T_STATE_WRITE;
+            if (block < T1T_BLOCKS_PER_SEGMENT)
+            {
+                p_t1t->b_update = FALSE;
+                p_t1t->b_rseg   = FALSE;
+            }
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNoErase8
+**
+** Description      This function sends a WRITE-NE8 command for Reader/Writer mode.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNoErase8 (UINT8 block, UINT8 *p_new_dat)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t= &rw_cb.tcb.t1t;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_ONLY)
+        &&(block != T1T_CC_BLOCK)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tWriteNoErase8 - Tag is in Read only state");
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if(  (block == T1T_UID_BLOCK)
+       ||(block == T1T_RES_BLOCK)  )
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteNoErase8 - Cannot write to Locked block: %u", block);
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+    {
+        /* send WRITE-NE command */
+        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, block, p_new_dat)) == NFC_STATUS_OK)
+        {
+            p_t1t->state    = RW_T1T_STATE_WRITE;
+            if (block < T1T_BLOCKS_PER_SEGMENT)
+            {
+                p_t1t->b_update = FALSE;
+                p_t1t->b_rseg   = FALSE;
+            }
+        }
+    }
+    return status;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         rw_t1t_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_t1t_get_state_name (UINT8 state)
+{
+    switch (state)
+    {
+    case RW_T1T_STATE_IDLE:
+        return ("IDLE");
+    case RW_T1T_STATE_NOT_ACTIVATED:
+        return ("NOT_ACTIVATED");
+    case RW_T1T_STATE_READ:
+        return ("APP_READ");
+    case RW_T1T_STATE_WRITE:
+        return ("APP_WRITE");
+    case RW_T1T_STATE_TLV_DETECT:
+        return ("TLV_DETECTION");
+    case RW_T1T_STATE_READ_NDEF:
+        return ("READING_NDEF");
+    case RW_T1T_STATE_WRITE_NDEF:
+        return ("WRITING_NDEF");
+    case RW_T1T_STATE_SET_TAG_RO:
+        return ("SET_TAG_RO");
+    case RW_T1T_STATE_CHECK_PRESENCE:
+        return ("CHECK_PRESENCE");
+    case RW_T1T_STATE_FORMAT_TAG:
+        return ("FORMAT_TAG");
+    default:
+        return ("???? UNKNOWN STATE");
+    }
+}
+
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_t1t_ndef.c b/src/nfc/tags/rw_t1t_ndef.c
new file mode 100644
index 0000000..f37f343
--- /dev/null
+++ b/src/nfc/tags/rw_t1t_ndef.c
@@ -0,0 +1,2830 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 1 tag NDEF operation in
+ *  Reader/Writer mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+
+/* Local Functions */
+static tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_callback, UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data);
+static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void);
+static tNFC_STATUS rw_t1t_ndef_write_first_block (void);
+static tNFC_STATUS rw_t1t_next_ndef_write_block (void);
+static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len);
+static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block);
+static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len);
+static UINT8 rw_t1t_get_ndef_flags (void);
+static UINT16 rw_t1t_get_ndef_max_size (void);
+static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index);
+static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index);
+static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte);
+static void rw_t1t_update_attributes (void);
+static void rw_t1t_update_lock_attributes (void);
+static void rw_t1t_extract_lock_bytes (UINT8 *p_data);
+static void rw_t1t_update_tag_state (void);
+
+const UINT8 rw_t1t_mask_bits[8] =
+{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_rsp
+**
+** Description      This function handles the response received for all commands
+**                  sent to tag
+**
+** Returns          event to be sent to application
+**
+*******************************************************************************/
+tRW_EVENT rw_t1t_handle_rsp (const tT1T_CMD_RSP_INFO * p_info, BOOLEAN *p_notify, UINT8 *p_data, tNFC_STATUS *p_status)
+{
+    tRW_EVENT   rw_event;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    UINT8       adds;
+
+    if(  (p_t1t->state == RW_T1T_STATE_READ)
+       ||(p_t1t->state == RW_T1T_STATE_WRITE)  )
+    {
+        return t1t_info_to_evt (p_info);
+    }
+
+    rw_event = rw_t1t_info_to_event (p_info);
+
+    if (p_info->opcode == T1T_CMD_RALL)
+    {
+        *p_status = rw_t1t_handle_rall_rsp (p_notify,p_data);
+    }
+    else if (p_info->opcode == T1T_CMD_RSEG)
+    {
+        adds = *p_data;
+        if (adds == 0)
+        {
+            p_t1t->b_rseg   = TRUE;
+            rw_t1t_update_tag_state ();
+            rw_t1t_update_attributes ();
+            rw_t1t_update_lock_attributes ();
+            memcpy (p_t1t->mem, (UINT8 *) (p_data + 1), T1T_SEGMENT_SIZE);
+        }
+        *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data);
+    }
+    else if (p_info->opcode == T1T_CMD_READ8)
+    {
+        *p_status = rw_t1t_handle_dyn_read_rsp (p_notify,p_data);
+    }
+    else
+    {
+        *p_status = rw_t1t_handle_write_rsp (p_notify,p_data);
+    }
+    return rw_event;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_info_to_event
+**
+** Description      This function returns RW event code based on the current state
+**
+** Returns          RW event code
+**
+*******************************************************************************/
+tRW_EVENT rw_t1t_info_to_event (const tT1T_CMD_RSP_INFO * p_info)
+{
+    tRW_EVENT   rw_event;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+
+    switch (p_t1t->state)
+    {
+    case RW_T1T_STATE_TLV_DETECT:
+        if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+            rw_event = RW_T1T_NDEF_DETECT_EVT;
+        else
+            rw_event = RW_T1T_TLV_DETECT_EVT;
+        break;
+
+    case RW_T1T_STATE_READ_NDEF:
+        rw_event = RW_T1T_NDEF_READ_EVT;
+        break;
+
+    case RW_T1T_STATE_WRITE_NDEF:
+        rw_event = RW_T1T_NDEF_WRITE_EVT;
+        break;
+
+    case RW_T1T_STATE_SET_TAG_RO:
+        rw_event = RW_T1T_SET_TAG_RO_EVT;
+        break;
+
+    case RW_T1T_STATE_CHECK_PRESENCE:
+        rw_event = RW_T1T_PRESENCE_CHECK_EVT;
+        break;
+
+    case RW_T1T_STATE_FORMAT_TAG:
+        rw_event = RW_T1T_FORMAT_CPLT_EVT;
+        break;
+
+    default:
+	    rw_event = t1t_info_to_evt (p_info);
+        break;
+    }
+    return rw_event;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_extract_lock_bytes
+**
+** Description      This function will extract lock bytes if any present in the
+**                  response data
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t1t_extract_lock_bytes (UINT8 *p_data)
+{
+    UINT16              end;
+    UINT16              start;
+    UINT8               num_locks;
+    UINT16              lock_offset = 0;
+    UINT16              offset;
+    tRW_T1T_CB          *p_t1t          = &rw_cb.tcb.t1t;
+    tT1T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+
+    num_locks = 0;
+    /* Based on the Command used to read Tag, calculate the offset of the tag read */
+    if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
+    {
+        start = p_t1t->segment * T1T_SEGMENT_SIZE;
+        end   = (p_t1t->segment + 1) * T1T_SEGMENT_SIZE;
+    }
+    else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8)
+    {
+        start = p_data[0] * T1T_BLOCK_SIZE;
+        end   = (p_data[0] + 1) * T1T_BLOCK_SIZE;
+    }
+    else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL)
+    {
+        start = 0;
+        end   = T1T_STATIC_SIZE;
+    }
+    else
+        return;
+
+    /* Collect lock bytes that are present in the part of the data read from Tag */
+    while (num_locks < p_t1t->num_lockbytes)
+    {
+        if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
+        {
+            offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
+            if (  (offset <  end)
+                &&(offset >= start)  )
+
+            {
+                if (p_cmd_rsp_info->opcode == T1T_CMD_RSEG)
+                {
+                    lock_offset = (offset % T1T_SEGMENT_SIZE) + T1T_ADD_LEN;
+                }
+                else if (p_cmd_rsp_info->opcode == T1T_CMD_READ8)
+                {
+                    lock_offset = (offset % T1T_BLOCK_SIZE) + T1T_ADD_LEN;
+                }
+                else if (p_cmd_rsp_info->opcode == T1T_CMD_RALL)
+                {
+                    lock_offset = offset;
+                }
+
+                p_t1t->lockbyte[num_locks].lock_byte    = p_data[lock_offset];
+                p_t1t->lockbyte[num_locks].b_lock_read  = TRUE;
+            }
+            else
+                break;
+        }
+        num_locks++;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_update_tag_attributes
+**
+** Description      This function will update tag attributes based on cc, ndef
+**                  message length
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t1t_update_tag_state (void)
+{
+    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
+
+    /* Set Tag state based on CC value and NDEF Message length */
+    if (  ((p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN) || (p_t1t->mem[T1T_CC_NMN_BYTE] == 0))
+        &&((p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_VNO) || (p_t1t->mem[T1T_CC_VNO_BYTE] == T1T_CC_LEGACY_VNO))
+        &&((p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW)|| (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO))  )
+    {
+        /* Valid CC value, so Tag is initialized */
+        if (p_t1t->ndef_msg_len > 0)
+        {
+            if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RO)
+            {
+                /* NDEF Message presence, CC indication sets Tag as READ ONLY  */
+                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_ONLY;
+            }
+            else if (p_t1t->mem[T1T_CC_RWA_BYTE] == T1T_CC_RWA_RW)
+            {
+                /* NDEF Message presence, CC indication sets Tag as READ WRITE */
+                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
+            }
+        }
+        else
+        {
+            /* If NDEF is not yet detected then Tag remains in Initialized state
+            *  after NDEF Detection the Tag state may be updated */
+            p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
+        }
+    }
+    else
+    {
+        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_UNKNOWN;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_read_locks
+**
+** Description      This function will send command to read next unread locks
+**
+** Returns          NFC_STATUS_OK, if all locks are read successfully
+**                  NFC_STATUS_FAILED, if reading locks failed
+**                  NFC_STATUS_CONTINUE, if reading locks is in progress
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_read_locks (void)
+{
+    UINT8       num_locks   = 0;
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    tNFC_STATUS status      = NFC_STATUS_CONTINUE;
+    UINT16      offset;
+
+    while (num_locks < p_t1t->num_lockbytes)
+    {
+        if (p_t1t->lockbyte[num_locks].b_lock_read == FALSE)
+        {
+            offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
+            if (offset < T1T_STATIC_SIZE)
+            {
+               p_t1t->lockbyte[num_locks].lock_byte   = p_t1t->mem[offset];
+               p_t1t->lockbyte[num_locks].b_lock_read = TRUE;
+            }
+            else if (offset < (p_t1t->mem[T1T_CC_TMS_BYTE] + 1) * T1T_BLOCK_SIZE)
+            {
+                /* send READ8 command */
+                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, (UINT8) (offset/T1T_BLOCK_SIZE), NULL)) == NFC_STATUS_OK)
+                {
+                    /* Reading Locks */
+                    status          = NFC_STATUS_CONTINUE;
+                    p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_LOCKS;
+                }
+                break;
+            }
+            else
+            {
+                /* Read locks failed */
+                status = NFC_STATUS_FAILED;
+                break;
+            }
+        }
+        num_locks++;
+    }
+    if (num_locks == p_t1t->num_lockbytes)
+    {
+        /* All locks are read */
+        status = NFC_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_write_rsp
+**
+** Description      This function handles response received for WRITE_E8,
+**                  WRITE_NE8, WRITE_E, WRITE_NE commands
+**
+** Returns          status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_write_rsp (BOOLEAN *p_notify, UINT8 *p_data)
+{
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    tNFC_STATUS status      = NFC_STATUS_OK;
+    UINT8       num_locks;
+    UINT8       lock_count;
+    UINT8       value;
+    UINT8       addr;
+    UINT8       write_block[T1T_BLOCK_SIZE];
+    UINT16      offset;
+    UINT16      next_offset;
+    UINT8       num_bits;
+    UINT8       next_num_bits;
+
+    *p_notify = FALSE;
+
+    switch (p_t1t->state)
+    {
+    case RW_T1T_STATE_WRITE:
+        *p_notify = TRUE;
+        break;
+
+    case RW_T1T_STATE_FORMAT_TAG:
+        if (p_t1t->substate == RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF)
+        {
+            if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+                *p_notify = TRUE;
+            else
+            {
+                if (p_t1t->work_offset < (T1T_BLOCK_SIZE - 1))
+                {
+                    p_t1t->work_offset++;
+                    /* send WRITE-E command */
+                    RW_T1T_BLD_ADD ((addr), 1, (UINT8) p_t1t->work_offset);
+
+                    if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[(UINT8) p_t1t->work_offset])) != NFC_STATUS_OK)
+                        *p_notify = TRUE;
+                }
+                else
+                    *p_notify = TRUE;
+            }
+
+        }
+        else
+        {
+            /* send WRITE-E8 command */
+            if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 2, p_t1t->ndef_final_block)) != NFC_STATUS_OK)
+                *p_notify = TRUE;
+            else
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+        }
+        break;
+
+    case RW_T1T_STATE_SET_TAG_RO:
+        switch (p_t1t->substate)
+        {
+        case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
+
+            if (!p_t1t->b_hard_lock)
+            {
+                status    = NFC_STATUS_OK;
+                *p_notify = TRUE;
+                break;
+            }
+
+            if ((p_t1t->hr[0] & 0x0F) != 1)
+            {
+                memset (write_block,0,T1T_BLOCK_SIZE);
+                write_block[0] = 0xFF;
+                write_block[1] = 0xFF;
+
+                /* send WRITE-NE8 command */
+                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, T1T_LOCK_BLOCK, write_block)) != NFC_STATUS_OK)
+                    *p_notify       = TRUE;
+                else
+                    p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+            }
+            else
+            {
+                /* send WRITE-NE command */
+                RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (0));
+                if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
+                    *p_notify       = TRUE;
+                else
+                    p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
+            }
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+
+            /* send WRITE-NE command */
+            RW_T1T_BLD_ADD ((addr), (T1T_LOCK_BLOCK), (1));
+            if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0xFF)) != NFC_STATUS_OK)
+                *p_notify       = TRUE;
+            else
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+            num_locks = 0;
+            while (num_locks < p_t1t->num_lockbytes)
+            {
+                if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_UPDATE_INITIATED)
+                {
+                    p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATED;
+                }
+                num_locks++;
+            }
+
+            num_locks = 0;
+            while (num_locks < p_t1t->num_lockbytes)
+            {
+                if (p_t1t->lockbyte[num_locks].lock_status == RW_T1T_LOCK_NOT_UPDATED)
+                {
+                    offset = p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].offset + p_t1t->lockbyte[num_locks].byte_index;
+                    num_bits = ((p_t1t->lockbyte[num_locks].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[num_locks].tlv_index].num_bits % 8;
+
+                    if ((p_t1t->hr[0] & 0x0F) != 1)
+                    {
+                        memset (write_block,0,T1T_BLOCK_SIZE);
+
+                        write_block[(UINT8) (offset%T1T_BLOCK_SIZE)] |=  tags_pow (2,num_bits) - 1;
+                        lock_count = num_locks + 1;
+                        while (lock_count < p_t1t->num_lockbytes)
+                        {
+                            next_offset = p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].offset + p_t1t->lockbyte[lock_count].byte_index;
+                            next_num_bits = ((p_t1t->lockbyte[lock_count].byte_index + 1)* 8 <= p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits) ? 8 : p_t1t->lock_tlv[p_t1t->lockbyte[lock_count].tlv_index].num_bits % 8;
+
+                            if (next_offset/T1T_BLOCK_SIZE == offset/T1T_BLOCK_SIZE)
+                            {
+                                write_block[(UINT8) (next_offset%T1T_BLOCK_SIZE)] |=  tags_pow (2,next_num_bits) - 1;
+                            }
+                            else
+                                break;
+                            lock_count ++;
+                        }
+
+                        /* send WRITE-NE8 command */
+                        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_NE8, (UINT8) (offset/T1T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
+                        {
+                            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+                            while (lock_count >  num_locks)
+                            {
+                                p_t1t->lockbyte[lock_count - 1].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
+                                lock_count --;
+                            }
+                        }
+                        else
+                            *p_notify       = TRUE;
+                    }
+                    else
+                    {
+                        /* send WRITE-NE command */
+                        RW_T1T_BLD_ADD ((addr), ((UINT8) (offset/T1T_BLOCK_SIZE)), ((UINT8) (offset%T1T_BLOCK_SIZE)));
+                        value = (UINT8) (tags_pow (2,num_bits) - 1);
+                        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, value)) == NFC_STATUS_OK)
+                        {
+                            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+                            p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_UPDATE_INITIATED;
+                        }
+                        else
+                            *p_notify       = TRUE;
+                    }
+                    break;
+                }
+                num_locks++;
+            }
+            if (num_locks == p_t1t->num_lockbytes)
+            {
+                rw_t1t_update_lock_attributes ();
+                status    = NFC_STATUS_OK;
+                *p_notify = TRUE;
+            }
+            break;
+        }
+        break;
+
+    case RW_T1T_STATE_WRITE_NDEF:
+        switch (p_t1t->substate)
+        {
+        case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
+            p_t1t->ndef_msg_len  = p_t1t->new_ndef_msg_len;
+            p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
+            *p_notify = TRUE;
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+            status      = rw_t1t_handle_ndef_write_rsp (p_data);
+            if (status == NFC_STATUS_OK)
+            {
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF;
+            }
+            else if (status == NFC_STATUS_FAILED)
+            {
+                /* Send Negative response to upper layer */
+                *p_notify       = TRUE;
+            }
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+            status = rw_t1t_handle_ndef_write_rsp (p_data);
+
+            if (status == NFC_STATUS_FAILED)
+            {
+                /* Send Negative response to upper layer */
+                *p_notify       = TRUE;
+            }
+            else if (status == NFC_STATUS_OK)
+            {
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
+            }
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+            status = rw_t1t_handle_ndef_write_rsp (p_data);
+            if (status == NFC_STATUS_FAILED)
+            {
+                /* Send Negative response to upper layer */
+                *p_notify   = TRUE;
+            }
+            else if (status == NFC_STATUS_CONTINUE)
+            {
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_WRITE;
+            }
+            else
+            {
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED;
+            }
+            break;
+        }
+        break;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_read_rsp
+**
+** Description      This function handle the response received for RSEG,
+**                  RALL, READ8 commands
+**
+** Returns          status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+tNFC_STATUS rw_t1t_handle_read_rsp (BOOLEAN *p_notify,UINT8 *p_data)
+{
+    tRW_T1T_CB              *p_t1t  = &rw_cb.tcb.t1t;
+    tNFC_STATUS             status  = NFC_STATUS_OK;
+    tRW_DETECT_NDEF_DATA    ndef_data;
+    tRW_DETECT_TLV_DATA     tlv_data;
+    UINT8                   count;
+    tRW_READ_DATA           evt_data;
+
+    *p_notify = FALSE;
+    /* Handle the response based on the current state */
+    switch (p_t1t->state)
+    {
+    case RW_T1T_STATE_READ:
+        *p_notify = TRUE;
+        break;
+
+    case RW_T1T_STATE_READ_NDEF:
+        status = rw_t1t_handle_ndef_rall_rsp ();
+        if (status != NFC_STATUS_CONTINUE)
+        {
+            evt_data.status = status;
+            evt_data.p_data = NULL;
+            rw_t1t_handle_op_complete ();
+            (*rw_cb.p_cback) (RW_T1T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
+        }
+        break;
+
+    case RW_T1T_STATE_TLV_DETECT:
+        switch (p_t1t->substate)
+        {
+        case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
+            status = rw_t1t_read_locks ();
+            if (status != NFC_STATUS_CONTINUE)
+            {
+                rw_t1t_update_lock_attributes ();
+                /* Send positive response to upper layer */
+                if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+                {
+                    tlv_data.protocol   = NFC_PROTOCOL_T1T;
+                    tlv_data.num_bytes  = p_t1t->num_lockbytes;
+                    tlv_data.status = status;
+                    rw_t1t_handle_op_complete ();
+                    (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+                }
+                else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+                {
+                    ndef_data.protocol  = NFC_PROTOCOL_T1T;
+                    ndef_data.flags     = rw_t1t_get_ndef_flags ();
+                    ndef_data.flags    |= RW_NDEF_FL_FORMATED;
+                    ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
+                    ndef_data.cur_size  = p_t1t->ndef_msg_len;
+
+                    if (ndef_data.max_size  < ndef_data.cur_size)
+                    {
+                        ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
+                        ndef_data.max_size  = ndef_data.cur_size;
+                    }
+
+                    if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+                    {
+                        ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
+                        if (status == NFC_STATUS_OK)
+                            ndef_data.flags    |= RW_NDEF_FL_HARD_LOCKABLE;
+                    }
+                    ndef_data.status = status;
+                    rw_t1t_handle_op_complete ();
+                    (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
+                }
+            }
+            break;
+
+        case RW_T1T_SUBSTATE_NONE:
+            if (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
+            {
+                tlv_data.status    = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
+                tlv_data.protocol  = NFC_PROTOCOL_T1T;
+                tlv_data.num_bytes = 0;
+                count              = 0;
+                while (count < p_t1t->num_mem_tlvs)
+                {
+                    tlv_data.num_bytes += p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes;
+                    count++;
+                }
+                rw_t1t_handle_op_complete ();
+                /* Send response to upper layer */
+                (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+            }
+            else if (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+            {
+                tlv_data.status    = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
+                tlv_data.protocol  = NFC_PROTOCOL_T1T;
+                tlv_data.num_bytes = p_t1t->num_lockbytes;
+
+                if (tlv_data.status == NFC_STATUS_FAILED)
+                {
+                    rw_t1t_handle_op_complete ();
+
+                    /* Send Negative response to upper layer */
+                    (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *)&tlv_data);
+                }
+                else
+                {
+                    rw_t1t_extract_lock_bytes (p_data);
+                    status = rw_t1t_read_locks ();
+                    if (status != NFC_STATUS_CONTINUE)
+                    {
+                        /* Send positive response to upper layer */
+                        tlv_data.status = status;
+                        rw_t1t_handle_op_complete ();
+
+                        (*rw_cb.p_cback) (RW_T1T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+                    }
+                }
+            }
+            else if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+            {
+                ndef_data.protocol  = NFC_PROTOCOL_T1T;
+                ndef_data.flags     = rw_t1t_get_ndef_flags ();
+
+                if (p_t1t->mem[T1T_CC_NMN_BYTE] == T1T_CC_NMN)
+                {
+                    ndef_data.status    = rw_t1t_handle_tlv_detect_rsp (p_t1t->mem);
+
+                    ndef_data.cur_size  = p_t1t->ndef_msg_len;
+                    if (ndef_data.status == NFC_STATUS_FAILED)
+                    {
+                        ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
+                        if (ndef_data.max_size  < ndef_data.cur_size)
+                        {
+                            ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
+                            ndef_data.max_size  = ndef_data.cur_size;
+                        }
+                        if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+                        {
+                            ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
+                        }
+                        /* Send Negative response to upper layer */
+                        rw_t1t_handle_op_complete ();
+
+                        (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
+                    }
+                    else
+                    {
+                        ndef_data.flags    |= RW_NDEF_FL_FORMATED;
+                        rw_t1t_extract_lock_bytes (p_data);
+                        status = rw_t1t_read_locks ();
+                        if (status != NFC_STATUS_CONTINUE)
+                        {
+                            ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
+                            if (ndef_data.max_size  < ndef_data.cur_size)
+                            {
+                                ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
+                                ndef_data.max_size  = ndef_data.cur_size;
+                            }
+
+                            if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+                            {
+                                ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
+                                if (status == NFC_STATUS_OK)
+                                    ndef_data.flags    |= RW_NDEF_FL_HARD_LOCKABLE;
+                            }
+                            /* Send positive response to upper layer */
+                            ndef_data.status = status;
+                            rw_t1t_handle_op_complete ();
+
+                            (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *)&ndef_data);
+                        }
+                    }
+                }
+                else
+                {
+                    /* Send Negative response to upper layer */
+                    ndef_data.status    = NFC_STATUS_FAILED;
+                    ndef_data.max_size  = (UINT32) rw_t1t_get_ndef_max_size ();
+                    ndef_data.cur_size  = p_t1t->ndef_msg_len;
+                    if (ndef_data.max_size  < ndef_data.cur_size)
+                    {
+                        ndef_data.flags    |= RW_NDEF_FL_READ_ONLY;
+                        ndef_data.max_size  = ndef_data.cur_size;
+                    }
+                    if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+                    {
+                        ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
+                        ndef_data.flags    |= RW_NDEF_FL_SOFT_LOCKABLE;
+                    }
+                    rw_t1t_handle_op_complete ();
+
+                    (*rw_cb.p_cback) (RW_T1T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
+                }
+            }
+            break;
+        }
+        break;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_dyn_read_rsp
+**
+** Description      This function handles response received for READ8, RSEG
+**                  commands based on the current state
+**
+** Returns          status of the current NDEF/TLV Operation
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_dyn_read_rsp (BOOLEAN *p_notify, UINT8 *p_data)
+{
+    tNFC_STATUS status  = NFC_STATUS_OK;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+
+    *p_notify = FALSE;
+
+    rw_t1t_extract_lock_bytes (p_data);
+
+    if (p_t1t->state == RW_T1T_STATE_READ_NDEF)
+    {
+        status = rw_t1t_handle_ndef_read_rsp (p_data);
+        if (  (status == NFC_STATUS_FAILED)
+            ||(status == NFC_STATUS_OK)  )
+        {
+            /* Send response to upper layer */
+            *p_notify = TRUE;
+        }
+    }
+    else if (p_t1t->state == RW_T1T_STATE_WRITE_NDEF)
+    {
+        status = rw_t1t_handle_ndef_write_rsp (p_data);
+        if (status == NFC_STATUS_FAILED)
+        {
+            /* Send response to upper layer */
+            *p_notify = TRUE;
+        }
+        else if (status == NFC_STATUS_CONTINUE)
+        {
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+        }
+    }
+    else
+    {
+        status = rw_t1t_handle_read_rsp (p_notify,p_data);
+    }
+    return status;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t1t_handle_rall_rsp
+**
+** Description      Handle response to RALL - Collect CC, set Tag state
+**
+** Returns          None
+**
+*****************************************************************************/
+static tNFC_STATUS rw_t1t_handle_rall_rsp (BOOLEAN *p_notify,UINT8 *p_data)
+{
+    tRW_T1T_CB  *p_t1t   = &rw_cb.tcb.t1t;
+
+    p_data      += T1T_HR_LEN; /* skip HR */
+    memcpy (p_t1t->mem, (UINT8 *) p_data, T1T_STATIC_SIZE);
+    p_t1t->segment  = 0;
+    rw_t1t_extract_lock_bytes (p_data);
+
+    p_data      += T1T_UID_LEN + T1T_RES_BYTE_LEN; /* skip Block 0, UID and Reserved byte */
+
+    RW_TRACE_DEBUG0 ("rw_t1t_handle_rall_rsp ()");
+
+    rw_t1t_update_tag_state ();
+    rw_t1t_update_attributes ();
+    rw_t1t_update_lock_attributes ();
+    p_t1t->b_update = TRUE;
+    return (rw_t1t_handle_read_rsp (p_notify, p_t1t->mem));
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_tlv_detect_rsp
+**
+** Description      Handle response to the last command sent while
+**                  detecting tlv
+**
+** Returns          NFC_STATUS_OK, if tlv detect is complete & success
+**                  NFC_STATUS_FAILED,if tlv detect failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_tlv_detect_rsp (UINT8 *p_data)
+{
+    UINT16      offset;
+    UINT16      len;
+    UINT8       xx;
+    UINT8       *p_readbytes;
+    UINT8       index;
+    UINT8       tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+    UINT8       found_tlv = TAG_NULL_TLV;
+    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
+    BOOLEAN     failed          = FALSE;
+    BOOLEAN     found           = FALSE;
+    UINT8       count           = 0;
+    tNFC_STATUS status          = NFC_STATUS_FAILED;
+    UINT8       start_offset    = T1T_UID_LEN + T1T_CC_LEN + T1T_RES_BYTE_LEN;
+    UINT8       end_offset      = T1T_STATIC_SIZE - (2*T1T_BLOCK_SIZE);
+    UINT8       bytes_read      = T1T_STATIC_SIZE;
+    UINT8       tlv_value[T1T_DEFAULT_TLV_LEN];
+    UINT16      bytes_count = 0;
+
+    p_readbytes = p_data;
+
+    for (offset = start_offset; offset < end_offset  && !failed && !found;)
+    {
+        if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == TRUE)
+        {
+            offset++;
+            continue;
+        }
+        switch (tlv_detect_state)
+        {
+        case RW_T1T_SUBSTATE_WAIT_TLV_DETECT:
+            /* Search for the tag */
+            found_tlv = p_readbytes[offset++];
+            switch (found_tlv)
+            {
+            case TAG_NULL_TLV:         /* May be used for padding. SHALL ignore this */
+                break;
+
+            case TAG_NDEF_TLV:
+                if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+                {
+                    index = (offset % T1T_BLOCK_SIZE);
+                    /* Backup ndef first block */
+                    memcpy (&p_t1t->ndef_first_block[0],&p_readbytes[offset-index],index);
+                    memcpy (&p_t1t->ndef_first_block[index],&p_readbytes[offset],T1T_BLOCK_SIZE - index);
+                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+                }
+                else if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+                {
+                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+                }
+                else if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
+                         ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
+                {
+                    found = TRUE;
+                }
+                else
+                {
+                    failed = TRUE;
+                }
+                break;
+
+            case TAG_LOCK_CTRL_TLV:
+            case TAG_MEM_CTRL_TLV:
+                tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+                break;
+
+            case TAG_PROPRIETARY_TLV:
+                if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+                {
+                    index = (offset % T1T_BLOCK_SIZE);
+                    /* Backup ndef first block */
+                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+                }
+                else if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
+                         ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
+                {
+                    found = TRUE;
+                }
+                else
+                {
+                    failed = TRUE;
+                }
+                break;
+
+            case TAG_TERMINATOR_TLV:   /* Last TLV block in the data area. Must be no NDEF nessage */
+                if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
+                    ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
+                {
+                    found = TRUE;
+                }
+                else
+                {
+                    failed = TRUE;
+                }
+                break;
+            default:
+                failed = TRUE;
+            }
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+            len = p_readbytes[offset];
+            switch (found_tlv)
+            {
+            case TAG_NDEF_TLV:
+                p_t1t->ndef_header_offset = offset + p_t1t->work_offset;
+                if (len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)
+                {
+                    /* The next two bytes constitute length bytes */
+                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+                }
+                else
+                {
+                    /* one byte length field */
+                    p_t1t->ndef_msg_len = len;
+                    bytes_count  = p_t1t->ndef_msg_len;
+                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+                }
+                break;
+
+            case TAG_PROPRIETARY_TLV:
+                if (len == 0xFF)
+                {
+                    /* The next two bytes constitute length bytes */
+                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0;
+                }
+                else
+                {
+                    /* one byte length field */
+                    bytes_count  = len;
+                    tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+                }
+                break;
+            }
+            offset++;
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN0:
+            switch (found_tlv)
+            {
+            case TAG_LOCK_CTRL_TLV:
+            case TAG_MEM_CTRL_TLV:
+
+                len = p_readbytes[offset];
+                if (len == T1T_DEFAULT_TLV_LEN)
+                {
+                    /* Valid Lock control TLV */
+                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+                    bytes_count = T1T_DEFAULT_TLV_LEN;
+                }
+                else if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
+                         ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
+                {
+                    found = TRUE;
+                }
+                else
+                {
+                    failed = TRUE;
+                }
+                break;
+
+            case TAG_NDEF_TLV:
+            case TAG_PROPRIETARY_TLV:
+                /* The first length byte */
+                bytes_count  = (UINT8) p_readbytes[offset];
+                tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1;
+                break;
+            }
+            offset++;
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_READ_TLV_LEN1:
+            bytes_count  = (bytes_count << 8) + p_readbytes[offset];
+            if (found_tlv == TAG_NDEF_TLV)
+            {
+                p_t1t->ndef_msg_len = bytes_count;
+            }
+            tlv_detect_state     = RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE;
+            offset++;
+            break;
+
+        case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
+            switch (found_tlv)
+            {
+            case TAG_NDEF_TLV:
+                if ((bytes_count == p_t1t->ndef_msg_len) && (p_t1t->tlv_detect == TAG_NDEF_TLV))
+                {
+                    /* The first byte offset after length field */
+                    p_t1t->ndef_msg_offset = offset + p_t1t->work_offset;
+                }
+                if (bytes_count > 0)
+                    bytes_count--;
+
+                if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+                {
+                    if (p_t1t->ndef_msg_len > 0)
+                    {
+                        rw_t1t_update_tag_state ();
+                    }
+                    else
+                    {
+                        p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED_NDEF;
+                    }
+                    found = TRUE;
+                }
+                else if (bytes_count == 0)
+                {
+                    tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                }
+                break;
+
+            case TAG_LOCK_CTRL_TLV:
+                bytes_count--;
+                if (  (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+                    ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
+                {
+                    tlv_value[2 - bytes_count] = p_readbytes[offset];
+                    if (bytes_count == 0)
+                    {
+                        if (p_t1t->num_lock_tlvs < RW_T1T_MAX_LOCK_TLVS)
+                        {
+                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset   = (tlv_value[0] >> 4) & 0x0F;
+                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset  *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
+                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].offset  += tlv_value[0] & 0x0F;
+                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((tlv_value[2] & 0xF0) >> 4));
+                            p_t1t->lock_tlv[p_t1t->num_lock_tlvs].num_bits = tlv_value[1];
+                            count = tlv_value[1] / 8 + ((tlv_value[1] % 8 != 0)? 1:0);
+                            xx = 0;
+                            while (xx < count)
+                            {
+                                if (p_t1t->num_lockbytes < RW_T1T_MAX_LOCK_BYTES)
+                                {
+                                    p_t1t->lockbyte[p_t1t->num_lockbytes].tlv_index = p_t1t->num_lock_tlvs;
+                                    p_t1t->lockbyte[p_t1t->num_lockbytes].byte_index = xx;
+                                    p_t1t->lockbyte[p_t1t->num_lockbytes].b_lock_read = FALSE;
+                                    p_t1t->num_lockbytes++;
+                                }
+                                else
+                                    RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock bytes=0x%02X", RW_T1T_MAX_LOCK_BYTES);
+                                xx++;
+                            }
+                            p_t1t->num_lock_tlvs++;
+                            rw_t1t_update_attributes ();
+                        }
+                        else
+                            RW_TRACE_ERROR1 ("T1T Buffer overflow error. Max supported lock tlvs=0x%02X", RW_T1T_MAX_LOCK_TLVS);
+
+                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                else
+                {
+                    if (bytes_count == 0)
+                    {
+                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                break;
+
+            case TAG_MEM_CTRL_TLV:
+                bytes_count--;
+                if (  (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
+                    ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
+                {
+                    tlv_value[2 - bytes_count] = p_readbytes[offset];
+                    if (bytes_count == 0)
+                    {
+                        if (p_t1t->num_mem_tlvs >= RW_T1T_MAX_MEM_TLVS)
+                        {
+                            RW_TRACE_ERROR0 ("rw_t1t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
+                            failed  = TRUE;
+                        }
+                        else
+                        {
+                            /* Extract dynamic reserved bytes */
+                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset   = (tlv_value[0] >> 4) & 0x0F;
+                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset  *= (UINT8) tags_pow (2, tlv_value[2] & 0x0F);
+                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].offset  += tlv_value[0] & 0x0F;
+                            p_t1t->mem_tlv[p_t1t->num_mem_tlvs].num_bytes = tlv_value[1];
+                            p_t1t->num_mem_tlvs++;
+                            rw_t1t_update_attributes ();
+                            tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                        }
+                    }
+                }
+                else
+                {
+                    if (bytes_count == 0)
+                    {
+                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                break;
+
+            case TAG_PROPRIETARY_TLV:
+                bytes_count--;
+                if (p_t1t->tlv_detect == TAG_PROPRIETARY_TLV)
+                    found = TRUE;
+                else
+                {
+                    if (bytes_count == 0)
+                    {
+                        tlv_detect_state = RW_T1T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                break;
+            }
+            offset++;
+            break;
+        }
+    }
+
+    p_t1t->work_offset += bytes_read;
+
+    /* If not found and not failed, try to read next segment in Dynamic Memory structure */
+    if (!found && !failed)
+    {
+        if (  ((p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV) && (p_t1t->num_lockbytes > 0))
+            ||((p_t1t->tlv_detect == TAG_MEM_CTRL_TLV) && (p_t1t->num_mem_tlvs > 0))  )
+        {
+            found = TRUE;
+        }
+        else
+        {
+            if (p_t1t->tlv_detect == TAG_NDEF_TLV)
+            {
+                p_t1t->tag_attribute = RW_T1_TAG_ATTRB_INITIALIZED;
+            }
+            failed = TRUE;
+        }
+    }
+
+
+    status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_ndef_rall_rsp
+**
+** Description      Handle response to RALL command sent while reading an
+**                  NDEF message
+**
+** Returns          NFC_STATUS_CONTINUE, if NDEF read operation is not complete
+**                  NFC_STATUS_OK, if NDEF read is successfull
+**                  NFC_STATUS_FAILED,if NDEF read failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_rall_rsp (void)
+{
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+    tNFC_STATUS status  = NFC_STATUS_CONTINUE;
+    UINT8       count;
+    UINT8       adds;
+
+    count               = (UINT8) p_t1t->ndef_msg_offset;
+    p_t1t->work_offset  = 0;
+    p_t1t->segment      = 0;
+
+    while (count < T1T_STATIC_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
+    {
+        if (rw_t1t_is_lock_reserved_otp_byte (count) == FALSE)
+        {
+            p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_t1t->mem[count];
+            p_t1t->work_offset++;
+        }
+        count++;
+    }
+    if (p_t1t->work_offset != p_t1t->ndef_msg_len)
+    {
+        if ((p_t1t->hr[0] & 0x0F) != 1)
+        {
+            if (p_t1t->work_offset == 0)
+                return NFC_STATUS_FAILED;
+
+            else
+            {
+                p_t1t->block_read   = T1T_STATIC_BLOCKS + 1;
+                p_t1t->segment++;
+            }
+            if (p_t1t->ndef_msg_len - p_t1t->work_offset <= 8)
+            {
+                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, p_t1t->block_read, NULL)) == NFC_STATUS_OK)
+                {
+                    p_t1t->tlv_detect  = TAG_NDEF_TLV;
+                    p_t1t->state    = RW_T1T_STATE_READ_NDEF;
+                    status          = NFC_STATUS_CONTINUE;
+                }
+            }
+            else
+            {
+                /* send RSEG command */
+                RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+                if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
+                {
+                    p_t1t->state    = RW_T1T_STATE_READ_NDEF;
+                    status          = NFC_STATUS_CONTINUE;
+                }
+            }
+        }
+        else
+        {
+            RW_TRACE_ERROR1 ("RW_T1tReadNDef - Invalid NDEF len: %u or NDEF corrupted", p_t1t->ndef_msg_len);
+            status = NFC_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        status = NFC_STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_ndef_read_rsp
+**
+** Description      Handle response to commands sent while reading an
+**                  NDEF message
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv read is not yet complete
+**                  NFC_STATUS_OK, if tlv read is complete & success
+**                  NFC_STATUS_FAILED,if tlv read failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_read_rsp (UINT8 *p_data)
+{
+    tNFC_STATUS         ndef_status = NFC_STATUS_CONTINUE;
+    tRW_T1T_CB          *p_t1t      = &rw_cb.tcb.t1t;
+    UINT8               index;
+    UINT8               adds;
+    UINT8               *p_readbytes;
+    tT1T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info;
+
+    p_readbytes = p_data + T1T_ADD_LEN;
+    /* The Response received could be for Read8 or Read Segment command */
+    switch(p_cmd_rsp_info->opcode)
+    {
+    case T1T_CMD_READ8:
+        if (p_t1t->work_offset == 0)
+        {
+            index = p_t1t->ndef_msg_offset % T1T_BLOCK_SIZE;
+        }
+        else
+        {
+            index = 0;
+        }
+        p_t1t->segment = (p_t1t->block_read * T1T_BLOCK_SIZE)/T1T_SEGMENT_SIZE;
+        while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
+        {
+            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((p_t1t->block_read * T1T_BLOCK_SIZE) + index)) == FALSE)
+            {
+                p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_readbytes[index];
+                p_t1t->work_offset++;
+            }
+            index++;
+        }
+        break;
+
+    case T1T_CMD_RSEG:
+        if (p_t1t->work_offset == 0)
+        {
+            index = p_t1t->ndef_msg_offset % T1T_SEGMENT_SIZE;
+        }
+        else
+        {
+            index = 0;
+        }
+        p_t1t->block_read = ((p_t1t->segment + 1) * T1T_BLOCKS_PER_SEGMENT) - 1;
+
+        while (index < T1T_SEGMENT_SIZE && p_t1t->work_offset < p_t1t->ndef_msg_len)
+        {
+            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (index)) == FALSE)
+            {
+                p_t1t->p_ndef_buffer[p_t1t->work_offset] = p_readbytes[index];
+                p_t1t->work_offset++;
+            }
+            index++;
+        }
+        break;
+
+    default:
+        break;
+    }
+    if (p_t1t->work_offset < p_t1t->ndef_msg_len)
+    {
+        if ((p_t1t->hr[0] & 0x0F) != 1)
+        {
+            if ((p_t1t->ndef_msg_len - p_t1t->work_offset) <= T1T_BLOCK_SIZE)
+            {
+                p_t1t->block_read++;
+                if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, (UINT8) (p_t1t->block_read), NULL)) == NFC_STATUS_OK)
+                {
+                    ndef_status  = NFC_STATUS_CONTINUE;
+                }
+            }
+            else
+            {
+                p_t1t->segment++;
+                /* send RSEG command */
+                RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+                if ((ndef_status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL)) == NFC_STATUS_OK)
+                {
+                    ndef_status  = NFC_STATUS_CONTINUE;
+                }
+            }
+        }
+    }
+    else
+    {
+        ndef_status = NFC_STATUS_OK;
+    }
+    return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_next_ndef_write_block
+**
+** Description      This function prepare and writes ndef blocks
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_next_ndef_write_block (void)
+{
+    BOOLEAN     b_block_write_cmd   = FALSE;
+    tRW_T1T_CB  *p_t1t              = &rw_cb.tcb.t1t;
+    tNFC_STATUS ndef_status         = NFC_STATUS_CONTINUE;
+    UINT8       write_block[8];
+    UINT8       block;
+    UINT8       index;
+    UINT8       new_lengthfield_len;
+    UINT8       length_field[3];
+    UINT16      initial_offset;
+    UINT8       count;
+    /* Write NDEF Message */
+    new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+
+    /* Identify the command to use for NDEF write operation */
+    if ((p_t1t->hr[0] & 0x0F) != 1)
+    {
+        /* Dynamic memory structure */
+        b_block_write_cmd = FALSE;
+        block           = p_t1t->ndef_block_written + 1;
+        p_t1t->segment  = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+
+        count = 0;
+        while (block <= p_t1t->mem[T1T_CC_TMS_BYTE])
+        {
+            index = 0;
+            if (block == p_t1t->num_ndef_finalblock)
+            {
+                /* T1T_CMD_WRITE_E8 Command */
+                b_block_write_cmd = TRUE;
+                break;
+            }
+            while (index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + new_lengthfield_len))
+            {
+                if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + index)) == FALSE)
+                {
+                    count++;
+                }
+                index++;
+            }
+            if (count == T1T_BLOCK_SIZE)
+            {
+                /* T1T_CMD_WRITE_E8 Command */
+                b_block_write_cmd = TRUE;
+                break;
+            }
+            else if (count == 0)
+            {
+                index = 0;
+                block++;
+                if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
+                {
+                    p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+                }
+            }
+            else
+            {
+                /* T1T_CMD_WRITE_E Command */
+                b_block_write_cmd = FALSE;
+                break;
+            }
+        }
+    }
+    else
+    {
+        /* Static memory structure */
+        block       = p_t1t->ndef_block_written;
+        b_block_write_cmd = FALSE;
+    }
+
+    new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+    if (new_lengthfield_len == 3)
+    {
+        length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
+        length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
+        length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
+    }
+    else
+    {
+        length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
+    }
+
+    if (b_block_write_cmd)
+    {
+        /* Dynamic memory structure */
+        index           = 0;
+        p_t1t->segment  = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+
+        initial_offset  = p_t1t->work_offset;
+        block = rw_t1t_prepare_ndef_bytes (write_block, length_field,  &index, FALSE, block, new_lengthfield_len);
+        if (p_t1t->work_offset == initial_offset)
+        {
+            ndef_status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            /* Send WRITE_E8 command */
+            ndef_status = rw_t1t_send_ndef_block (write_block, block);
+        }
+    }
+    else
+    {
+        /* Static memory structure */
+        if (p_t1t->write_byte + 1 >= T1T_BLOCK_SIZE)
+        {
+            index = 0;
+            block++;
+        }
+        else
+        {
+            index       = p_t1t->write_byte + 1;
+        }
+        initial_offset  = p_t1t->work_offset;
+        block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
+        if (p_t1t->work_offset == initial_offset)
+        {
+            ndef_status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            /* send WRITE-E command */
+            ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
+        }
+    }
+    return ndef_status;
+
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_ndef_write_first_block
+**
+** Description      This function writes ndef first block
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_ndef_write_first_block (void)
+{
+    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    UINT8       block;
+    UINT8       index;
+    UINT8       new_lengthfield_len;
+    UINT8       length_field[3];
+    UINT8       write_block[8];
+
+    /* handle positive response to invalidating existing NDEF Message */
+    p_t1t->work_offset = 0;
+    new_lengthfield_len = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+    if (new_lengthfield_len == 3)
+    {
+        length_field[0] = T1T_LONG_NDEF_LEN_FIELD_BYTE0;
+        length_field[1] = (UINT8) (p_t1t->new_ndef_msg_len >> 8);
+        length_field[2] = (UINT8) (p_t1t->new_ndef_msg_len);
+    }
+    else
+    {
+        length_field[0] = (UINT8) (p_t1t->new_ndef_msg_len);
+    }
+    /* updating ndef_first_block with new ndef message */
+    memcpy(write_block,p_t1t->ndef_first_block,T1T_BLOCK_SIZE);
+    index = p_t1t->ndef_header_offset % T1T_BLOCK_SIZE;
+    block = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
+    p_t1t->segment      = (UINT8) (p_t1t->ndef_header_offset/T1T_SEGMENT_SIZE);
+
+    if ((p_t1t->hr[0] & 0x0F) != 1)
+    {
+        /* Dynamic Memory structure */
+        block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, FALSE, block, new_lengthfield_len);
+
+        if (p_t1t->work_offset == 0)
+        {
+            ndef_status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            /* Send WRITE-E8 command based on the prepared write_block */
+            ndef_status = rw_t1t_send_ndef_block (write_block, block);
+        }
+    }
+    else
+    {
+        /* Static Memory structure */
+        block = rw_t1t_prepare_ndef_bytes (write_block, length_field, &index, TRUE, block, new_lengthfield_len);
+        if (p_t1t->work_offset == 0)
+        {
+            ndef_status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            /* send WRITE-E command */
+            ndef_status = rw_t1t_send_ndef_byte (write_block[index], block, index, new_lengthfield_len);
+        }
+    }
+
+    return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_ndef_byte
+**
+** Description      Sends ndef message or length field byte and update
+**                  status
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_send_ndef_byte (UINT8 data, UINT8 block, UINT8 index, UINT8 msg_len)
+{
+    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    UINT8       addr;
+
+    /* send WRITE-E command */
+    RW_T1T_BLD_ADD ((addr), (block), (index));
+    if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, data))
+    {
+        p_t1t->write_byte           = index;
+        p_t1t->ndef_block_written   = block;
+        if (p_t1t->work_offset == p_t1t->new_ndef_msg_len + msg_len)
+        {
+            ndef_status =  NFC_STATUS_OK;
+        }
+        else
+        {
+            ndef_status = NFC_STATUS_CONTINUE;
+        }
+    }
+    else
+    {
+        ndef_status = NFC_STATUS_FAILED;
+    }
+    return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_prepare_ndef_bytes
+**
+** Description      prepares ndef block to write
+**
+** Returns          block number where to write
+**
+*******************************************************************************/
+static UINT8 rw_t1t_prepare_ndef_bytes (UINT8 *p_data, UINT8 *p_length_field, UINT8 *p_index, BOOLEAN b_one_byte, UINT8 block, UINT8 lengthfield_len)
+{
+    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
+    UINT8       first_block     = (UINT8) (p_t1t->ndef_header_offset / T1T_BLOCK_SIZE);
+    UINT16      initial_offset  = p_t1t->work_offset;
+
+    while (p_t1t->work_offset == initial_offset && block <= p_t1t->mem[T1T_CC_TMS_BYTE])
+    {
+        if (  (block == p_t1t->num_ndef_finalblock)
+            &&(block != first_block)  )
+        {
+            memcpy (p_data,p_t1t->ndef_final_block,T1T_BLOCK_SIZE);
+        }
+        /* Update length field */
+        while (  (*p_index < T1T_BLOCK_SIZE)
+               &&(p_t1t->work_offset < lengthfield_len)  )
+        {
+            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
+            {
+                p_data[*p_index] = p_length_field[p_t1t->work_offset];
+                p_t1t->work_offset++;
+                if (b_one_byte)
+                    return block;
+            }
+            (*p_index)++;
+            if (p_t1t->work_offset == lengthfield_len)
+            {
+                break;
+            }
+        }
+        /* Update ndef message field */
+        while (*p_index < T1T_BLOCK_SIZE && p_t1t->work_offset < (p_t1t->new_ndef_msg_len + lengthfield_len))
+        {
+            if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) ((block * T1T_BLOCK_SIZE) + *p_index)) == FALSE)
+            {
+                p_data[*p_index] = p_t1t->p_ndef_buffer[p_t1t->work_offset - lengthfield_len];
+                p_t1t->work_offset++;
+                if (b_one_byte)
+                    return block;
+            }
+            (*p_index)++;
+        }
+        if (p_t1t->work_offset == initial_offset)
+        {
+            *p_index = 0;
+            block++;
+            if (p_t1t->segment != (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE)
+            {
+                p_t1t->segment = (block * T1T_BLOCK_SIZE) /T1T_SEGMENT_SIZE;
+            }
+        }
+    }
+    return block;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_send_ndef_block
+**
+** Description      Sends ndef block and update status
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_send_ndef_block (UINT8 *p_data, UINT8 block)
+{
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+
+    if (NFC_STATUS_OK == rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, block, p_data))
+    {
+        p_t1t->ndef_block_written = block;
+        if (p_t1t->ndef_block_written == p_t1t->num_ndef_finalblock)
+        {
+            ndef_status  =  NFC_STATUS_OK;
+        }
+        else
+        {
+             ndef_status =  NFC_STATUS_CONTINUE;
+        }
+    }
+    else
+    {
+        ndef_status = NFC_STATUS_FAILED;
+    }
+    return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_get_ndef_flags
+**
+** Description      Prepare NDEF Flags
+**
+** Returns          NDEF Flag value
+**
+*******************************************************************************/
+static UINT8 rw_t1t_get_ndef_flags (void)
+{
+    UINT8       flags   = 0;
+    tRW_T1T_CB  *p_t1t  = &rw_cb.tcb.t1t;
+
+    if ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
+        flags |= RW_NDEF_FL_SUPPORTED;
+
+    if (t1t_tag_init_data (p_t1t->hr[0]) != NULL)
+        flags |= RW_NDEF_FL_FORMATABLE;
+
+    if ((p_t1t->mem[T1T_CC_RWA_BYTE] & 0x0F) == T1T_CC_RWA_RO)
+        flags |=RW_NDEF_FL_READ_ONLY;
+
+    return flags;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_get_ndef_max_size
+**
+** Description      Calculate maximum size of NDEF message that can be written
+**                  on to the tag
+**
+** Returns          Maximum size of NDEF Message
+**
+*******************************************************************************/
+static UINT16 rw_t1t_get_ndef_max_size (void)
+{
+    UINT16              offset;
+    tRW_T1T_CB          *p_t1t   = &rw_cb.tcb.t1t;
+    UINT16              tag_size = (p_t1t->mem[T1T_CC_TMS_BYTE] +1)* T1T_BLOCK_SIZE;
+    const tT1T_INIT_TAG *p_ret;
+    UINT8               init_segment = p_t1t->segment;
+
+    p_t1t->max_ndef_msg_len = 0;
+    offset                  = p_t1t->ndef_msg_offset;
+    p_t1t->segment          = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
+
+    if (  (tag_size < T1T_STATIC_SIZE)
+        ||(tag_size > (T1T_SEGMENT_SIZE * T1T_MAX_SEGMENTS))
+        ||((p_t1t->mem[T1T_CC_NMN_BYTE] != T1T_CC_NMN) && (p_t1t->mem[T1T_CC_NMN_BYTE] != 0))  )
+    {
+        /* Tag not formated, determine maximum NDEF size from HR */
+        if  (  ((p_t1t->hr[0] & 0xF0) == T1T_NDEF_SUPPORTED)
+             &&((p_ret = t1t_tag_init_data (p_t1t->hr[0])) != NULL)  )
+        {
+            p_t1t->max_ndef_msg_len = ((p_ret->tms +1)* T1T_BLOCK_SIZE) - T1T_OTP_LOCK_RES_BYTES - T1T_UID_LEN - T1T_ADD_LEN - T1T_CC_LEN - T1T_TLV_TYPE_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN;
+            if (p_ret->b_dynamic)
+            {
+                p_t1t->max_ndef_msg_len -= (T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN + T1T_TLV_TYPE_LEN + T1T_DEFAULT_TLV_LEN_FIELD_LEN + T1T_DEFAULT_TLV_LEN);
+                p_t1t->max_ndef_msg_len -= T1T_DYNAMIC_LOCK_BYTES;
+            }
+            offset = tag_size;
+        }
+        else
+        {
+            p_t1t->segment = init_segment;
+            return p_t1t->max_ndef_msg_len;
+        }
+    }
+
+    /* Starting from NDEF Message offset find the first locked data byte */
+    while (offset < tag_size)
+    {
+        if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) (offset)) == FALSE)
+        {
+            if (rw_t1t_is_read_only_byte ((UINT16) offset) == TRUE)
+                break;
+            p_t1t->max_ndef_msg_len++;
+        }
+        offset++;
+        if (offset % T1T_SEGMENT_SIZE == 0)
+        {
+            p_t1t->segment = (UINT8) (offset / T1T_SEGMENT_SIZE);
+        }
+    }
+    /* NDEF Length field length changes based on NDEF size */
+    if (  (p_t1t->max_ndef_msg_len >= T1T_LONG_NDEF_LEN_FIELD_BYTE0)
+        &&((p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset) == T1T_SHORT_NDEF_LEN_FIELD_LEN)  )
+    {
+        p_t1t->max_ndef_msg_len -=  (p_t1t->max_ndef_msg_len == T1T_LONG_NDEF_LEN_FIELD_BYTE0)? 1 : (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+    }
+
+    p_t1t->segment = init_segment;
+    return p_t1t->max_ndef_msg_len;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_handle_ndef_write_rsp
+**
+** Description      Handle response to commands sent while writing an
+**                  NDEF message
+**
+** Returns          NFC_STATUS_CONTINUE, if tlv write is not yet complete
+**                  NFC_STATUS_OK, if tlv write is complete & success
+**                  NFC_STATUS_FAILED,if tlv write failed
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t1t_handle_ndef_write_rsp (UINT8 *p_data)
+{
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    tNFC_STATUS ndef_status = NFC_STATUS_CONTINUE;
+    UINT8       addr;
+
+    switch (p_t1t->substate)
+    {
+    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
+        /* Backup ndef_final_block */
+        memcpy (p_t1t->ndef_final_block,p_data + T1T_ADD_LEN,T1T_BLOCK_SIZE);
+        /* Invalidate existing NDEF Message */
+        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+        if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0))
+        {
+            ndef_status     = NFC_STATUS_CONTINUE;
+            p_t1t->state    = RW_T1T_STATE_WRITE_NDEF;
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+        }
+        else
+        {
+            ndef_status = NFC_STATUS_FAILED;
+        }
+        break;
+
+    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+        ndef_status = rw_t1t_ndef_write_first_block ();
+        break;
+
+    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+        ndef_status = rw_t1t_next_ndef_write_block ();
+        break;
+
+    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+        /* Validate new NDEF Message */
+        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+        if (NFC_STATUS_OK == rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, T1T_CC_NMN))
+        {
+            ndef_status     = NFC_STATUS_OK;
+        }
+        else
+        {
+            ndef_status     = NFC_STATUS_FAILED;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return ndef_status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_update_attributes
+**
+** Description      This function will prepare attributes for the current
+**                  segment. Every bit in the attribute refers to one byte of
+**                  tag content.The bit corresponding to a tag byte will be set
+**                  to '1' when the Tag byte is read only,otherwise will be set
+**                  to '0'
+**
+** Returns          None
+**
+*******************************************************************************/
+static void rw_t1t_update_attributes (void)
+{
+    UINT8       count       = 0;
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    UINT16      lower_offset;
+    UINT16      upper_offset;
+    UINT8       num_bytes;
+    UINT16      offset;
+    UINT8       bits_per_byte  = 8;
+
+    count = 0;
+    while (count < T1T_BLOCKS_PER_SEGMENT)
+    {
+        p_t1t->attr[count] = 0x00;
+        count++;
+    }
+
+    lower_offset  = p_t1t->segment * T1T_SEGMENT_SIZE;
+    upper_offset  = (p_t1t->segment + 1)* T1T_SEGMENT_SIZE;
+
+    if (p_t1t->segment == 0)
+    {
+        /* UID/Lock/Reserved/OTP bytes */
+        p_t1t->attr[0x00] = 0xFF; /* Uid bytes */
+        p_t1t->attr[0x0D] = 0xFF; /* Reserved bytes */
+        p_t1t->attr[0x0E] = 0xFF; /* lock/otp bytes */
+        p_t1t->attr[0x0F] = 0xFF; /* lock/otp bytes */
+    }
+
+    /* update attr based on lock control and mem control tlvs */
+    count = 0;
+    while (count < p_t1t->num_lockbytes)
+    {
+        offset = p_t1t->lock_tlv[p_t1t->lockbyte[count].tlv_index].offset + p_t1t->lockbyte[count].byte_index;
+        if (offset >= lower_offset && offset < upper_offset)
+        {
+            /* Set the corresponding bit in attr to indicate - lock byte */
+            p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
+        }
+        count++;
+    }
+    count = 0;
+    while (count < p_t1t->num_mem_tlvs)
+    {
+        num_bytes = 0;
+        while (num_bytes < p_t1t->mem_tlv[count].num_bytes)
+        {
+            offset = p_t1t->mem_tlv[count].offset + num_bytes;
+            if (offset >= lower_offset && offset < upper_offset)
+            {
+                /* Set the corresponding bit in attr to indicate - reserved byte */
+                p_t1t->attr[(offset % T1T_SEGMENT_SIZE) / bits_per_byte] |= rw_t1t_mask_bits[(offset % T1T_SEGMENT_SIZE) % bits_per_byte];
+            }
+            num_bytes++;
+        }
+        count++;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_get_lock_bits_for_segment
+**
+** Description      This function will identify the index of the dynamic lock
+**                  byte that covers the current segment
+**
+** Parameters:      segment, segment number
+**                  p_start_byte, pointer to hold the first lock byte index
+**                  p_start_bit, pointer to hold the first lock bit index
+**                  p_end_byte, pointer to hold the last lock byte index
+**
+** Returns          Total lock bits that covers the specified segment
+**
+*******************************************************************************/
+static UINT8 rw_t1t_get_lock_bits_for_segment (UINT8 segment,UINT8 *p_start_byte, UINT8 *p_start_bit,UINT8 *p_end_byte)
+{
+    tRW_T1T_CB  *p_t1t              = &rw_cb.tcb.t1t;
+    UINT16      byte_count          = T1T_SEGMENT_SIZE;
+    UINT8       total_bits          = 0;
+    UINT8       num_dynamic_locks   = 0;
+    UINT8       bit_count           = 0;
+    UINT16      tag_size            = (p_t1t->mem[T1T_CC_TMS_BYTE] +1) * T1T_BLOCK_SIZE;
+    UINT16      lower_offset;
+    UINT16      upper_offset;
+    BOOLEAN     b_all_bits_are_locks = TRUE;
+    UINT8       bytes_locked_per_bit;
+    UINT8       num_bits;
+
+    upper_offset    = (segment + 1) * T1T_SEGMENT_SIZE;
+
+    if (upper_offset > tag_size)
+        upper_offset = tag_size;
+
+    lower_offset    = segment * T1T_SEGMENT_SIZE;
+    *p_start_byte   = num_dynamic_locks;
+    *p_start_bit    = 0;
+
+    while (  (byte_count <= lower_offset)
+           &&(num_dynamic_locks < p_t1t->num_lockbytes)  )
+    {
+        bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+        /* Number of bits in the current lock byte */
+        b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+        num_bits = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+        /* Skip lock bits that covers all previous segments */
+        if (bytes_locked_per_bit * num_bits + byte_count <= lower_offset)
+        {
+            byte_count += bytes_locked_per_bit * num_bits;
+            num_dynamic_locks++;
+        }
+        else
+        {
+            /* The first lock bit that covers this segment is present in this segment */
+            bit_count = 0;
+            while (bit_count < num_bits)
+            {
+                byte_count += bytes_locked_per_bit;
+                if (byte_count > lower_offset)
+                {
+                    *p_start_byte = num_dynamic_locks;
+                    *p_end_byte = num_dynamic_locks;
+                    *p_start_bit  = bit_count;
+                    bit_count++;
+                    total_bits = 1;
+                    break;
+                }
+                bit_count++;
+            }
+        }
+    }
+    if (num_dynamic_locks == p_t1t->num_lockbytes)
+    {
+        return 0;
+    }
+    while (  (byte_count < upper_offset)
+           &&(num_dynamic_locks < p_t1t->num_lockbytes)  )
+    {
+        bytes_locked_per_bit = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+
+        /* Number of bits in the current lock byte */
+        b_all_bits_are_locks = ((p_t1t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+        num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+        /* Collect all lock bits that covers the current segment */
+        if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
+        {
+            byte_count       += bytes_locked_per_bit * (num_bits - bit_count);
+            total_bits       += num_bits - bit_count;
+            bit_count         = 0;
+            *p_end_byte       = num_dynamic_locks;
+            num_dynamic_locks++;
+        }
+        else
+        {
+            /* The last lock byte that covers the current segment */
+            bit_count = 0;
+            while (bit_count < num_bits)
+            {
+                byte_count += bytes_locked_per_bit;
+                if (byte_count >= upper_offset)
+                {
+                    *p_end_byte = num_dynamic_locks;
+                    total_bits += (bit_count + 1);
+                    break;
+                }
+                bit_count++;
+            }
+        }
+    }
+    return total_bits;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_update_lock_attributes
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a locked byte and return
+**                  TRUE or FALSE
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          TRUE, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  FALSE, otherwise
+**
+*******************************************************************************/
+static void rw_t1t_update_lock_attributes (void)
+{
+    UINT8       xx = 0;
+    UINT8       bytes_locked_per_lock_bit;
+    UINT8       num_static_lock_bytes       = 0;
+    UINT8       num_dynamic_lock_bytes      = 0;
+    UINT8       bits_covered                = 0;
+    UINT8       bytes_covered               = 0;
+    UINT8       block_count                 = 0;
+    tRW_T1T_CB  *p_t1t = &rw_cb.tcb.t1t;
+    UINT8       start_lock_byte;
+    UINT8       start_lock_bit;
+    UINT8       end_lock_byte;
+    UINT8       num_lock_bits;
+    UINT8       total_bits;
+
+
+    block_count = 0;
+    while (block_count < T1T_BLOCKS_PER_SEGMENT)
+    {
+        p_t1t->lock_attr[block_count] = 0x00;
+        block_count++;
+    }
+
+    /* update lock_attr based on static lock bytes */
+    if (p_t1t->segment == 0)
+    {
+        xx                      = 0;
+        num_static_lock_bytes   = 0;
+        block_count             = 0;
+        num_lock_bits           = 8;
+
+        while (num_static_lock_bytes < T1T_NUM_STATIC_LOCK_BYTES)
+        {
+            /* Update lock attribute based on 2 static locks */
+            while (xx < num_lock_bits)
+            {
+                p_t1t->lock_attr[block_count] = 0x00;
+
+                if (p_t1t->mem[T1T_LOCK_0_OFFSET + num_static_lock_bytes] & rw_t1t_mask_bits[xx++])
+                {
+                    /* If the bit is set then 1 block is locked */
+                    p_t1t->lock_attr[block_count] = 0xFF;
+                }
+
+                block_count++;
+            }
+            num_static_lock_bytes++;
+            xx = 0;
+        }
+        /* Locked bytes */
+        p_t1t->lock_attr[0x00] = 0xFF;
+        p_t1t->lock_attr[0x0D] = 0xFF;
+    }
+    else
+    {
+        /* update lock_attr based on segment and using dynamic lock bytes */
+        if ((total_bits = rw_t1t_get_lock_bits_for_segment (p_t1t->segment,&start_lock_byte, &start_lock_bit,&end_lock_byte)) != 0)
+        {
+            xx                       = start_lock_bit;
+            num_dynamic_lock_bytes   = start_lock_byte;
+            bits_covered             = 0;
+            bytes_covered            = 0;
+            block_count              = 0;
+            num_lock_bits            = 8;
+
+            p_t1t->lock_attr[block_count] = 0;
+
+            while (num_dynamic_lock_bytes <= end_lock_byte)
+            {
+                bytes_locked_per_lock_bit   = p_t1t->lock_tlv[p_t1t->lockbyte[num_dynamic_lock_bytes].tlv_index].bytes_locked_per_bit;
+                if (num_dynamic_lock_bytes == end_lock_byte)
+                {
+                    num_lock_bits = (total_bits % 8 == 0)? 8:total_bits % 8;
+                }
+                while (xx < num_lock_bits)
+                {
+                    bytes_covered = 0;
+                    while (bytes_covered < bytes_locked_per_lock_bit)
+                    {
+                        /* Set/clear lock_attr byte bits based on whether a particular lock bit is set or not
+                         * each bit in lock_attr represents one byte in Tag read only attribute */
+                        if (p_t1t->lockbyte[num_dynamic_lock_bytes].lock_byte & rw_t1t_mask_bits[xx])
+                        {
+                            p_t1t->lock_attr[block_count] |= 0x01 << bits_covered;
+                        }
+                        bytes_covered++;
+                        bits_covered++;
+                        if (bits_covered == 8)
+                        {
+                            bits_covered = 0;
+                            block_count++;
+                            if (block_count < T1T_BLOCKS_PER_SEGMENT)
+                                p_t1t->lock_attr[block_count] = 0;
+                        }
+                    }
+                    xx++;
+                }
+                num_dynamic_lock_bytes++;
+                xx = 0;
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_is_lock_reserved_otp_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a lock or reserved or otp byte
+**
+** Parameters:      index, the index of the byte in the tag's current segment
+**
+**
+** Returns          TRUE, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t1t_is_lock_reserved_otp_byte (UINT16 index)
+{
+    tRW_T1T_CB  *p_t1t = &rw_cb.tcb.t1t;
+
+    if (p_t1t->attr_seg != p_t1t->segment)
+    {
+        /* Update p_t1t->attr to reflect the current segment */
+        rw_t1t_update_attributes ();
+        p_t1t->attr_seg = p_t1t->segment;
+    }
+    index = index % T1T_SEGMENT_SIZE;
+
+    /* Every bit in p_t1t->attr indicates one specific byte of the tag is either a lock/reserved/otp byte or not
+     * So, each array element in p_t1t->attr covers one block in the tag as T1 block size and array element size is 8
+     * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
+     * p_t1t->attr[block] is set or not. If the bit is set then it is a lock/reserved/otp byte, otherwise not */
+
+    return ((p_t1t->attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t1t_is_read_only_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a read only byte
+**
+** Parameters:      index, the index of the byte in the tag's current segment
+**
+**
+** Returns          TRUE, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t1t_is_read_only_byte (UINT16 index)
+{
+    tRW_T1T_CB  *p_t1t = &rw_cb.tcb.t1t;
+
+    if (p_t1t->lock_attr_seg != p_t1t->segment)
+    {
+        /* Update p_t1t->lock_attr to reflect the current segment */
+        rw_t1t_update_lock_attributes ();
+        p_t1t->lock_attr_seg = p_t1t->segment;
+    }
+
+    index = index % T1T_SEGMENT_SIZE;
+    /* Every bit in p_t1t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
+     * So, each array element in p_t1t->lock_attr covers one block in the tag as T1 block size and array element size is 8
+     * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
+     * p_t1t->lock_attr[block] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
+
+    return ((p_t1t->lock_attr[index /8] & rw_t1t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_REJECTED: Invalid HR0 and cannot format the tag
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tFormatNDef (void)
+{
+    tRW_T1T_CB          *p_t1t  = &rw_cb.tcb.t1t;
+    tNFC_STATUS         status  = NFC_STATUS_FAILED;
+    const tT1T_INIT_TAG *p_ret;
+    UINT8               addr;
+    UINT8               *p;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Tag not initialized/ Busy! State: %u", p_t1t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if ((p_t1t->hr[0] & 0xF0) != T1T_NDEF_SUPPORTED)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tFormatNDef - Cannot format tag as NDEF not supported. HR0: %u", p_t1t->hr[0]);
+        return (NFC_STATUS_REJECTED);
+    }
+
+    if ((p_ret = t1t_tag_init_data (p_t1t->hr[0])) == NULL)
+    {
+        RW_TRACE_WARNING2 ("RW_T1tFormatNDef - Invalid HR - HR0: %u, HR1: %u", p_t1t->hr[0], p_t1t->hr[1]);
+        return (NFC_STATUS_REJECTED);
+    }
+
+    memset (p_t1t->ndef_first_block, 0, T1T_BLOCK_SIZE);
+    memset (p_t1t->ndef_final_block, 0, T1T_BLOCK_SIZE);
+    p = p_t1t->ndef_first_block;
+
+    /* Prepare Capability Container */
+    UINT8_TO_BE_STREAM (p, T1T_CC_NMN);
+    UINT8_TO_BE_STREAM (p, T1T_CC_VNO);
+    UINT8_TO_BE_STREAM (p, p_ret->tms);
+    UINT8_TO_BE_STREAM (p, T1T_CC_RWA_RW);
+    if (p_ret->b_dynamic)
+    {
+        /* Prepare Lock and Memory TLV */
+        UINT8_TO_BE_STREAM (p, TAG_LOCK_CTRL_TLV);
+        UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
+        UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[0]);
+        UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[1]);
+        p = p_t1t->ndef_final_block;
+        UINT8_TO_BE_STREAM (p, p_ret->lock_tlv[2]);
+        UINT8_TO_BE_STREAM (p, TAG_MEM_CTRL_TLV);
+        UINT8_TO_BE_STREAM (p, T1T_DEFAULT_TLV_LEN);
+        UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[0]);
+        UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[1]);
+        UINT8_TO_BE_STREAM (p, p_ret->mem_tlv[2]);
+    }
+    /* Prepare NULL NDEF TLV */
+    UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
+    UINT8_TO_BE_STREAM (p, 0);
+
+    if (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0 || rw_cb.tcb.t1t.hr[1] >= RW_T1T_HR1_MIN)
+    {
+        /* send WRITE-E8 command */
+        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_WRITE_E8, 1, p_t1t->ndef_first_block)) == NFC_STATUS_OK)
+        {
+            p_t1t->state    = RW_T1T_STATE_FORMAT_TAG;
+            p_t1t->b_update = FALSE;
+            p_t1t->b_rseg   = FALSE;
+            if (p_ret->b_dynamic)
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC;
+            else
+                p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+        }
+    }
+    else
+    {
+        /* send WRITE-E command */
+        RW_T1T_BLD_ADD ((addr), 1, 0);
+
+        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, p_t1t->ndef_first_block[0])) == NFC_STATUS_OK)
+        {
+            p_t1t->work_offset  = 0;
+            p_t1t->state        = RW_T1T_STATE_FORMAT_TAG;
+            p_t1t->substate     = RW_T1T_SUBSTATE_WAIT_SET_NULL_NDEF;
+            p_t1t->b_update     = FALSE;
+            p_t1t->b_rseg       = FALSE;
+        }
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tLocateTlv
+**
+** Description      This function is called to find the start of the given TLV
+**
+** Parameters:      tlv_type, Type of TLV to find
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tLocateTlv (UINT8 tlv_type)
+{
+    tNFC_STATUS     status = NFC_STATUS_FAILED;
+    tRW_T1T_CB      *p_t1t= &rw_cb.tcb.t1t;
+    BOOLEAN         b_notify;
+    UINT8           adds;
+    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rall = t1t_cmd_to_rsp_info (T1T_CMD_RALL);
+    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rseg = t1t_cmd_to_rsp_info (T1T_CMD_RSEG);
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tLocateTlv - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_FAILED);
+    }
+    p_t1t->tlv_detect = tlv_type;
+
+    if(  (p_t1t->tlv_detect == TAG_NDEF_TLV)
+       &&(((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tLocateTlv - Error: NDEF not supported by the tag");
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (  (p_t1t->tlv_detect == TAG_MEM_CTRL_TLV)
+        ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
+    {
+        p_t1t->num_mem_tlvs = 0;
+    }
+
+    if (  (p_t1t->tlv_detect == TAG_LOCK_CTRL_TLV)
+        ||(p_t1t->tlv_detect == TAG_NDEF_TLV)  )
+    {
+        p_t1t->num_lockbytes = 0;
+        p_t1t->num_lock_tlvs = 0;
+    }
+
+    if (p_t1t->b_rseg == TRUE)
+    {
+        /* If already got response to RSEG 0 */
+        p_t1t->tlv_detect   = tlv_type;
+        p_t1t->work_offset  = 0;
+        p_t1t->state        = RW_T1T_STATE_TLV_DETECT;
+        p_t1t->substate     = RW_T1T_SUBSTATE_NONE;
+
+        p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rseg;
+        rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
+        status              = NFC_STATUS_OK;
+    }
+    else if (p_t1t->b_update == TRUE)
+    {
+        /* If already got response to RALL */
+        p_t1t->tlv_detect   = tlv_type;
+        p_t1t->work_offset  = 0;
+        p_t1t->state        = RW_T1T_STATE_TLV_DETECT;
+        p_t1t->substate     = RW_T1T_SUBSTATE_NONE;
+
+        p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rall;
+        rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
+        status              = NFC_STATUS_OK;
+    }
+    else
+    {
+        /* Start reading memory, looking for the TLV */
+        p_t1t->segment = 0;
+        if ((p_t1t->hr[0] & 0x0F) != 1)
+        {
+            /* send RSEG command */
+            RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+            status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
+        }
+        else
+        {
+            status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
+        }
+        if (status == NFC_STATUS_OK)
+        {
+            p_t1t->tlv_detect   = tlv_type;
+            p_t1t->work_offset  = 0;
+            p_t1t->state        = RW_T1T_STATE_TLV_DETECT;
+            p_t1t->substate     = RW_T1T_SUBSTATE_NONE;
+        }
+
+    }
+    return status;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T1tDetectNDef
+**
+** Description
+**      This function is used to perform NDEF detection on a Type 1 tag, and
+**      retrieve the tag's NDEF attribute information (block 0).
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 1 tag has been activated.
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_WRONG_PROTOCOL: type 1 tag not activated
+**      NFC_STATUS_BUSY: another command is already in progress
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T1tDetectNDef (void)
+{
+    return RW_T1tLocateTlv (TAG_NDEF_TLV);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tReadNDef
+**
+** Description      This function can be called to read the NDEF message on the tag.
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tReadNDef (UINT8 *p_buffer, UINT16 buf_len)
+{
+    tNFC_STATUS     status = NFC_STATUS_FAILED;
+    tRW_T1T_CB      *p_t1t = &rw_cb.tcb.t1t;
+    BOOLEAN         b_notify;
+    UINT8           adds;
+    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rall = t1t_cmd_to_rsp_info (T1T_CMD_RALL);
+    const tT1T_CMD_RSP_INFO *p_cmd_rsp_info_rseg = t1t_cmd_to_rsp_info (T1T_CMD_RSEG);
+
+
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tReadNDef - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Check HR0 if NDEF supported by the tag */
+    if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
+    {
+        RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF not supported by the tag");
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (p_t1t->tag_attribute  == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tReadNDef - NDEF Message length is zero, NDEF Length : %u ", p_t1t->ndef_msg_len);
+        return (NFC_STATUS_NOT_INITIALIZED);
+    }
+
+    if (  (p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_WRITE)
+        &&(p_t1t->tag_attribute != RW_T1_TAG_ATTRB_READ_ONLY)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tReadNDef - Error: NDEF detection not performed yet/ Tag is in Initialized state");
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (buf_len < p_t1t->ndef_msg_len)
+    {
+        RW_TRACE_WARNING2 ("RW_T1tReadNDef - buffer size: %u  less than NDEF msg sise: %u", buf_len, p_t1t->ndef_msg_len);
+        return (NFC_STATUS_FAILED);
+    }
+    p_t1t->p_ndef_buffer = p_buffer;
+
+    if (p_t1t->b_rseg == TRUE)
+    {
+        /* If already got response to RSEG 0 */
+        p_t1t->state = RW_T1T_STATE_READ_NDEF;
+        p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *)p_cmd_rsp_info_rseg;
+
+        rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
+        status       = NFC_STATUS_OK;
+    }
+    else if (p_t1t->b_update == TRUE)
+    {
+        /* If already got response to RALL */
+        p_t1t->state = RW_T1T_STATE_READ_NDEF;
+        p_t1t->p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) p_cmd_rsp_info_rall;
+
+        rw_t1t_handle_read_rsp (&b_notify,p_t1t->mem);
+        status       = NFC_STATUS_OK;
+
+    }
+    else
+    {
+        p_t1t->segment      = 0;
+        p_t1t->work_offset  = 0;
+        if ((p_t1t->hr[0] & 0x0F) != 1)
+        {
+            /* send RSEG command */
+            RW_T1T_BLD_ADDS ((adds), (p_t1t->segment));
+            status = rw_t1t_send_dyn_cmd (T1T_CMD_RSEG, adds, NULL);
+        }
+        else
+        {
+            status = rw_t1t_send_static_cmd (T1T_CMD_RALL, 0, 0);
+        }
+        if (status == NFC_STATUS_OK)
+            p_t1t->state = RW_T1T_STATE_READ_NDEF;
+
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tWriteNDef
+**
+** Description      This function can be called to write an NDEF message to the tag.
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
+{
+    tNFC_STATUS status          = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t          = &rw_cb.tcb.t1t;
+    UINT16      num_ndef_bytes;
+    UINT16      offset;
+    UINT8       block;
+    UINT8       addr;
+    UINT8       init_lengthfield_len;
+    UINT8       new_lengthfield_len;
+    UINT16      init_ndef_msg_offset;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tWriteNDef - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Check HR0 if NDEF supported by the tag */
+    if (((p_t1t->hr[0]) & 0xF0) != T1T_NDEF_SUPPORTED)
+    {
+        RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Error: NDEF not supported by the tag");
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (  (p_t1t->tag_attribute  != RW_T1_TAG_ATTRB_READ_WRITE)
+        &&(p_t1t->tag_attribute  != RW_T1_TAG_ATTRB_INITIALIZED_NDEF)  )
+    {
+        RW_TRACE_ERROR0 ("RW_T1tWriteNDef - Tag cannot update NDEF");
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (msg_len > p_t1t->max_ndef_msg_len)
+    {
+        RW_TRACE_ERROR1 ("RW_T1tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t1t->max_ndef_msg_len);
+        return (NFC_STATUS_REFUSED);
+    }
+
+    p_t1t->p_ndef_buffer        = p_msg;
+    p_t1t->new_ndef_msg_len     = msg_len;
+    new_lengthfield_len         = p_t1t->new_ndef_msg_len > 254 ? 3:1;
+    init_lengthfield_len        = (UINT8) (p_t1t->ndef_msg_offset - p_t1t->ndef_header_offset);
+    init_ndef_msg_offset        = p_t1t->ndef_msg_offset;
+
+    /* ndef_msg_offset should reflect the new ndef message offset */
+    if (init_lengthfield_len > new_lengthfield_len)
+    {
+        p_t1t->ndef_msg_offset  =  init_ndef_msg_offset - (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+    }
+    else if (init_lengthfield_len < new_lengthfield_len)
+    {
+        p_t1t->ndef_msg_offset  =  init_ndef_msg_offset + (T1T_LONG_NDEF_LEN_FIELD_LEN - T1T_SHORT_NDEF_LEN_FIELD_LEN);
+    }
+
+    num_ndef_bytes              = 0;
+    offset                      = p_t1t->ndef_msg_offset;
+    p_t1t->segment              = (UINT8) (p_t1t->ndef_msg_offset/T1T_SEGMENT_SIZE);
+
+    /* Locate NDEF final block based on the size of new NDEF Message */
+    while (num_ndef_bytes < p_t1t->new_ndef_msg_len)
+    {
+        if (rw_t1t_is_lock_reserved_otp_byte ((UINT16) offset) == FALSE)
+            num_ndef_bytes++;
+
+        offset++;
+        if (offset % T1T_SEGMENT_SIZE == 0)
+        {
+            p_t1t->segment      = (UINT8) (offset / T1T_SEGMENT_SIZE);
+        }
+    }
+
+    p_t1t->b_update = FALSE;
+    p_t1t->b_rseg   = FALSE;
+
+    if ((p_t1t->hr[0] & 0x0F) != 1)
+    {
+        /* Dynamic data structure */
+        block = (UINT8) ((offset - 1)/T1T_BLOCK_SIZE);
+        /* Read NDEF final block before updating */
+        if ((status = rw_t1t_send_dyn_cmd (T1T_CMD_READ8, block, NULL)) == NFC_STATUS_OK)
+        {
+            p_t1t->num_ndef_finalblock = block;
+            p_t1t->state    = RW_T1T_STATE_WRITE_NDEF;
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK;
+        }
+    }
+    else
+    {
+        /* NDEF detected and Static memory structure so send WRITE-E command */
+        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_NMN_OFFSET));
+        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_E, addr, 0)) == NFC_STATUS_OK)
+        {
+            p_t1t->state    = RW_T1T_STATE_WRITE_NDEF;
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF;
+        }
+
+    }
+
+    if (status != NFC_STATUS_OK)
+    {
+        /* if status failed, reset ndef_msg_offset to initial message */
+        p_t1t->ndef_msg_offset = init_ndef_msg_offset;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T1tSetTagReadOnly
+**
+** Description      This function can be called to set t1 tag as read only.
+**
+** Parameters:      None
+**
+** Returns          NCI_STATUS_OK, if setting tag as read only was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T1tSetTagReadOnly (BOOLEAN b_hard_lock)
+{
+    tNFC_STATUS status      = NFC_STATUS_FAILED;
+    tRW_T1T_CB  *p_t1t      = &rw_cb.tcb.t1t;
+    UINT8       addr;
+    UINT8       num_locks;
+
+    if (p_t1t->state != RW_T1T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T1tSetTagReadOnly - Busy - State: %u", p_t1t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    p_t1t->b_hard_lock = b_hard_lock;
+
+    if (  (p_t1t->tag_attribute == RW_T1_TAG_ATTRB_READ_WRITE)
+        ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED)
+        ||(p_t1t->tag_attribute == RW_T1_TAG_ATTRB_INITIALIZED_NDEF)  )
+    {
+        /* send WRITE-NE command */
+        RW_T1T_BLD_ADD ((addr), (T1T_CC_BLOCK), (T1T_CC_RWA_OFFSET));
+        if ((status = rw_t1t_send_static_cmd (T1T_CMD_WRITE_NE, addr, 0x0F)) == NFC_STATUS_OK)
+        {
+            p_t1t->b_update = FALSE;
+            p_t1t->b_rseg   = FALSE;
+
+            if (p_t1t->b_hard_lock)
+            {
+                num_locks = 0;
+                while (num_locks < p_t1t->num_lockbytes)
+                {
+                    p_t1t->lockbyte[num_locks].lock_status = RW_T1T_LOCK_NOT_UPDATED;
+                    num_locks++;
+                }
+            }
+            p_t1t->state    = RW_T1T_STATE_SET_TAG_RO;
+            p_t1t->substate = RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO;
+        }
+    }
+
+    return status;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         rw_t1t_get_sub_state_name
+**
+** Description      This function returns the sub_state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_t1t_get_sub_state_name (UINT8 sub_state)
+{
+    switch (sub_state)
+    {
+    case RW_T1T_SUBSTATE_NONE:
+        return ("NONE");
+    case RW_T1T_SUBSTATE_WAIT_READ_TLV_VALUE:
+        return ("EXTRACT_TLV_VALUE");
+    case RW_T1T_SUBSTATE_WAIT_READ_LOCKS:
+        return ("READING_LOCKS");
+    case RW_T1T_SUBSTATE_WAIT_READ_NDEF_BLOCK:
+        return ("READ_NDEF_FINAL_BLOCK");
+    case RW_T1T_SUBSTATE_WAIT_INVALIDATE_NDEF:
+        return ("INVALIDATING_NDEF");
+    case RW_T1T_SUBSTATE_WAIT_NDEF_WRITE:
+        return ("WRITE_NDEF_TLV_MESSAGE");
+    case RW_T1T_SUBSTATE_WAIT_NDEF_UPDATED:
+        return ("WAITING_RSP_FOR_LAST_NDEF_WRITE");
+    case RW_T1T_SUBSTATE_WAIT_VALIDATE_NDEF:
+        return ("VALIDATING_NDEF");
+    case RW_T1T_SUBSTATE_WAIT_SET_CC_RWA_RO:
+        return ("SET_RWA_RO");
+    case RW_T1T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+        return ("SET_STATIC_LOCK_BITS");
+    case RW_T1T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+        return ("SET_DYNAMIC_LOCK_BITS");
+
+    default:
+        return ("???? UNKNOWN SUBSTATE");
+    }
+}
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_t2t.c b/src/nfc/tags/rw_t2t.c
new file mode 100644
index 0000000..91f51f4
--- /dev/null
+++ b/src/nfc/tags/rw_t2t.c
@@ -0,0 +1,1109 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 2 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+/* Static local functions */
+static void rw_t2t_proc_data (UINT8 conn_id, tNFC_CONN_EVT event, BT_HDR *p_pkt);
+static tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat);
+static void rw_t2t_process_error (void);
+static void rw_t2t_process_frame_error (void);
+static void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status);
+static void rw_t2t_resume_op (void);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_t2t_get_state_name (UINT8 state);
+static char *rw_t2t_get_substate_name (UINT8 substate);
+#endif
+
+/*******************************************************************************
+**
+** Function         rw_t2t_proc_data
+**
+** Description      This function handles data evt received from NFC Controller.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_proc_data (UINT8 conn_id, tNFC_CONN_EVT event, BT_HDR *p_pkt)
+{
+    tRW_EVENT               rw_event    = RW_RAW_FRAME_EVT;
+    tRW_T2T_CB              *p_t2t      = &rw_cb.tcb.t2t;
+    BOOLEAN                 b_notify    = TRUE;
+    BOOLEAN                 b_release   = TRUE;
+    UINT8                   *p;
+    tRW_READ_DATA           evt_data = {0};
+    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+    tRW_DETECT_NDEF_DATA    ndef_data;
+
+    if (  (p_t2t->state == RW_T2T_STATE_IDLE)
+        ||(p_cmd_rsp_info == NULL)  )
+    {
+        RW_TRACE_DEBUG2 ("rw_t2t_proc_data - Raw frame event! state: IDLE, conn_id: %u  event: %u",
+                           conn_id, event);
+
+        evt_data.status = NFC_STATUS_OK;
+        evt_data.p_data = p_pkt;
+        (*rw_cb.p_cback) (RW_T2T_RAW_FRAME_EVT, (tRW_DATA *)&evt_data);
+        return;
+    }
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Update rx stats */
+    rw_main_update_rx_stats (p_pkt->len);
+#endif
+    /* Stop timer as response is received */
+    nfc_stop_quick_timer (&p_t2t->t2_timer);
+
+    RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+    if (  (p_pkt->len != p_cmd_rsp_info->rsp_len)
+        &&(p_pkt->len != p_cmd_rsp_info->nack_rsp_len)
+        &&(p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)  )
+    {
+#if (BT_TRACE_VERBOSE == TRUE)
+        RW_TRACE_ERROR1 ("T2T Frame error. state=%s ", rw_t2t_get_state_name (p_t2t->state));
+#else
+        RW_TRACE_ERROR1 ("T2T Frame error. state=0x%02X command=0x%02X ", p_t2t->state);
+#endif
+        /* Retrasmit the last sent command if retry-count < max retry */
+        rw_t2t_process_frame_error ();
+        GKI_freebuf (p_pkt);
+        return;
+    }
+    rw_cb.cur_retry = 0;
+
+    /* Assume the data is just the response byte sequence */
+    p = (UINT8 *) (p_pkt + 1) + p_pkt->offset;
+
+
+    RW_TRACE_EVENT5 ("rw_t2t_proc_data State: %u  conn_id: %u  event: %u  len: %u  data[0]: 0x%02x",
+                      p_t2t->state, conn_id, event, p_pkt->len, *p);
+
+    evt_data.p_data     = NULL;
+
+    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT)
+    {
+        /* The select process happens in two steps */
+        if ((*p & 0x0f) == T2T_RSP_ACK)
+        {
+            if (rw_t2t_sector_change (p_t2t->select_sector) == NFC_STATUS_OK)
+                b_notify = FALSE;
+            else
+                evt_data.status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            evt_data.status = NFC_STATUS_FAILED;
+        }
+    }
+    else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+    else if (p_pkt->len == p_cmd_rsp_info->rsp_len)
+    {
+        /* If the response length indicates positive response or cannot be known from length then assume success */
+        evt_data.status  = NFC_STATUS_OK;
+
+        /* The response data depends on what the current operation was */
+        switch (p_t2t->state)
+        {
+        case RW_T2T_STATE_CHECK_PRESENCE:
+            b_notify = FALSE;
+            rw_t2t_handle_presence_check_rsp (NFC_STATUS_OK);
+            break;
+
+        case RW_T2T_STATE_READ:
+            evt_data.p_data = p_pkt;
+            b_release = FALSE;
+            if (p_t2t->block_read == 0)
+            {
+                p_t2t->b_read_hdr = TRUE;
+                memcpy (p_t2t->tag_hdr,  p, T2T_READ_DATA_LEN);
+
+                /* On Ultralight - C tag, if CC is corrupt, correct it */
+                if (  (p_t2t->tag_hdr[0] == TAG_MIFARE_MID)
+                    &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0)
+                    &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1)  )
+                {
+                    p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC;
+                }
+            }
+            break;
+
+        case RW_T2T_STATE_WRITE:
+            /* Check positive or negative acknowledgment */
+            if ((*p & 0x0f) != T2T_RSP_ACK)
+                evt_data.status = NFC_STATUS_FAILED;
+            break;
+
+        default:
+            /* NDEF/other Tlv Operation/Format Tag/Config Tag as Read only
+             * Check if Positive response to previous write command */
+            if (  (p_cmd_rsp_info->opcode == T2T_CMD_WRITE)
+                &&((*p & 0x0f) != T2T_RSP_ACK)  )
+                evt_data.status = NFC_STATUS_FAILED;
+            else
+            {
+                b_notify = FALSE;
+                rw_t2t_handle_rsp (p);
+            }
+            break;
+        }
+    }
+    else
+    {
+        evt_data.p_data = p_pkt;
+        if (p_t2t->state == RW_T2T_STATE_READ)
+            b_release = FALSE;
+
+        /* Negative response to the command sent */
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+
+    if (b_notify)
+    {
+        rw_event = rw_t2t_info_to_event (p_cmd_rsp_info);
+        /* Move back to idle state */
+        rw_t2t_handle_op_complete ();
+        if (rw_event == RW_T2T_NDEF_DETECT_EVT)
+        {
+            ndef_data.status    = evt_data.status;
+            ndef_data.protocol  = NFC_PROTOCOL_T2T;
+            ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
+            ndef_data.max_size  = 0;
+            ndef_data.cur_size  = 0;
+            (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
+        }
+        else
+            (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
+    }
+
+    if (b_release)
+        GKI_freebuf (p_pkt);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_conn_cback
+**
+** Description      This callback function receives events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t2t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+    tRW_READ_DATA       evt_data;
+
+    RW_TRACE_DEBUG2 ("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event);
+    /* Only handle static conn_id */
+    if (conn_id != NFC_RF_CONN_ID)
+    {
+        return;
+    }
+
+    switch (event)
+    {
+    case NFC_CONN_CREATE_CEVT:
+    case NFC_CONN_CLOSE_CEVT:
+        break;
+
+    case NFC_DEACTIVATE_CEVT:
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        /* Display stats */
+        rw_main_log_stats ();
+#endif
+        /* Stop t2t timer (if started) */
+        nfc_stop_quick_timer (&p_t2t->t2_timer);
+
+        /* Free cmd buf for retransmissions */
+        if (p_t2t->p_cur_cmd_buf)
+        {
+            GKI_freebuf (p_t2t->p_cur_cmd_buf);
+            p_t2t->p_cur_cmd_buf = NULL;
+        }
+        /* Free cmd buf used to hold command before sector change */
+        if (p_t2t->p_sec_cmd_buf)
+        {
+            GKI_freebuf (p_t2t->p_sec_cmd_buf);
+            p_t2t->p_sec_cmd_buf = NULL;
+        }
+
+        p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED;
+        NFC_SetStaticRfCback (NULL);
+        break;
+
+    case NFC_DATA_CEVT:
+        if (  (p_data != NULL)
+            &&(p_data->data.status == NFC_STATUS_OK)  )
+        {
+            rw_t2t_proc_data (conn_id, event, (BT_HDR *) (p_data->data.p_data));
+            break;
+        }
+        /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+    case NFC_ERROR_CEVT:
+        if (  (p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED)
+            ||(p_t2t->state == RW_T2T_STATE_IDLE)  )
+        {
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            rw_main_update_trans_error_stats ();
+#endif  /* RW_STATS_INCLUDED */
+            if (event == NFC_ERROR_CEVT)
+                evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+            else if (p_data)
+                evt_data.status = p_data->status;
+            else
+                evt_data.status = NFC_STATUS_FAILED;
+
+            evt_data.p_data = NULL;
+            (*rw_cb.p_cback) (RW_T2T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data);
+            break;
+        }
+        nfc_stop_quick_timer (&p_t2t->t2_timer);
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        rw_main_update_trans_error_stats ();
+#endif
+        if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE)
+        {
+            rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED);
+        }
+        else
+        {
+            rw_t2t_process_error ();
+        }
+        break;
+
+    default:
+        break;
+
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_send_cmd
+**
+** Description      This function composes a Type 2 Tag command and send it via
+**                  NCI to NFCC.
+**
+** Returns          NFC_STATUS_OK if the command is successfuly sent to NCI
+**                  otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_send_cmd (UINT8 opcode, UINT8 *p_dat)
+{
+    tNFC_STATUS             status  = NFC_STATUS_FAILED;
+    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
+    const tT2T_CMD_RSP_INFO *p_cmd_rsp_info = t2t_cmd_to_rsp_info (opcode);
+    BT_HDR                  *p_data;
+    UINT8                   *p;
+
+    if (p_cmd_rsp_info)
+    {
+        /* a valid opcode for RW */
+        p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+        if (p_data)
+        {
+            p_t2t->p_cmd_rsp_info   = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
+            p_data->offset  = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p               = (UINT8 *) (p_data + 1) + p_data->offset;
+
+            UINT8_TO_STREAM (p, opcode);
+
+            if (p_dat)
+            {
+                ARRAY_TO_STREAM (p, p_dat, (p_cmd_rsp_info->cmd_len - 1));
+            }
+
+            p_data->len     = p_cmd_rsp_info->cmd_len;
+
+            /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+            rw_cb.cur_retry = 0;
+            memcpy (p_t2t->p_cur_cmd_buf, p_data, sizeof (BT_HDR) + p_data->offset + p_data->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            /* Update stats */
+            rw_main_update_tx_stats (p_data->len, FALSE);
+#endif
+            RW_TRACE_EVENT2 ("RW SENT [%s]:0x%x CMD", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode);
+
+            if ((status = NFC_SendData (NFC_RF_CONN_ID, p_data)) == NFC_STATUS_OK)
+            {
+                nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+                       (RW_T2T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000);
+            }
+            else
+            {
+#if (BT_TRACE_VERBOSE == TRUE)
+                RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=%s substate=%s ", rw_t2t_get_state_name (p_t2t->state), rw_t2t_get_substate_name (p_t2t->substate));
+#else
+                RW_TRACE_ERROR2 ("T2T NFC Send data failed. state=0x%02X substate=0x%02X ", p_t2t->state, p_t2t->substate);
+#endif
+            }
+        }
+        else
+        {
+            status = NFC_STATUS_NO_BUFFERS;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_process_timeout
+**
+** Description      handles timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t2t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    tRW_READ_DATA       evt_data;
+    tRW_T2T_CB          *p_t2t          = &rw_cb.tcb.t2t;
+
+    if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE)
+    {
+        /* Move back to idle state */
+        rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED);
+        return;
+    }
+
+    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR)
+    {
+        p_t2t->sector   = p_t2t->select_sector;
+        /* Here timeout is an acknowledgment for successfull sector change */
+        if (p_t2t->state == RW_T2T_STATE_SELECT_SECTOR)
+        {
+            /* Notify that select sector op is successfull */
+            rw_t2t_handle_op_complete ();
+            evt_data.status = NFC_STATUS_OK;
+            evt_data.p_data = NULL;
+            (*rw_cb.p_cback) (RW_T2T_SELECT_CPLT_EVT, (tRW_DATA *) &evt_data);
+        }
+        else
+        {
+            /* Resume operation from where we stopped before sector change */
+            rw_t2t_resume_op ();
+        }
+    }
+    else if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+#if (BT_TRACE_VERBOSE == TRUE)
+        RW_TRACE_ERROR1 ("T2T timeout. state=%s ", rw_t2t_get_state_name (p_t2t->state));
+#else
+        RW_TRACE_ERROR1 ("T2T timeout. state=0x%02X ", p_t2t->state);
+#endif
+        /* Handle timeout error as no response to the command sent */
+        rw_t2t_process_error ();
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_process_frame_error
+**
+** Description      handles frame crc error
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_process_frame_error (void)
+{
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Update stats */
+    rw_main_update_crc_error_stats ();
+#endif
+    /* Process the error */
+    rw_t2t_process_error ();
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_process_error
+**
+** Description      Process error including Timeout, Frame error. This function
+**                  will retry atleast till RW_MAX_RETRIES before give up and
+**                  sending negative notification to upper layer
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_process_error (void)
+{
+    tRW_READ_DATA           evt_data;
+    tRW_EVENT               rw_event;
+    BT_HDR                  *p_cmd_buf;
+    tRW_T2T_CB              *p_t2t          = &rw_cb.tcb.t2t;
+    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+    tRW_DETECT_NDEF_DATA    ndef_data;
+
+    RW_TRACE_DEBUG1 ("rw_t2t_process_error () State: %u", p_t2t->state);
+
+    /* Retry sending command if retry-count < max */
+    if (rw_cb.cur_retry < RW_MAX_RETRIES)
+    {
+        /* retry sending the command */
+        rw_cb.cur_retry++;
+
+        RW_TRACE_DEBUG2 ("T2T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
+
+        /* allocate a new buffer for message */
+        if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+        {
+            memcpy (p_cmd_buf, p_t2t->p_cur_cmd_buf, sizeof (BT_HDR) + p_t2t->p_cur_cmd_buf->offset + p_t2t->p_cur_cmd_buf->len);
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+            /* Update stats */
+            rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
+#endif
+            if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
+            {
+                /* Start timer for waiting for response */
+                nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+                                       (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+                return;
+            }
+        }
+    }
+    else
+    {
+        RW_TRACE_DEBUG1 ("T2T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
+    }
+    rw_event = rw_t2t_info_to_event (p_cmd_rsp_info);
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* update failure count */
+    rw_main_update_fail_stats ();
+#endif
+    /* If not activated remain in non activated state, otherwise move to idle state */
+    if (p_t2t->state != RW_T2T_STATE_NOT_ACTIVATED)
+        rw_t2t_handle_op_complete ();
+
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    evt_data.status = NFC_STATUS_TIMEOUT;
+    if (rw_event == RW_T2T_NDEF_DETECT_EVT)
+    {
+        ndef_data.status    = evt_data.status;
+        ndef_data.protocol  = NFC_PROTOCOL_T2T;
+        ndef_data.flags     = RW_NDEF_FL_UNKNOWN;
+        ndef_data.max_size  = 0;
+        ndef_data.cur_size  = 0;
+        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data);
+    }
+    else
+    {
+        evt_data.p_data = NULL;
+        (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data);
+    }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t2t_handle_presence_check_rsp
+**
+** Description      Handle response to presence check
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t2t_handle_presence_check_rsp (tNFC_STATUS status)
+{
+    tRW_READ_DATA   evt_data;
+
+    /* Notify, Tag is present or not */
+    evt_data.status = status;
+    rw_t2t_handle_op_complete ();
+
+    (*rw_cb.p_cback) (RW_T2T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_resume_op
+**
+** Description      This function will continue operation after moving to new
+**                  sector
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+static void rw_t2t_resume_op (void)
+{
+    tRW_T2T_CB          *p_t2t = &rw_cb.tcb.t2t;
+    tRW_READ_DATA       evt_data;
+    BT_HDR              *p_cmd_buf;
+    tRW_EVENT           event;
+    const tT2T_CMD_RSP_INFO   *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+    UINT8               *p;
+
+    /* Move back to the substate where we were before changing sector */
+    p_t2t->substate = p_t2t->prev_substate;
+
+    p              = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+    p_cmd_rsp_info = t2t_cmd_to_rsp_info ((UINT8) *p);
+    p_t2t->p_cmd_rsp_info   = (tT2T_CMD_RSP_INFO *) p_cmd_rsp_info;
+
+    /* allocate a new buffer for message */
+    if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+    {
+        memcpy (p_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len);
+        memcpy (p_t2t->p_cur_cmd_buf, p_t2t->p_sec_cmd_buf, sizeof (BT_HDR) + p_t2t->p_sec_cmd_buf->offset + p_t2t->p_sec_cmd_buf->len);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        /* Update stats */
+         rw_main_update_tx_stats (p_cmd_buf->len, TRUE);
+#endif
+        if (NFC_SendData (NFC_RF_CONN_ID, p_cmd_buf) == NFC_STATUS_OK)
+        {
+            /* Start timer for waiting for response */
+            nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+                                   (RW_T2T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+        }
+        else
+        {
+            /* failure - could not send buffer */
+            evt_data.p_data = NULL;
+            evt_data.status = NFC_STATUS_FAILED;
+            event = rw_t2t_info_to_event (p_cmd_rsp_info);
+            rw_t2t_handle_op_complete ();
+            (*rw_cb.p_cback) (event, (tRW_DATA *) &evt_data);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_sector_change
+**
+** Description      This function issues Type 2 Tag SECTOR-SELECT command
+**                  packet 1.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_sector_change (UINT8 sector)
+{
+    tNFC_STATUS status;
+    BT_HDR      *p_data;
+    UINT8       *p;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+
+    if ((p_data = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+    {
+        RW_TRACE_ERROR0 ("rw_t2t_sector_change - No buffer");
+         return (NFC_STATUS_NO_BUFFERS);
+    }
+
+    p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_data + 1) + p_data->offset;
+
+    UINT8_TO_BE_STREAM (p, sector);
+    UINT8_TO_BE_STREAM (p, 0x00);
+    UINT8_TO_BE_STREAM (p, 0x00);
+    UINT8_TO_BE_STREAM (p, 0x00);
+
+    p_data->len = 4;
+
+    if ((status = NFC_SendData (NFC_RF_CONN_ID , p_data)) == NFC_STATUS_OK)
+    {
+        /* Passive rsp command and suppose not to get response to this command */
+        p_t2t->p_cmd_rsp_info = NULL;
+        p_t2t->substate       = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR;
+
+        RW_TRACE_EVENT0 ("rw_t2t_sector_change Sent Second Command");
+        nfc_start_quick_timer (&p_t2t->t2_timer, NFC_TTYPE_RW_T2T_RESPONSE,
+                               (RW_T2T_SEC_SEL_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+    }
+    else
+    {
+        RW_TRACE_ERROR1 ("rw_t2t_sector_change Send failed at rw_t2t_send_cmd, error: %u", status);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read
+**
+** Description      This function issues Type 2 Tag READ command for the
+**                  specified block. If the specified block is in different
+**                  sector then it first sends command to move to new sector
+**                  and after the tag moves to new sector it issues the read
+**                  command for the block.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read (UINT16 block)
+{
+    tNFC_STATUS status;
+    UINT8       *p;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT8       sector_byte2[1];
+    UINT8       read_cmd[1];
+
+
+    read_cmd[0] = block % T2T_BLOCKS_PER_SECTOR;
+    if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR)
+    {
+        sector_byte2[0] = 0xFF;
+        /* First Move to new sector before sending Read command */
+        if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL,sector_byte2)) == NFC_STATUS_OK)
+        {
+            /* Prepare command that needs to be sent after sector change op is completed */
+            p_t2t->select_sector         = (UINT8) (block/T2T_BLOCKS_PER_SECTOR);
+            p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+
+            p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+            UINT8_TO_BE_STREAM (p, T2T_CMD_READ);
+            UINT8_TO_BE_STREAM (p, read_cmd[0]);
+            p_t2t->p_sec_cmd_buf->len = 2;
+            p_t2t->block_read = block;
+
+            /* Backup the current substate to move back to this substate after changing sector */
+            p_t2t->prev_substate = p_t2t->substate;
+            p_t2t->substate      = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+            return NFC_STATUS_OK;
+        }
+        return NFC_STATUS_FAILED;
+    }
+
+    /* Send Read command as sector change is not needed */
+    if ((status = rw_t2t_send_cmd (T2T_CMD_READ, (UINT8 *) read_cmd)) == NFC_STATUS_OK)
+    {
+        p_t2t->block_read = block;
+        RW_TRACE_EVENT1 ("rw_t2t_read Sent Command for Block: %u", block);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_write
+**
+** Description      This function issues Type 2 Tag WRITE command for the
+**                  specified block.  If the specified block is in different
+**                  sector then it first sends command to move to new sector
+**                  and after the tag moves to new sector it issues the write
+**                  command for the block.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write (UINT16 block, UINT8 *p_write_data)
+{
+    tNFC_STATUS status;
+    UINT8       *p;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT8       write_cmd[T2T_WRITE_DATA_LEN + 1];
+    UINT8       sector_byte2[1];
+
+    p_t2t->block_written = block;
+    write_cmd[0] = (UINT8) (block%T2T_BLOCKS_PER_SECTOR);
+    memcpy (&write_cmd[1], p_write_data, T2T_WRITE_DATA_LEN);
+
+    if (p_t2t->sector != block/T2T_BLOCKS_PER_SECTOR)
+    {
+        sector_byte2[0] = 0xFF;
+        /* First Move to new sector before sending Write command */
+        if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK)
+        {
+            /* Prepare command that needs to be sent after sector change op is completed */
+            p_t2t->select_sector         = (UINT8) (block/T2T_BLOCKS_PER_SECTOR);
+            p_t2t->p_sec_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+            p = (UINT8 *) (p_t2t->p_sec_cmd_buf + 1) + p_t2t->p_sec_cmd_buf->offset;
+            UINT8_TO_BE_STREAM (p, T2T_CMD_WRITE);
+            memcpy (p, write_cmd, T2T_WRITE_DATA_LEN + 1);
+            p_t2t->p_sec_cmd_buf->len   = 2 + T2T_WRITE_DATA_LEN;
+            p_t2t->block_written  = block;
+
+            /* Backup the current substate to move back to this substate after changing sector */
+            p_t2t->prev_substate        = p_t2t->substate;
+            p_t2t->substate             = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+            return NFC_STATUS_OK;
+        }
+        return NFC_STATUS_FAILED;
+    }
+
+    /* Send Write command as sector change is not needed */
+    if ((status = rw_t2t_send_cmd (T2T_CMD_WRITE, write_cmd)) == NFC_STATUS_OK)
+    {
+        RW_TRACE_EVENT1 ("rw_t2t_write Sent Command for Block: %u", block);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_select
+**
+** Description      This function selects type 2 tag.
+**
+** Returns          Tag selection status
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_select (void)
+{
+    tRW_T2T_CB    *p_t2t = &rw_cb.tcb.t2t;
+
+    p_t2t->state       = RW_T2T_STATE_IDLE;
+    p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
+
+
+    /* Alloc cmd buf for retransmissions */
+    if (p_t2t->p_cur_cmd_buf ==  NULL)
+    {
+        if ((p_t2t->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+        {
+            RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer for retransmission");
+            return (NFC_STATUS_FAILED);
+        }
+    }
+    /* Alloc cmd buf for holding a command untill sector changes */
+    if (p_t2t->p_sec_cmd_buf ==  NULL)
+    {
+        if ((p_t2t->p_sec_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+        {
+            RW_TRACE_ERROR0 ("rw_t2t_select: unable to allocate buffer used during sector change");
+            return (NFC_STATUS_FAILED);
+        }
+    }
+
+    NFC_SetStaticRfCback (rw_t2t_conn_cback);
+    rw_t2t_handle_op_complete ();
+
+    return NFC_STATUS_OK;
+}
+
+/*****************************************************************************
+**
+** Function         rw_t2t_handle_op_complete
+**
+** Description      Reset to IDLE state
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t2t_handle_op_complete (void)
+{
+    tRW_T2T_CB      *p_t2t  = &rw_cb.tcb.t2t;
+
+    p_t2t->state    = RW_T2T_STATE_IDLE;
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    return;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T2tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T2T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tPresenceCheck (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_DATA evt_data;
+    tRW_CB *p_rw_cb = &rw_cb;
+    UINT8 sector_blk = 0;           /* block 0 of current sector */
+
+    RW_TRACE_API0 ("RW_T2tPresenceCheck");
+
+    /* If RW_SelectTagType was not called (no conn_callback) return failure */
+    if (!p_rw_cb->p_cback)
+    {
+        retval = NFC_STATUS_FAILED;
+    }
+    /* If we are not activated, then RW_T2T_PRESENCE_CHECK_EVT status=FAIL */
+    else if (p_rw_cb->tcb.t2t.state == RW_T2T_STATE_NOT_ACTIVATED)
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+        (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    /* If command is pending, assume tag is still present */
+    else if (p_rw_cb->tcb.t2t.state != RW_T2T_STATE_IDLE)
+    {
+        evt_data.status = NFC_STATUS_OK;
+        (*p_rw_cb->p_cback) (RW_T2T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    else
+    {
+        /* IDLE state: send a READ command to block 0 of the current sector */
+        if((retval = rw_t2t_send_cmd (T2T_CMD_READ, &sector_blk))== NFC_STATUS_OK)
+        {
+            p_rw_cb->tcb.t2t.state = RW_T2T_STATE_CHECK_PRESENCE;
+        }
+    }
+
+    return (retval);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tRead
+**
+** Description      This function issues the Type 2 Tag READ command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_READ_EVT.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tRead (UINT16 block)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
+    {
+        p_t2t->state    = RW_T2T_STATE_READ;
+        RW_TRACE_EVENT0 ("RW_T2tRead Sent Read command");
+    }
+
+    return status;
+
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tWrite
+**
+** Description      This function issues the Type 2 Tag WRITE command. When the
+**                  operation is complete the callback function will be called
+**                  with a RW_T2T_WRITE_EVT.
+**
+**                  p_new_bytes points to the array of 4 bytes to be written
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tWrite (UINT16 block, UINT8 *p_write_data)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if ((status = rw_t2t_write (block, p_write_data)) == NFC_STATUS_OK)
+    {
+        p_t2t->state    = RW_T2T_STATE_WRITE;
+        if (block < T2T_FIRST_DATA_BLOCK)
+            p_t2t->b_read_hdr = FALSE;
+        else if (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
+            p_t2t->b_read_data = FALSE;
+        RW_TRACE_EVENT0 ("RW_T2tWrite Sent Write command");
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tSectorSelect
+**
+** Description      This function issues the Type 2 Tag SECTOR-SELECT command
+**                  packet 1. If a NACK is received as the response, the callback
+**                  function will be called with a RW_T2T_SECTOR_SELECT_EVT. If
+**                  an ACK is received as the response, the command packet 2 with
+**                  the given sector number is sent to the peer device. When the
+**                  response for packet 2 is received, the callback function will
+**                  be called with a RW_T2T_SECTOR_SELECT_EVT.
+**
+**                  A sector is 256 contiguous blocks (1024 bytes).
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tSectorSelect (UINT8 sector)
+{
+    tNFC_STATUS status;
+    tRW_T2T_CB  *p_t2t       = &rw_cb.tcb.t2t;
+    UINT8       sector_byte2[1];
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (sector >= T2T_MAX_SECTOR)
+    {
+        RW_TRACE_ERROR2 ("RW_T2tSectorSelect - Invalid sector: %u, T2 Max supported sector value: %u", sector, T2T_MAX_SECTOR - 1);
+        return (NFC_STATUS_FAILED);
+    }
+
+    sector_byte2[0] = 0xFF;
+
+    if ((status = rw_t2t_send_cmd (T2T_CMD_SEC_SEL, sector_byte2)) == NFC_STATUS_OK)
+    {
+        p_t2t->state         = RW_T2T_STATE_SELECT_SECTOR;
+        p_t2t->select_sector = sector;
+        p_t2t->substate      = RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT;
+
+        RW_TRACE_EVENT0 ("RW_T2tSectorSelect Sent Sector select first command");
+    }
+
+    return status;
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         rw_t2t_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_t2t_get_state_name (UINT8 state)
+{
+    switch (state)
+    {
+    case RW_T2T_STATE_NOT_ACTIVATED:
+        return ("NOT_ACTIVATED");
+    case RW_T2T_STATE_IDLE:
+        return ("IDLE");
+    case RW_T2T_STATE_READ:
+        return ("APP_READ");
+    case RW_T2T_STATE_WRITE:
+        return ("APP_WRITE");
+    case RW_T2T_STATE_SELECT_SECTOR:
+        return ("SECTOR_SELECT");
+    case RW_T2T_STATE_DETECT_TLV:
+        return ("TLV_DETECT");
+    case RW_T2T_STATE_READ_NDEF:
+        return ("READ_NDEF");
+    case RW_T2T_STATE_WRITE_NDEF:
+        return ("WRITE_NDEF");
+    case RW_T2T_STATE_SET_TAG_RO:
+        return ("SET_TAG_RO");
+    case RW_T2T_STATE_CHECK_PRESENCE:
+        return ("CHECK_PRESENCE");
+    default:
+        return ("???? UNKNOWN STATE");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_substate_name
+**
+** Description      This function returns the substate name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_t2t_get_substate_name (UINT8 substate)
+{
+    switch (substate)
+    {
+    case RW_T2T_SUBSTATE_NONE:
+        return ("RW_T2T_SUBSTATE_NONE");
+    case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT:
+        return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT");
+    case RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR:
+        return ("RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR");
+    case RW_T2T_SUBSTATE_WAIT_READ_CC:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_CC");
+    case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
+        return ("RW_T2T_SUBSTATE_WAIT_TLV_DETECT");
+    case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+        return ("RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN");
+    case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0");
+    case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1");
+    case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE");
+    case RW_T2T_SUBSTATE_WAIT_READ_LOCKS:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_LOCKS");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
+        return ("RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK");
+    case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
+        return ("RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT");
+    default:
+        return ("???? UNKNOWN SUBSTATE");
+    }
+}
+
+#endif /* (BT_TRACE_VERBOSE == TRUE) */
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/nfc/tags/rw_t2t_ndef.c b/src/nfc/tags/rw_t2t_ndef.c
new file mode 100644
index 0000000..a258aef
--- /dev/null
+++ b/src/nfc/tags/rw_t2t_ndef.c
@@ -0,0 +1,3178 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 2 tag NDEF operation in
+ *  Reader/Writer mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "nfc_int.h"
+#include "gki.h"
+
+#if (defined (RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE))
+
+/* Local static functions */
+static void rw_t2t_handle_cc_read_rsp (void);
+static void rw_t2t_handle_lock_read_rsp (UINT8 *p_data);
+static void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data);
+static void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data);
+static void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data);
+static void rw_t2t_handle_format_tag_rsp (UINT8 *p_data);
+static void rw_t2t_handle_config_tag_readonly (UINT8 *p_data);
+static UINT8 rw_t2t_get_tag_size (UINT8 *p_data);
+static void rw_t2t_extract_default_locks_info (void);
+static void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len);
+static UINT8 rw_t2t_get_ndef_flags (void);
+static UINT16 rw_t2t_get_ndef_max_size (void);
+static tNFC_STATUS rw_t2t_read_locks (void);
+static tNFC_STATUS rw_t2t_read_ndef_last_block (void);
+static void rw_t2t_update_attributes (void);
+static void rw_t2t_update_lock_attributes (void);
+static BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index);
+static BOOLEAN rw_t2t_is_read_only_byte (UINT16 index);
+static tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len);
+static tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len);
+static tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block);
+static tNFC_STATUS rw_t2t_add_terminator_tlv (void);
+static BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read);
+static tNFC_STATUS rw_t2t_set_cc (UINT8 tms);
+static tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size);
+static tNFC_STATUS rw_t2t_format_tag (void);
+static tNFC_STATUS rw_t2t_soft_lock_tag (void);
+static tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data);
+static void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status);
+
+const UINT8 rw_t2t_mask_bits[8] =
+{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_rsp
+**
+** Description      This function handles response to command sent during
+**                  NDEF and other tlv operation
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t2t_handle_rsp (UINT8 *p_data)
+{
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+
+    if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
+    {
+        p_t2t->b_read_hdr = TRUE;
+        memcpy (p_t2t->tag_hdr,  p_data, T2T_READ_DATA_LEN);
+
+        /* On Ultralight - C tag, if CC is corrupt, correct it */
+        if (  (p_t2t->tag_hdr[0] == TAG_MIFARE_MID)
+            &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0)
+            &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1)  )
+        {
+            p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC;
+        }
+    }
+
+    switch (p_t2t->state)
+    {
+    case RW_T2T_STATE_DETECT_TLV:
+        if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV)
+        {
+            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
+            {
+                rw_t2t_handle_cc_read_rsp ();
+            }
+            else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
+            {
+                rw_t2t_handle_lock_read_rsp (p_data);
+            }
+            else
+            {
+                rw_t2t_handle_tlv_detect_rsp (p_data);
+            }
+        }
+        else if (p_t2t->tlv_detect == TAG_NDEF_TLV)
+        {
+            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
+            {
+                if (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] == T2T_CC0_NMN)
+                {
+                    rw_t2t_handle_cc_read_rsp ();
+                }
+                else
+                {
+                    RW_TRACE_WARNING3 ("NDEF Detection failed!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: 0x%02x", p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE], p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+                    rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+                }
+            }
+            else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS)
+            {
+                rw_t2t_handle_lock_read_rsp (p_data);
+            }
+            else
+            {
+                rw_t2t_handle_tlv_detect_rsp (p_data);
+            }
+        }
+        else
+        {
+            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC)
+            {
+                rw_t2t_handle_cc_read_rsp ();
+            }
+            else
+            {
+                rw_t2t_handle_tlv_detect_rsp (p_data);
+            }
+        }
+        break;
+
+    case RW_T2T_STATE_SET_TAG_RO:
+        rw_t2t_handle_config_tag_readonly (p_data);
+        break;
+
+    case RW_T2T_STATE_FORMAT_TAG:
+        rw_t2t_handle_format_tag_rsp (p_data);
+        break;
+
+    case RW_T2T_STATE_READ_NDEF:
+        rw_t2t_handle_ndef_read_rsp (p_data);
+        break;
+
+    case RW_T2T_STATE_WRITE_NDEF:
+        rw_t2t_handle_ndef_write_rsp (p_data);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_info_to_event
+**
+** Description      This function returns RW event code based on the current state
+**
+** Returns          RW event code
+**
+*******************************************************************************/
+tRW_EVENT rw_t2t_info_to_event (const tT2T_CMD_RSP_INFO *p_info)
+{
+    tRW_EVENT   rw_event;
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+
+    switch (p_t2t->state)
+    {
+    case RW_T2T_STATE_DETECT_TLV:
+        if (p_t2t->tlv_detect == TAG_NDEF_TLV)
+            rw_event = RW_T2T_NDEF_DETECT_EVT;
+        else
+            rw_event = RW_T2T_TLV_DETECT_EVT;
+
+        break;
+
+    case RW_T2T_STATE_READ_NDEF:
+        rw_event = RW_T2T_NDEF_READ_EVT;
+        break;
+
+    case RW_T2T_STATE_WRITE_NDEF:
+        rw_event = RW_T2T_NDEF_WRITE_EVT;
+        break;
+
+    case RW_T2T_STATE_SET_TAG_RO:
+        rw_event = RW_T2T_SET_TAG_RO_EVT;
+        break;
+
+    case RW_T2T_STATE_CHECK_PRESENCE:
+        rw_event = RW_T2T_PRESENCE_CHECK_EVT;
+        break;
+
+    case RW_T2T_STATE_FORMAT_TAG:
+        rw_event = RW_T2T_FORMAT_CPLT_EVT;
+        break;
+
+    default:
+	    rw_event = t2t_info_to_evt (p_info);
+        break;
+    }
+    return rw_event;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_cc_read_rsp
+**
+** Description      Handle read cc bytes
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_cc_read_rsp (void)
+{
+    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
+
+    if (  (  (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
+           &&(p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RO)  )
+                                    ||
+          (  (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO)
+           &&(p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO)
+           &&(p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO)  )  )
+    {
+        /* Invalid Version number or RWA byte */
+        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+        return;
+    }
+
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+
+    if (rw_t2t_read ((UINT16) T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK)
+    {
+        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_ntf_tlv_detect_complete
+**
+** Description      Notify TLV detection complete to upper layer
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_ntf_tlv_detect_complete (tNFC_STATUS status)
+{
+    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
+    tRW_DETECT_NDEF_DATA    ndef_data = {0};
+    tRW_DETECT_TLV_DATA     tlv_data;
+    tRW_T2T_DETECT          evt_data;
+    UINT8                   xx;
+
+    if (p_t2t->tlv_detect == TAG_NDEF_TLV)
+    {
+        /* Notify upper layer the result of NDEF detect op */
+        ndef_data.status    = status;
+        ndef_data.protocol  = NFC_PROTOCOL_T2T;
+        ndef_data.flags     = rw_t2t_get_ndef_flags ();
+        ndef_data.cur_size  = p_t2t->ndef_msg_len;
+
+        if (status == NFC_STATUS_OK)
+            ndef_data.flags   |= RW_NDEF_FL_FORMATED;
+
+        if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW)
+            ndef_data.max_size = (UINT32) rw_t2t_get_ndef_max_size ();
+        else
+            ndef_data.max_size = ndef_data.cur_size;
+
+        if (ndef_data.max_size < ndef_data.cur_size)
+        {
+            ndef_data.flags   |= RW_NDEF_FL_READ_ONLY;
+            ndef_data.max_size = ndef_data.cur_size;
+        }
+
+        if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY))
+        {
+            ndef_data.flags  |= RW_NDEF_FL_SOFT_LOCKABLE;
+            if (status == NFC_STATUS_OK)
+                ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
+        }
+
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_NDEF_DETECT_EVT, (tRW_DATA *) &ndef_data);
+    }
+    else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV)
+    {
+        evt_data.msg_len = p_t2t->prop_msg_len;
+        evt_data.status  = status;
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &evt_data);
+    }
+    else
+    {
+        /* Notify upper layer the result of Lock/Mem TLV detect op */
+        tlv_data.protocol   = NFC_PROTOCOL_T2T;
+        if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV)
+        {
+            tlv_data.num_bytes  = p_t2t->num_lockbytes;
+        }
+        else
+        {
+            tlv_data.num_bytes = 0;
+            for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+            {
+                tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes;
+            }
+        }
+        tlv_data.status     = status;
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_TLV_DETECT_EVT, (tRW_DATA *) &tlv_data);
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_lock_read_rsp
+**
+** Description      Handle response to reading lock bytes
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_lock_read_rsp (UINT8 *p_data)
+{
+    UINT8                   updated_lock_byte;
+    UINT8                   num_locks;
+    UINT8                   offset = 0;
+    UINT16                  lock_offset;
+    UINT16                  base_lock_offset = 0;
+    tRW_T2T_CB              *p_t2t  = &rw_cb.tcb.t2t;
+    UINT16                  block;
+
+    /* Prepare NDEF/TLV attributes (based on current op) for sending response to upper layer */
+
+    num_locks = 0;
+    updated_lock_byte = 0;
+
+    /*  Extract all lock bytes present in the read 16 bytes
+     *  but atleast one lock byte (base lock) should be present in the read 16 bytes */
+
+    while (num_locks < p_t2t->num_lockbytes)
+    {
+        if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE)
+        {
+            lock_offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
+            if (updated_lock_byte == 0)
+            {
+                /* The offset of the first lock byte present in the 16 bytes read using READ command */
+                base_lock_offset = lock_offset;
+                /* Block number used to read may not be the block where lock offset is present */
+                offset = (UINT8) (lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
+                /* Update the lock byte value in the control block */
+                p_t2t->lockbyte[num_locks].lock_byte = p_data[offset];
+                p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
+                updated_lock_byte++;
+            }
+            else if (lock_offset > base_lock_offset)
+            {
+                /* Atleast one lock byte will get updated in the control block */
+                if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN)
+                {
+                    /* And this lock byte is also present in the read data */
+                    p_t2t->lockbyte[num_locks].lock_byte   = p_data[lock_offset - base_lock_offset + offset];
+                    p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
+                    updated_lock_byte++;
+                }
+                else
+                {
+                    /* This lock byte is not present in the read data */
+                    block  = (UINT16) (lock_offset / T2T_BLOCK_LEN);
+                    block -= block % T2T_READ_BLOCKS;
+                    /* send READ command to read this lock byte */
+                    if (NFC_STATUS_OK != rw_t2t_read ((UINT16) block))
+                    {
+                        /* Unable to send Read command, notify failure status to upper layer */
+                        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+                    }
+                    break;
+                }
+            }
+            else
+            {
+                /* This Lock byte is not present in the read 16 bytes
+                 * send READ command to read the lock byte       */
+                if (NFC_STATUS_OK != rw_t2t_read ((UINT16) (lock_offset / T2T_BLOCK_LEN)))
+                {
+                    /* Unable to send Read command, notify failure status to upper layer */
+                    rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+                }
+                break;
+            }
+        }
+        num_locks++;
+    }
+    if (num_locks == p_t2t->num_lockbytes)
+    {
+        /* All locks are read, notify upper layer */
+        rw_t2t_update_lock_attributes ();
+        rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_OK);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_tlv_detect_rsp
+**
+** Description      Handle TLV detection.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_tlv_detect_rsp (UINT8 *p_data)
+{
+    tRW_T2T_CB              *p_t2t = &rw_cb.tcb.t2t;
+    UINT16                  offset;
+    UINT16                  len = 0;
+    BOOLEAN                 failed = FALSE;
+    BOOLEAN                 found  = FALSE;
+    tRW_EVENT               event;
+    UINT8                   index;
+    UINT8                   count = 0;
+    UINT8                   xx;
+    tNFC_STATUS             status;
+    tT2T_CMD_RSP_INFO       *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info;
+    UINT8                   tlvtype = p_t2t->tlv_detect;
+
+    if (p_t2t->work_offset == 0)
+    {
+        /* Skip UID,Static Lock block,CC*/
+        p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN;
+        p_t2t->b_read_data = TRUE;
+        memcpy (p_t2t->tag_data,  p_data, T2T_READ_DATA_LEN);
+    }
+
+    p_t2t->segment = 0;
+
+    for (offset = 0; offset < T2T_READ_DATA_LEN  && !failed && !found;)
+    {
+        if (rw_t2t_is_lock_res_byte ((UINT16) (p_t2t->work_offset + offset)) == TRUE)
+        {
+            /* Skip locks, reserved bytes while searching for TLV */
+            offset++;
+            continue;
+        }
+        switch (p_t2t->substate)
+        {
+        case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
+            /* Search for the tlv */
+            p_t2t->found_tlv = p_data[offset++];
+            switch (p_t2t->found_tlv)
+            {
+            case TAG_NULL_TLV:         /* May be used for padding. SHALL ignore this */
+                break;
+
+            case TAG_NDEF_TLV:
+                if (tlvtype == TAG_NDEF_TLV)
+                {
+                    /* NDEF Detected, now collect NDEF Attributes including NDEF Length */
+                    index = (offset % T2T_BLOCK_SIZE);
+                    /* Backup ndef first block */
+                    memcpy (p_t2t->ndef_first_block,&p_data[offset-index],index);
+                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+                }
+                else if (tlvtype == TAG_PROPRIETARY_TLV)
+                {
+                    /* Proprietary TLV can exist after NDEF Tlv so we continue searching */
+                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+                }
+                else if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+                         ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
+                {
+                    /* Lock / Memory control tlv cannot exist after NDEF TLV
+                     * So when NDEF is found, we stop searching for Lock and Memory control tlv */
+                    found = TRUE;
+                }
+                else
+                {
+                    /* While searching for Lock / Memory control tlv, if NDEF TLV is found
+                     * first then our search for Lock /Memory control tlv failed and we stop here */
+                    failed = TRUE;
+                }
+                break;
+
+            case TAG_LOCK_CTRL_TLV:
+            case TAG_MEM_CTRL_TLV:
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+                break;
+
+            case TAG_PROPRIETARY_TLV:
+                if (tlvtype == TAG_PROPRIETARY_TLV)
+                {
+                    index = (offset % T2T_BLOCK_SIZE);
+                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
+                }
+                else if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+                         ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
+                {
+                    /* We stop searching for Lock/Memory control Tlv if a proprietary tlv is found */
+                    found = TRUE;
+                }
+                else
+                {
+                    /* NDEF, Lock control TLV, Memory control tlv cannot exist after proprietary TLV */
+                    failed = TRUE;
+                }
+                break;
+
+            case TAG_TERMINATOR_TLV:   /* Last TLV block in the data area. Must be no NDEF nessage */
+                if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+                    ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
+                {
+                    /* No more Lock/Memory TLV control tlv in the tag, so stop searching */
+                    found = TRUE;
+                }
+                else
+                {
+                    /* NDEF/Lock/Memory/Proprietary TLV cannot exist after Terminator Tlv */
+                    failed = TRUE;
+                }
+                break;
+            default:
+                failed = TRUE;
+            }
+            break;
+
+        case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
+            len = p_data[offset];
+            switch (p_t2t->found_tlv)
+            {
+            case TAG_NDEF_TLV:
+                p_t2t->ndef_header_offset = offset + p_t2t->work_offset;
+                if (len == TAG_LONG_NDEF_LEN_FIELD_BYTE0)
+                {
+                    /* The next two bytes constitute length bytes */
+                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+                }
+                else
+                {
+                    /* one byte length field */
+                    p_t2t->ndef_msg_len = len;
+                    p_t2t->bytes_count  = p_t2t->ndef_msg_len;
+                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+                }
+                break;
+
+            case TAG_PROPRIETARY_TLV:
+                if (len == T2T_LONG_NDEF_LEN_FIELD_BYTE0)
+                {
+                    /* The next two bytes constitute length bytes */
+                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
+                }
+                else
+                {
+                    /* one byte length field */
+                    p_t2t->prop_msg_len = len;
+                    p_t2t->bytes_count  = p_t2t->prop_msg_len;
+                    p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+                }
+                break;
+            }
+            offset++;
+            break;
+
+        case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
+            switch (p_t2t->found_tlv)
+            {
+            case TAG_LOCK_CTRL_TLV:
+            case TAG_MEM_CTRL_TLV:
+
+                len = p_data[offset];
+                if (len == TAG_DEFAULT_TLV_LEN)
+                {
+                    /* Valid Lock control TLV */
+                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+                    p_t2t->bytes_count = TAG_DEFAULT_TLV_LEN;
+                }
+                else if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+                         ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
+                {
+                    /* Stop searching for Lock/ Memory control tlv */
+                    found = TRUE;
+                }
+                else
+                {
+                    failed = TRUE;
+                }
+                break;
+
+            case TAG_NDEF_TLV:
+            case TAG_PROPRIETARY_TLV:
+                /* The first length byte */
+                p_t2t->bytes_count  = (UINT8) p_data[offset];
+                p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1;
+                break;
+            }
+            offset++;
+            break;
+
+        case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
+            /* Prepare NDEF Message length */
+            p_t2t->bytes_count  = (p_t2t->bytes_count << 8) + p_data[offset];
+            if (p_t2t->found_tlv == TAG_NDEF_TLV)
+            {
+                p_t2t->ndef_msg_len = p_t2t->bytes_count;
+            }
+            else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV)
+            {
+                p_t2t->prop_msg_len = p_t2t->bytes_count;
+            }
+            p_t2t->substate     = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+            offset++;
+            break;
+
+        case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
+            switch (p_t2t->found_tlv)
+            {
+            case TAG_NDEF_TLV:
+                if (  (p_t2t->bytes_count == p_t2t->ndef_msg_len)
+                    &&(tlvtype == TAG_NDEF_TLV)  )
+                {
+                    /* The first byte offset after length field */
+                    p_t2t->ndef_msg_offset = offset + p_t2t->work_offset;
+                }
+                /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */
+                if (p_t2t->bytes_count > 0)
+                    p_t2t->bytes_count--;
+
+                if (tlvtype == TAG_NDEF_TLV)
+                {
+                    found = TRUE;
+                    p_t2t->ndef_status = T2T_NDEF_DETECTED;
+                }
+                else if (p_t2t->bytes_count == 0)
+                {
+                    /* Next byte could be a different TLV */
+                    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                }
+                break;
+
+            case TAG_LOCK_CTRL_TLV:
+                p_t2t->bytes_count--;
+                if (  (tlvtype == TAG_LOCK_CTRL_TLV)
+                    ||(tlvtype == TAG_NDEF_TLV)  )
+                {
+                    /* Collect Lock TLV */
+                    p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
+                    if (p_t2t->bytes_count == 0)
+                    {
+                        /* Lock TLV is collected and buffered in tlv_value, now decode it */
+                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset   = (p_t2t->tlv_value[0] >> 4) & 0x0F;
+                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset  *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F);
+                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset  += p_t2t->tlv_value[0] & 0x0F;
+                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit = (UINT8) tags_pow (2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
+                        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = p_t2t->tlv_value[1];
+                        count = p_t2t->tlv_value[1] / 8 + ((p_t2t->tlv_value[1]%8 != 0)? 1:0);
+
+                        /* Extract lockbytes info addressed by this Lock TLV */
+                        xx = 0;
+                        while (xx < count)
+                        {
+                            p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index     = p_t2t->num_lock_tlvs;
+                            p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index    = xx;
+                            p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read   = FALSE;
+                            xx++;
+                            p_t2t->num_lockbytes++;
+                        }
+                        p_t2t->num_lock_tlvs++;
+                        rw_t2t_update_attributes ();
+                        /* Next byte could be a different TLV */
+                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                else
+                {
+                    /* If not looking for lock/ndef tlv, just skip this Lock TLV */
+                    if (p_t2t->bytes_count == 0)
+                    {
+                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                break;
+
+            case TAG_MEM_CTRL_TLV:
+                p_t2t->bytes_count--;
+                if (  (tlvtype == TAG_MEM_CTRL_TLV)
+                    ||(tlvtype == TAG_NDEF_TLV)  )
+                {
+                    p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
+                    if (p_t2t->bytes_count == 0)
+                    {
+                        if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS)
+                        {
+                            RW_TRACE_ERROR0 ("rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated for Memory tlv has reached");
+                            failed  = TRUE;
+                        }
+                        else
+                        {
+                            /* Extract memory control tlv */
+                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset    = (p_t2t->tlv_value[0] >> 4) & 0x0F;
+                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset   *= (UINT8) tags_pow (2, p_t2t->tlv_value[2] & 0x0F);
+                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset   += p_t2t->tlv_value[0] & 0x0F;
+                            p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes = p_t2t->tlv_value[1];
+                            p_t2t->num_mem_tlvs++;
+                            rw_t2t_update_attributes ();
+                            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                        }
+                    }
+                }
+                else
+                {
+                    if (p_t2t->bytes_count == 0)
+                    {
+                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                break;
+
+            case TAG_PROPRIETARY_TLV:
+                p_t2t->bytes_count--;
+                if (tlvtype == TAG_PROPRIETARY_TLV)
+                {
+                    found = TRUE;
+                    p_t2t->prop_msg_len = len;
+                }
+                else
+                {
+                    if (p_t2t->bytes_count == 0)
+                    {
+                        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+                    }
+                }
+                break;
+            }
+            offset++;
+            break;
+        }
+    }
+
+
+    p_t2t->work_offset += T2T_READ_DATA_LEN;
+
+    event = rw_t2t_info_to_event (p_cmd_rsp_info);
+
+    /* If not found and not failed, read next block and search tlv */
+    if (!found && !failed)
+    {
+
+        if (p_t2t->work_offset >= (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR))
+        {
+            if (  ((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0))
+                ||((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))  )
+            {
+                found = TRUE;
+            }
+            else
+            {
+                failed = TRUE;
+            }
+        }
+        else
+        {
+            if (rw_t2t_read ((UINT16) ((p_t2t->work_offset / T2T_BLOCK_LEN) + T2T_FIRST_DATA_BLOCK)) != NFC_STATUS_OK)
+                failed = TRUE;
+        }
+    }
+
+    if (failed || found)
+    {
+        if (tlvtype == TAG_LOCK_CTRL_TLV)
+        {
+            /* Incase no Lock control tlv is present then look for default dynamic lock bytes */
+            rw_t2t_extract_default_locks_info ();
+
+            /* Send command to read the dynamic lock bytes */
+            status = rw_t2t_read_locks ();
+
+            if (status != NFC_STATUS_CONTINUE)
+            {
+                /* If unable to read a lock/all locks read, notify upper layer */
+                rw_t2t_update_lock_attributes ();
+                rw_t2t_ntf_tlv_detect_complete (status);
+            }
+        }
+        else if (tlvtype == TAG_NDEF_TLV)
+        {
+            rw_t2t_extract_default_locks_info ();
+
+            if (failed)
+            {
+                rw_t2t_ntf_tlv_detect_complete (NFC_STATUS_FAILED);
+            }
+            else
+            {
+                /* NDEF present,Send command to read the dynamic lock bytes */
+                status = rw_t2t_read_locks ();
+                if (status != NFC_STATUS_CONTINUE)
+                {
+                    /* If unable to read a lock/all locks read, notify upper layer */
+                    rw_t2t_update_lock_attributes ();
+                    rw_t2t_ntf_tlv_detect_complete (status);
+                }
+            }
+        }
+        else
+        {
+            /* Notify Memory/ Proprietary tlv detect result */
+            status  = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+            rw_t2t_ntf_tlv_detect_complete (status);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_locks
+**
+** Description      This function will send command to read next unread locks
+**
+** Returns          NFC_STATUS_OK, if all locks are read successfully
+**                  NFC_STATUS_FAILED, if reading locks failed
+**                  NFC_STATUS_CONTINUE, if reading locks is in progress
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_locks (void)
+{
+    UINT8       num_locks   = 0;
+    tRW_T2T_CB  *p_t2t      = &rw_cb.tcb.t2t;
+    tNFC_STATUS status      = NFC_STATUS_CONTINUE;
+    UINT16      offset;
+    UINT16      block;
+
+    if (  (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
+        ||((p_t2t->tag_hdr[0] == TAG_MIFARE_MID) && (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_MULC))  )
+
+    {
+        /* Skip reading dynamic lock bytes if CC is set as Read only or on MUL-C tag */
+        while (num_locks < p_t2t->num_lockbytes)
+        {
+            p_t2t->lockbyte[num_locks].lock_byte   = 0x00;
+            p_t2t->lockbyte[num_locks].b_lock_read = TRUE;
+            num_locks++;
+        }
+    }
+
+    while (num_locks < p_t2t->num_lockbytes)
+    {
+        if (p_t2t->lockbyte[num_locks].b_lock_read == FALSE)
+        {
+            /* Send Read command to read the first un read locks */
+            offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
+
+            /* Read 16 bytes where this lock byte is present */
+            block  = (UINT16) (offset / T2T_BLOCK_LEN);
+            block -= block % T2T_READ_BLOCKS;
+
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
+            /* send READ8 command */
+            if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK)
+            {
+                /* Reading Locks */
+                status          = NFC_STATUS_CONTINUE;
+            }
+            else
+            {
+                status = NFC_STATUS_FAILED;
+            }
+            break;
+        }
+        num_locks++;
+    }
+    if (num_locks == p_t2t->num_lockbytes)
+    {
+        /* All locks are read */
+        status = NFC_STATUS_OK;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_extract_default_locks_info
+**
+** Description      This function will prepare lockbytes information for default
+**                  locks present in the tag in the absence of lock control tlv.
+**                  Adding a virtual lock control tlv for these lock bytes for
+**                  easier manipulation.
+**
+** Returns          None
+**
+*******************************************************************************/
+void rw_t2t_extract_default_locks_info (void)
+{
+    UINT8       num_dynamic_lock_bits;
+    UINT8       num_dynamic_lock_bytes;
+    UINT8       xx;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    const       tT2T_INIT_TAG *p_ret;
+    UINT8       bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
+
+
+    if (  (p_t2t->num_lock_tlvs == 0)
+        &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC)  )
+    {
+        /* No Lock control tlv is detected. Indicates lock bytes are present in default location */
+        /* Add a virtual Lock tlv to map this default lock location */
+        if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+            bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
+
+        num_dynamic_lock_bits   = ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) - (T2T_STATIC_SIZE - T2T_HEADER_SIZE)) / bytes_locked_per_lock_bit;
+        num_dynamic_lock_bytes  = num_dynamic_lock_bits / 8;
+        num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0:1;
+
+        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset                = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
+        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit  = bytes_locked_per_lock_bit;
+        p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits              = num_dynamic_lock_bits;
+
+        /* Based on tag data size the number of locks present in the default location changes */
+        for (xx = 0; xx < num_dynamic_lock_bytes; xx++)
+        {
+            p_t2t->lockbyte[xx].tlv_index   = p_t2t->num_lock_tlvs;
+            p_t2t->lockbyte[xx].byte_index  = xx;
+            p_t2t->lockbyte[xx].b_lock_read = FALSE;
+        }
+        p_t2t->num_lockbytes = num_dynamic_lock_bytes;
+        p_t2t->num_lock_tlvs = 1;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_ndef_last_block
+**
+** Description      This function will locate and read the last ndef block.
+**                  The last ndef block refers to the tag block where last byte
+**                  of new ndef message will reside. Also this function will
+**                  locate the offset of Terminator TLV based on the size of
+**                  new NDEF Message
+**
+** Returns          NCI_STATUS_OK,if able to locate last ndef block & read started
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_ndef_last_block (void)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT16      header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN) ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+    UINT16      num_ndef_bytes;
+    UINT16      total_ndef_bytes;
+    UINT16      last_ndef_byte_offset;
+    UINT16      terminator_tlv_byte_index;
+    tNFC_STATUS status;
+    UINT16      block;
+
+
+    total_ndef_bytes        = header_len + p_t2t->new_ndef_msg_len;
+    num_ndef_bytes          = 0;
+    last_ndef_byte_offset   = p_t2t->ndef_header_offset;
+
+    /* Locate NDEF final block based on the size of new NDEF Message */
+    while (num_ndef_bytes < total_ndef_bytes)
+    {
+        if (rw_t2t_is_lock_res_byte ((UINT16) (last_ndef_byte_offset)) == FALSE)
+            num_ndef_bytes++;
+
+        last_ndef_byte_offset++;
+    }
+    p_t2t->ndef_last_block_num = (UINT16) ((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
+    block  = p_t2t->ndef_last_block_num;
+
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK;
+    /* Read NDEF last block before updating */
+    if ((status = rw_t2t_read (block))== NFC_STATUS_OK)
+    {
+        if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len)
+        {
+            /* Locate Terminator TLV Block */
+            total_ndef_bytes++;
+            terminator_tlv_byte_index = last_ndef_byte_offset;
+
+            while (num_ndef_bytes < total_ndef_bytes)
+            {
+                if (rw_t2t_is_lock_res_byte ((UINT16) terminator_tlv_byte_index) == FALSE)
+                        num_ndef_bytes++;
+
+                terminator_tlv_byte_index++;
+            }
+
+            p_t2t->terminator_byte_index = terminator_tlv_byte_index - 1;
+        }
+        else
+        {
+            /* No space for Terminator TLV */
+            p_t2t->terminator_byte_index = 0x00;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_terminator_tlv_block
+**
+** Description      This function will read the block where terminator tlv will
+**                  be added later
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_terminator_tlv_block (void)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status;
+    UINT16      block;
+
+    /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */
+    block  = p_t2t->terminator_byte_index / T2T_BLOCK_SIZE;
+    block -= block % T2T_READ_BLOCKS;
+
+    p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK;
+    /* Read the block where Terminator TLV may be added later during NDEF Write operation */
+    status = rw_t2t_read (block);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_read_ndef_next_block
+**
+** Description      This function will read the tag block passed as argument
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_read_ndef_next_block (UINT16 block)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status;
+
+    /* Send read command to read base block (Block % 4==0) where this block is also read as part of 16 bytes */
+    block -= block % T2T_READ_BLOCKS;
+
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
+    /* Read the block */
+    status = rw_t2t_read (block);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_is_read_before_write_block
+**
+** Description      This function will check if the block has to be read before
+**                  writting to avoid over writting in to lock/reserved bytes
+**                  present in the block.
+**                  If no bytes in the block can be overwritten it moves in to
+**                  next block and check. Finally it finds a block where part of
+**                  ndef bytes can exist and check if the whole block can be
+**                  updated or only part of block can be modified.
+**
+** Returns          TRUE, if the block returned should be read before writting
+**                  FALSE, if the block need not be read as it was already
+**                         read or during NDEF write we may completely overwrite
+**                         the block and there is no reserved or locked bytes in
+**                         that block
+**
+*******************************************************************************/
+static BOOLEAN rw_t2t_is_read_before_write_block (UINT16 block, UINT16 *p_block_to_read)
+{
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+    UINT8       *p_cc   = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+    UINT8       count;
+    UINT8       index;
+    UINT16      tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+    BOOLEAN     read_before_write = TRUE;
+
+
+    if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE)
+    {
+        /* First NDEF block is already read */
+        read_before_write = FALSE;
+        memcpy (p_t2t->ndef_read_block,p_t2t->ndef_first_block,T2T_BLOCK_SIZE);
+    }
+    else if (block == p_t2t->ndef_last_block_num)
+    {
+        /* Last NDEF block is already read */
+        read_before_write = FALSE;
+        memcpy (p_t2t->ndef_read_block,p_t2t->ndef_last_block,T2T_BLOCK_SIZE);
+    }
+    else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE)
+    {
+        /* Terminator tlv block is already read */
+        read_before_write = FALSE;
+        memcpy (p_t2t->ndef_read_block,p_t2t->terminator_tlv_block,T2T_BLOCK_SIZE);
+    }
+    else
+    {
+        count = 0;
+        while (block < tag_size)
+        {
+            index = 0;
+
+            while (index < T2T_BLOCK_SIZE)
+            {
+                /* check if it is a reserved or locked byte */
+                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+                {
+                    count++;
+                }
+                index++;
+            }
+            if (count == T2T_BLOCK_SIZE)
+            {
+                /* All the bytes in the block are free to NDEF write  */
+                read_before_write = FALSE;
+                break;
+            }
+            else if (count == 0)
+            {
+                /* The complete block is not free for NDEF write  */
+                index = 0;
+                block++;
+            }
+            else
+            {
+                /* The block has reseved byte (s) or locked byte (s) or both */
+                read_before_write = TRUE;
+                break;
+            }
+        }
+    }
+    /* Return the block to read next before NDEF write */
+    *p_block_to_read = block;
+    return read_before_write;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_write_ndef_first_block
+**
+** Description      This function will write the first NDEF block with Length
+**                  field reset to zero.
+**                  Also after writting NDEF this function may be called to
+**                  update new NDEF length
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write_ndef_first_block (UINT16 msg_len, BOOLEAN b_update_len)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT8       new_lengthfield_len;
+    UINT8       write_block[4];
+    UINT8       block;
+    UINT8       *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+    UINT16      total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+    tNFC_STATUS status;
+    UINT8       length_field[3];
+    UINT8       index;
+
+    p_t2t->work_offset = 0;
+    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+    if (new_lengthfield_len == 3)
+    {
+        /* New NDEF is Long NDEF */
+        if (msg_len == 0)
+        {
+            /* Clear NDEF length field */
+            length_field[0] = 0x00;
+            length_field[1] = 0x00;
+            length_field[2] = 0x00;
+        }
+        else
+        {
+            /* Update NDEF length field with new NDEF Msg len */
+            length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
+            length_field[1] = (UINT8) (msg_len >> 8);
+            length_field[2] = (UINT8) (msg_len);
+        }
+    }
+    else
+    {
+        /* New NDEF is Short NDEF */
+        length_field[0] = (UINT8) (msg_len);
+    }
+
+    /* updating ndef_first_block with new ndef message */
+    memcpy (write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
+
+    index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
+    block = (UINT8) (p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
+
+    while (p_t2t->work_offset == 0 && block < total_blocks)
+    {
+        /* update length field */
+        while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len)
+        {
+            if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+            {
+                write_block[index] = length_field[p_t2t->work_offset];
+                p_t2t->work_offset++;
+            }
+            index++;
+            if (p_t2t->work_offset == new_lengthfield_len)
+            {
+                break;
+            }
+        }
+        /* If more space in this block then add ndef message */
+        while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
+        {
+            if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+            {
+                write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+                p_t2t->work_offset++;
+            }
+            index++;
+        }
+        if (p_t2t->work_offset == 0)
+        {
+            /* If no bytes are written move to next block */
+            index = 0;
+            block++;
+            if (block == p_t2t->ndef_last_block_num)
+            {
+                memcpy (write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
+            }
+        }
+    }
+    if (p_t2t->work_offset == 0)
+    {
+        status  = NFC_STATUS_FAILED;
+    }
+    else
+    {
+        rw_t2t_update_cb (block, write_block, b_update_len);
+        /* Update the identified block with newly prepared data */
+        if ((status = rw_t2t_write (block, write_block)) == NFC_STATUS_OK)
+        {
+            p_t2t->b_read_data = FALSE;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_write_ndef_next_block
+**
+** Description      This function can be called to write an NDEF message block
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_write_ndef_next_block (UINT16 block, UINT16 msg_len, BOOLEAN b_update_len)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT8       new_lengthfield_len;
+    UINT8       write_block[4];
+    UINT8       *p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
+    UINT16      total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
+    UINT16      initial_offset;
+    UINT8       length_field[3];
+    UINT8       index;
+    tNFC_STATUS status;
+
+    /* Write NDEF Message */
+    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+
+    index = 0;
+
+    memcpy (write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
+
+    if (p_t2t->work_offset >= new_lengthfield_len)
+    {
+        /* Length field is updated, write ndef message field */
+        initial_offset = p_t2t->work_offset;
+        while (p_t2t->work_offset == initial_offset && block < total_blocks)
+        {
+            while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
+            {
+                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+                {
+                    write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+                    p_t2t->work_offset++;
+                }
+                index++;
+            }
+            if (p_t2t->work_offset == initial_offset)
+            {
+                index = 0;
+                block++;
+            }
+        }
+    }
+    else
+    {
+        /* Complete writting Length field and then write ndef message */
+        new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+        if (new_lengthfield_len == 3)
+        {
+            /* New NDEF is Long NDEF */
+            if (msg_len == 0)
+            {
+                length_field[0] = 0x00;
+                length_field[1] = 0x00;
+                length_field[2] = 0x00;
+            }
+            else
+            {
+                length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
+                length_field[1] = (UINT8) (msg_len >> 8);
+                length_field[2] = (UINT8) (msg_len);
+            }
+        }
+        else
+        {
+            /* New NDEF is short NDEF */
+            length_field[0] = (UINT8) (msg_len);
+        }
+        initial_offset = p_t2t->work_offset;
+        while (p_t2t->work_offset == initial_offset && block < total_blocks)
+        {
+            /* Update length field */
+            while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < p_t2t->new_ndef_msg_len)
+            {
+                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+                {
+                    write_block[index] = length_field[p_t2t->work_offset];
+                    p_t2t->work_offset++;
+                }
+                index++;
+                if (p_t2t->work_offset == new_lengthfield_len)
+                {
+                    break;
+                }
+            }
+            /* Update ndef message field */
+            while (index < T2T_BLOCK_SIZE && p_t2t->work_offset < (p_t2t->new_ndef_msg_len + new_lengthfield_len))
+            {
+                if (rw_t2t_is_lock_res_byte ((UINT16) ((block * T2T_BLOCK_SIZE) + index)) == FALSE)
+                {
+                    write_block[index] = p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
+                    p_t2t->work_offset++;
+                }
+                index++;
+            }
+            if (p_t2t->work_offset == initial_offset)
+            {
+                index = 0;
+                block++;
+            }
+        }
+    }
+    if (p_t2t->work_offset == initial_offset)
+    {
+        status  = NFC_STATUS_FAILED;
+    }
+    else
+    {
+        rw_t2t_update_cb (block, write_block, b_update_len);
+        /* Write the NDEF Block */
+        status = rw_t2t_write (block, write_block);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_update_cb
+**
+** Description      This function can be called to write an NDEF message block
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+static void rw_t2t_update_cb (UINT16 block, UINT8 *p_write_block, BOOLEAN b_update_len)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT8       new_lengthfield_len;
+
+        /* Write NDEF Message */
+    new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN ? T2T_LONG_NDEF_LEN_FIELD_LEN : T2T_SHORT_NDEF_LEN_FIELD_LEN;
+
+    if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE)
+    {
+        /* Update ndef first block if the 'block' points to ndef first block */
+        memcpy (p_t2t->ndef_first_block,p_write_block,T2T_BLOCK_SIZE);
+    }
+    if (p_t2t->terminator_byte_index/T2T_BLOCK_SIZE == block)
+    {
+        /* Update terminator block if the 'block' points to terminator tlv block */
+        memcpy (p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
+    }
+    if (b_update_len == FALSE)
+    {
+        if (block == p_t2t->ndef_last_block_num)
+        {
+            p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
+            p_t2t->work_offset      = 0;
+            /* Update ndef final block if the 'block' points to ndef final block */
+            memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE);
+        }
+        else
+        {
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
+        }
+    }
+    else
+    {
+        if (block == p_t2t->ndef_last_block_num)
+        {
+            /* Update the backup of Ndef final block TLV block */
+            memcpy (p_t2t->ndef_last_block,p_write_block,T2T_BLOCK_SIZE);
+        }
+
+        if (p_t2t->work_offset >= new_lengthfield_len)
+        {
+            if (p_t2t->terminator_byte_index != 0)
+            {
+                /* Add Terminator TLV as part of NDEF Write operation */
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
+            }
+            else
+            {
+                /* Skip adding Terminator TLV */
+                p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
+            }
+        }
+        else
+        {
+            /* Part of NDEF Message Len should be added in the next block */
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_ndef_flags
+**
+** Description      Prepare NDEF Flags
+**
+** Returns          NDEF Flag value
+**
+*******************************************************************************/
+static UINT8 rw_t2t_get_ndef_flags (void)
+{
+    UINT8       flags   = 0;
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+    const       tT2T_INIT_TAG *p_ret;
+
+    flags |= RW_NDEF_FL_SUPPORTED;
+
+    if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) || (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
+        flags |= RW_NDEF_FL_FORMATABLE;
+
+    if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
+        flags |=RW_NDEF_FL_READ_ONLY;
+
+    if (  ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+        &&(p_ret->b_otp)  )
+    {
+        /* Set otp flag */
+        flags |= RW_NDEF_FL_OTP;
+
+        /* Set Read only flag if otp tag already has NDEF Message */
+        if (p_t2t->ndef_msg_len)
+            flags |= RW_NDEF_FL_READ_ONLY;
+    }
+    return flags;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_ndef_max_size
+**
+** Description      Calculate maximum size of NDEF message that can be written
+**                  on to the tag
+**
+** Returns          Maximum size of NDEF Message
+**
+*******************************************************************************/
+static UINT16 rw_t2t_get_ndef_max_size (void)
+{
+    UINT16      offset;
+    UINT8       xx;
+    tRW_T2T_CB  *p_t2t   = &rw_cb.tcb.t2t;
+    UINT16      tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN) + p_t2t->num_lockbytes;
+
+    for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+        tag_size += p_t2t->mem_tlv[xx].num_bytes;
+
+    offset                  = p_t2t->ndef_msg_offset;
+    p_t2t->max_ndef_msg_len = 0;
+
+    if (  (tag_size < T2T_STATIC_SIZE)
+        ||(tag_size > (T2T_SECTOR_SIZE * T2T_MAX_SECTOR))
+        ||((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0))  )
+    {
+        /* Tag not formated, assume static tag */
+        p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE - T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
+        return p_t2t->max_ndef_msg_len;
+    }
+
+    /* Starting from NDEF Message offset find the first locked data byte */
+    while (offset < tag_size)
+    {
+        if (rw_t2t_is_lock_res_byte ((UINT16) offset) == FALSE)
+        {
+            if (rw_t2t_is_read_only_byte ((UINT16) offset) == TRUE)
+                break;
+            p_t2t->max_ndef_msg_len++;
+        }
+        offset++;
+    }
+    /* NDEF Length field length changes based on NDEF size */
+    if (  (p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0)
+        &&((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) == T2T_SHORT_NDEF_LEN_FIELD_LEN)  )
+    {
+        p_t2t->max_ndef_msg_len -=  (p_t2t->max_ndef_msg_len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) ? 1: (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
+    }
+    return p_t2t->max_ndef_msg_len;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_add_terminator_tlv
+**
+** Description      This function will add terminator TLV after NDEF Message
+**
+** Returns          NCI_STATUS_OK, if write was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_add_terminator_tlv (void)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status;
+    UINT16      block;
+
+    /* Add Terminator TLV after NDEF Message */
+    p_t2t->terminator_tlv_block[p_t2t->terminator_byte_index%T2T_BLOCK_LEN] = TAG_TERMINATOR_TLV;
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
+
+    block = p_t2t->terminator_byte_index/T2T_BLOCK_LEN;
+    status = rw_t2t_write (block, p_t2t->terminator_tlv_block);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_ndef_read_rsp
+**
+** Description      This function handles reading an NDEF message.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_ndef_read_rsp (UINT8 *p_data)
+{
+    tRW_T2T_CB      *p_t2t = &rw_cb.tcb.t2t;
+    tRW_READ_DATA    evt_data;
+    UINT16          len;
+    UINT16          offset;
+    BOOLEAN         failed = FALSE;
+    BOOLEAN         done   = FALSE;
+
+    /* On the first read, adjust for any partial block offset */
+    offset = 0;
+    len    = T2T_READ_DATA_LEN;
+
+    if (p_t2t->work_offset == 0)
+    {
+        /* The Ndef Message offset may be present in the read 16 bytes */
+        offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
+    }
+
+    /* Skip all reserved and lock bytes */
+    while (  (offset < len)
+           &&(p_t2t->work_offset<p_t2t->ndef_msg_len)  )
+
+    {
+        if (rw_t2t_is_lock_res_byte ((UINT16) (offset + p_t2t->block_read * T2T_BLOCK_LEN)) == FALSE)
+        {
+            /* Collect the NDEF Message */
+            p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
+            p_t2t->work_offset++;
+        }
+        offset++;
+    }
+
+    if (p_t2t->work_offset >= p_t2t->ndef_msg_len)
+    {
+        done = TRUE;
+        p_t2t->ndef_status = T2T_NDEF_READ;
+    }
+    else
+    {
+        /* Read next 4 blocks */
+        if (rw_t2t_read ((UINT16) (p_t2t->block_read + T2T_READ_BLOCKS)) != NFC_STATUS_OK)
+            failed = TRUE;
+    }
+
+    if (failed || done)
+    {
+        evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+        evt_data.p_data = NULL;
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_NDEF_READ_EVT, (tRW_DATA *) &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_ndef_write_rsp
+**
+** Description      Handle response received to reading (or part of) NDEF message.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_ndef_write_rsp (UINT8 *p_data)
+{
+    tRW_T2T_CB      *p_t2t = &rw_cb.tcb.t2t;
+    tRW_READ_DATA   evt_data;
+    BOOLEAN         failed = FALSE;
+    BOOLEAN         done   = FALSE;
+    UINT16          block;
+    UINT8           offset;
+
+    switch (p_t2t->substate)
+    {
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
+
+        /* Backup the read NDEF first block */
+           memcpy (p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
+        /* Read ndef final block */
+        if (rw_t2t_read_ndef_last_block () !=  NFC_STATUS_OK)
+            failed = TRUE;
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LAST_BLOCK:
+
+        offset = (UINT8) (p_t2t->ndef_last_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE;
+        /* Backup the read NDEF final block */
+        memcpy (p_t2t->ndef_last_block, &p_data[offset], T2T_BLOCK_LEN);
+        if ((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) == p_t2t->ndef_last_block_num)
+        {
+            /* If Terminator TLV will reside on the NDEF Final block */
+            memcpy (p_t2t->terminator_tlv_block, p_t2t->ndef_last_block, T2T_BLOCK_LEN);
+            if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!=  NFC_STATUS_OK)
+                failed = TRUE;
+        }
+        else if (p_t2t->terminator_byte_index != 0)
+        {
+            /* If there is space for Terminator TLV and if it will reside outside NDEF Final block */
+            if (rw_t2t_read_terminator_tlv_block ()!=  NFC_STATUS_OK)
+                failed = TRUE;
+        }
+        else
+        {
+            if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!=  NFC_STATUS_OK)
+                failed = TRUE;
+        }
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_TERM_TLV_BLOCK:
+
+        offset = (UINT8) (((p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) - p_t2t->block_read) * T2T_BLOCK_SIZE);
+        /* Backup the read Terminator TLV block */
+        memcpy (p_t2t->terminator_tlv_block, &p_data[offset], T2T_BLOCK_LEN);
+
+        /* Write the first block for new NDEF Message */
+        if (rw_t2t_write_ndef_first_block (0x0000, FALSE)!=  NFC_STATUS_OK)
+           failed = TRUE;
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
+
+        offset = (UINT8) (p_t2t->ndef_read_block_num - p_t2t->block_read) * T2T_BLOCK_SIZE;
+        /* Backup read block */
+        memcpy (p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
+
+        /* Update the block with new NDEF Message */
+        if (rw_t2t_write_ndef_next_block (p_t2t->ndef_read_block_num, 0x0000, FALSE) !=  NFC_STATUS_OK)
+            failed = TRUE;
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
+        if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->block_written + 1), &block) == TRUE)
+        {
+            p_t2t->ndef_read_block_num = block;
+            /* If only part of the block is going to be updated read the block to retain previous data for
+               unchanged part of the block */
+            if (rw_t2t_read_ndef_next_block (block) !=  NFC_STATUS_OK)
+                failed = TRUE;
+        }
+        else
+        {
+            if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK)
+            {
+                /* Directly write the block with new NDEF contents as whole block is going to be updated */
+                if (rw_t2t_write_ndef_next_block (block, p_t2t->new_ndef_msg_len, TRUE)!=  NFC_STATUS_OK)
+                   failed = TRUE;
+            }
+            else
+            {
+                /* Directly write the block with new NDEF contents as whole block is going to be updated */
+                if (rw_t2t_write_ndef_next_block (block, 0x0000, FALSE)!=  NFC_STATUS_OK)
+                   failed = TRUE;
+            }
+        }
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
+        /* Write the next block for new NDEF Message */
+        p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
+        if (rw_t2t_is_read_before_write_block ((UINT16) (p_t2t->ndef_write_block), &block) == TRUE)
+        {
+            /* If only part of the block is going to be updated read the block to retain previous data for
+               part of the block thats not going to be changed */
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
+            if (rw_t2t_read (block) !=  NFC_STATUS_OK)
+                failed = TRUE;
+
+        }
+        else
+        {
+            /* Update NDEF Message Length in the Tag */
+            if (rw_t2t_write_ndef_first_block (p_t2t->new_ndef_msg_len, TRUE)!=  NFC_STATUS_OK)
+               failed = TRUE;
+        }
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
+        /* Backup read block */
+        memcpy (p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
+
+        /* Update the block with new NDEF Message */
+        if (rw_t2t_write_ndef_next_block (p_t2t->block_read, p_t2t->new_ndef_msg_len, TRUE) ==  NFC_STATUS_OK)
+            p_t2t->ndef_write_block = p_t2t->block_read + 1;
+        else
+            failed = TRUE;
+
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
+        if (rw_t2t_add_terminator_tlv ()!=  NFC_STATUS_OK)
+           failed = TRUE;
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
+        done = TRUE;
+        break;
+
+    default:
+        break;
+    }
+
+    if (failed || done)
+    {
+        evt_data.p_data = NULL;
+        /* NDEF WRITE Operation is done, inform up the stack */
+        evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
+        if (done)
+        {
+            if (  (p_t2t->ndef_msg_len >= 0x00FF)
+                &&(p_t2t->new_ndef_msg_len < 0x00FF)  )
+            {
+                p_t2t->ndef_msg_offset -= 2;
+            }
+            else if (  (p_t2t->new_ndef_msg_len >= 0x00FF)
+                     &&(p_t2t->ndef_msg_len < 0x00FF)  )
+            {
+                p_t2t->ndef_msg_offset += 2;
+            }
+            p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
+        }
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_NDEF_WRITE_EVT, (tRW_DATA *) &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_tag_size
+**
+** Description      This function calculates tag data area size from data read
+**                  from block with version number
+**
+** Returns          TMS of the tag
+**
+*******************************************************************************/
+static UINT8 rw_t2t_get_tag_size (UINT8 *p_data)
+{
+    UINT16  LchunkSize = 0;
+    UINT16  Num_LChuncks = 0;
+    UINT16  tms = 0;
+
+    LchunkSize   = (UINT16) p_data[2] << 8 | p_data[3];
+    Num_LChuncks = (UINT16) p_data[4] << 8 | p_data[5];
+
+    tms = (UINT16) (LchunkSize * Num_LChuncks);
+
+    tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
+
+    tms /= 0x08;
+
+    return (UINT8) tms;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_config_tag_readonly
+**
+** Description      This function handles configure type 2 tag as read only
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_config_tag_readonly (UINT8 *p_data)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    BOOLEAN     b_notify = FALSE;
+    UINT8       write_block[T2T_BLOCK_SIZE];
+    tRW_DATA    evt;
+    BOOLEAN     b_pending = FALSE;
+    UINT8       read_lock = 0;
+    UINT8       num_locks = 0;
+    UINT16      offset;
+
+    switch (p_t2t->substate)
+    {
+    case RW_T2T_SUBSTATE_WAIT_READ_CC:
+
+        /* First soft lock the tag */
+        rw_t2t_soft_lock_tag ();
+
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
+
+        /* Successfully soft locked! Update Tag header for future reference */
+        p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
+        if (!p_t2t->b_hard_lock)
+        {
+            /* Tag configuration complete */
+            status   = NFC_STATUS_OK;
+            b_notify = TRUE;
+            break;
+        }
+
+        /* Coverity: [FALSE-POSITIVE error] intended fall through */
+        /* Missing break statement between cases in switch statement */
+        /* fall through */
+    case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
+
+        num_locks = 0;
+
+        while (num_locks < p_t2t->num_lockbytes)
+        {
+            if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_UPDATE_INITIATED)
+            {
+                /* Update control block as one or more dynamic lock byte (s) are set */
+                p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
+            }
+            if (!b_pending && p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED)
+            {
+                /* One or more dynamic lock bits are not set */
+                b_pending = TRUE;
+                read_lock = num_locks;
+            }
+            num_locks++;
+        }
+
+        if (b_pending)
+        {
+            /* Read the block where dynamic lock bits are present to avoid writing to NDEF bytes in the same block */
+            offset = p_t2t->lock_tlv[p_t2t->lockbyte[read_lock].tlv_index].offset + p_t2t->lockbyte[read_lock].byte_index;
+            p_t2t->substate    = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
+            status = rw_t2t_read ((UINT16) (offset / T2T_BLOCK_LEN));
+        }
+        else
+        {
+            /* Now set Static lock bits as no more dynamic lock bits to set */
+
+            /* Copy the internal bytes */
+            memcpy (write_block, &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN], T2T_INTERNAL_BYTES_LEN);
+            /* Set all Static lock bits */
+            write_block [T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
+            write_block [T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS;
+            status = rw_t2t_write ((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
+        }
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
+        /* Now set the dynamic lock bits present in the block read now */
+        status = rw_t2t_set_dynamic_lock_bits (p_data);
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_ST_LOCK_BITS:
+        /* Tag configuration complete */
+        status   = NFC_STATUS_OK;
+        b_notify = TRUE;
+        break;
+
+    }
+
+    if (status != NFC_STATUS_OK || b_notify)
+    {
+        /* Notify upper layer the result of Configuring Tag as Read only */
+        evt.status      = status;
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_SET_TAG_RO_EVT, (tRW_DATA *) &evt);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_handle_format_tag_rsp
+**
+** Description      This function handles formating a type 2 tag
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t2t_handle_format_tag_rsp (UINT8 *p_data)
+{
+    tRW_DATA    evt;
+    UINT8       *p;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    UINT16      version_no;
+    const       tT2T_INIT_TAG *p_ret;
+    UINT8       tms;
+    UINT8       next_block = T2T_FIRST_DATA_BLOCK + 1;
+    UINT16      addr, locked_area;
+    BOOLEAN     b_notify = FALSE;
+
+
+    p = p_t2t->ndef_final_block;
+    UINT8_TO_BE_STREAM (p, p_t2t->tlv_value[2]);
+
+    switch (p_t2t->substate)
+    {
+    case RW_T2T_SUBSTATE_WAIT_READ_CC:
+        /* Start format operation */
+        status = rw_t2t_format_tag ();
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
+
+        memcpy (p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
+        p_t2t->b_read_data = TRUE;
+        version_no = (UINT16) p_data[0] << 8 | p_data[1];
+        if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) != NULL)
+        {
+            /* Valid Version Number */
+            if (p_ret->b_calc_cc)
+                /* Calculate tag size from Version Information */
+                tms = rw_t2t_get_tag_size (p_data);
+
+            else
+                /* Tag size from Look up table */
+                tms = p_ret->tms;
+
+            /* Set CC with the Tag size from look up table or from calculated value */
+            status = rw_t2t_set_cc (tms);
+        }
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_CC:
+
+        version_no = (UINT16) p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
+        if (  (version_no == 0)
+            ||((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], TRUE, version_no)) == NULL)
+            ||(!p_ret->b_multi_version)
+            ||(!p_ret->b_calc_cc)  )
+        {
+            /* Currently Formating a non blank tag or a blank tag with manufacturer
+             * has only one variant of tag. Set Null NDEF TLV and complete Format Operation */
+            next_block = T2T_FIRST_DATA_BLOCK;
+            p = p_t2t->ndef_final_block;
+        }
+        else
+        {
+            addr        = (UINT16) (((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[4] << 8 | p_t2t->tag_data[5]) + T2T_STATIC_SIZE);
+            locked_area = ((UINT16) p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) * ((UINT16) p_t2t->tag_data[6]);
+
+            if ((status = rw_t2t_set_lock_tlv (addr, p_t2t->tag_data[7], locked_area)) == NFC_STATUS_REJECTED)
+            {
+                /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format Operation */
+                next_block = T2T_FIRST_DATA_BLOCK;
+                p = p_t2t->ndef_final_block;
+            }
+            else
+                break;
+        }
+
+        /* falls through */
+    case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
+
+        /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
+        UINT8_TO_BE_STREAM (p, TAG_NDEF_TLV);
+        UINT8_TO_BE_STREAM (p, 0);
+
+        if (  ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+            &&(!p_ret->b_otp)  )
+        {
+            UINT8_TO_BE_STREAM (p, TAG_TERMINATOR_TLV);
+        }
+        else
+            UINT8_TO_BE_STREAM (p, 0);
+
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
+        /* send WRITE-E8 command */
+        if ((status = rw_t2t_write (next_block, p_t2t->ndef_final_block)) == NFC_STATUS_OK)
+            p_t2t->b_read_data = FALSE;
+        break;
+
+    case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
+        /* Tag Formated successfully */
+        status   = NFC_STATUS_OK;
+        b_notify = TRUE;
+        break;
+
+    default:
+        break;
+
+    }
+
+    if (status != NFC_STATUS_OK || b_notify)
+    {
+        /* Notify upper layer the result of Format op */
+        evt.status      = status;
+        rw_t2t_handle_op_complete ();
+        (*rw_cb.p_cback) (RW_T2T_FORMAT_CPLT_EVT, (tRW_DATA *) &evt);
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_update_attributes
+**
+** Description      This function will update attribute for the current segment
+**                  based on lock and reserved bytes
+**
+** Returns          None
+**
+*******************************************************************************/
+static void rw_t2t_update_attributes (void)
+{
+    UINT8       count = 0;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT16      lower_offset;
+    UINT16      upper_offset;
+    UINT16      offset;
+    UINT8       num_bytes;
+
+    /* Prepare attr for the current segment */
+    memset (p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8));
+
+    /* calculate offset where the current segment starts in the tag */
+    lower_offset   = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
+    /* calculate offset where the current segment ends in the tag */
+    upper_offset   = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
+
+
+    /* check offset of lock bytes in the tag and update p_t2t->attr
+     * for every lock byte that is present in the current segment */
+    count = 0;
+    while (count < p_t2t->num_lockbytes)
+    {
+        offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset + p_t2t->lockbyte[count].byte_index;
+        if (offset >= lower_offset && offset < upper_offset)
+        {
+            /* Calculate offset in the current segment as p_t2t->attr is prepared for one segment only */
+            offset %= RW_T2T_SEGMENT_BYTES;
+            /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not
+             * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
+             * Set the corresponding bit in attr to indicate - reserved byte */
+            p_t2t->attr[offset / TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
+        }
+        count++;
+    }
+
+
+    /* Search reserved bytes identified by all memory tlvs present in the tag */
+    count = 0;
+    while (count < p_t2t->num_mem_tlvs)
+    {
+        /* check the offset of reserved bytes in the tag and update  p_t2t->attr
+         * for every  reserved byte that is present in the current segment */
+        num_bytes = 0;
+        while (num_bytes < p_t2t->mem_tlv[count].num_bytes)
+        {
+            offset = p_t2t->mem_tlv[count].offset + num_bytes;
+            if (offset >= lower_offset && offset < upper_offset)
+            {
+                /* Let offset represents offset in the current segment as p_t2t->attr is prepared for one segment only */
+                offset %= RW_T2T_SEGMENT_BYTES;
+                /* Every bit in p_t2t->attr indicates one byte of the tag is either a lock/reserved byte or not
+                 * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
+                 * Set the corresponding bit in attr to indicate - reserved byte */
+                p_t2t->attr[offset /TAG_BITS_PER_BYTE] |= rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
+            }
+            num_bytes++;
+        }
+        count++;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_get_lock_bits_for_segment
+**
+** Description      This function returns the offset of lock bits associated for
+**                  the specified segment
+**
+** Parameters:      segment: The segment number to which lock bits are associated
+**                  p_start_byte: The offset of lock byte that contains the first
+**                                lock bit for the segment
+**                  p_start_bit:  The offset of the lock bit in the lock byte
+**
+**                  p_end_byte:   The offset of the last bit associcated to the
+**                                segment
+**
+** Returns          Total number of lock bits assigned to the specified segment
+**
+*******************************************************************************/
+static UINT8 rw_t2t_get_lock_bits_for_segment (UINT8 segment, UINT8 *p_start_byte, UINT8 *p_start_bit, UINT8 *p_end_byte)
+{
+    UINT8       total_bits = 0;
+    UINT16      byte_count = 0;
+    UINT16      lower_offset, upper_offset;
+    UINT8       num_dynamic_locks = 0;
+    UINT8       bit_count  = 0;
+    UINT8       bytes_locked_per_bit;
+    UINT8       num_bits;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    BOOLEAN     b_all_bits_are_locks = TRUE;
+    UINT16      tag_size;
+    UINT8       xx;
+
+    tag_size      = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) + (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
+
+    for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
+        tag_size += p_t2t->mem_tlv[xx].num_bytes;
+
+    lower_offset  = segment * RW_T2T_SEGMENT_BYTES;
+    if (segment == 0)
+    {
+        lower_offset  += T2T_STATIC_SIZE;
+    }
+    upper_offset  = (segment + 1) * RW_T2T_SEGMENT_BYTES;
+
+    byte_count = T2T_STATIC_SIZE;
+    if (tag_size < upper_offset)
+    {
+        upper_offset = tag_size;
+    }
+
+    *p_start_byte = num_dynamic_locks;
+    *p_start_bit  = 0;
+
+    while (  (byte_count <= lower_offset)
+           &&(num_dynamic_locks < p_t2t->num_lockbytes)  )
+    {
+        bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+        /* Number of bits in the current lock byte */
+        b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+        num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+        if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset)
+        {
+            /* Skip this lock byte as it covers different segment */
+            byte_count += bytes_locked_per_bit * num_bits;
+            num_dynamic_locks++;
+        }
+        else
+        {
+            bit_count = 0;
+            while (bit_count < num_bits)
+            {
+                byte_count += bytes_locked_per_bit;
+                if (byte_count > lower_offset)
+                {
+                    /* First lock bit that is used to lock this segment */
+                    *p_start_byte = num_dynamic_locks;
+                    *p_end_byte   = num_dynamic_locks;
+                    *p_start_bit  = bit_count;
+                    bit_count++;
+                    total_bits    = 1;
+                    break;
+                }
+                bit_count++;
+            }
+        }
+    }
+    if (num_dynamic_locks == p_t2t->num_lockbytes)
+    {
+        return 0;
+    }
+    while (  (byte_count < upper_offset)
+           &&(num_dynamic_locks < p_t2t->num_lockbytes)  )
+    {
+        bytes_locked_per_bit = p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].bytes_locked_per_bit;
+        /* Number of bits in the current lock byte */
+        b_all_bits_are_locks = ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits);
+        num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+        if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count < upper_offset)
+        {
+            /* Collect all lock bits that covers the current segment */
+            byte_count += bytes_locked_per_bit * (num_bits - bit_count);
+            total_bits += num_bits - bit_count;
+            bit_count   = 0;
+            *p_end_byte = num_dynamic_locks;
+            num_dynamic_locks++;
+        }
+        else
+        {
+            /* The last lock byte that covers the current segment */
+            bit_count = 0;
+            while (bit_count < num_bits)
+            {
+                /* The last lock bit that is used to lock this segment */
+                byte_count += bytes_locked_per_bit;
+                if (byte_count >= upper_offset)
+                {
+                    *p_end_byte = num_dynamic_locks;
+                    total_bits  += (bit_count + 1);
+                    break;
+                }
+                bit_count++;
+            }
+        }
+    }
+    return total_bits;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_update_lock_attributes
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a locked byte and return TRUE or FALSE
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          TRUE, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  FALSE, otherwise
+**
+*******************************************************************************/
+static void rw_t2t_update_lock_attributes (void)
+{
+    tRW_T2T_CB  *p_t2t                      = &rw_cb.tcb.t2t;
+    UINT8       xx                          = 0;
+    UINT8       num_static_lock_bytes       = 0;
+    UINT8       num_dyn_lock_bytes          = 0;
+    UINT8       bits_covered                = 0;
+    UINT8       bytes_covered               = 0;
+    UINT8       block_count                 = 0;
+    BOOLEAN     b_all_bits_are_locks        = TRUE;
+    UINT8       bytes_locked_per_lock_bit;
+    UINT8       start_lock_byte;
+    UINT8       start_lock_bit;
+    UINT8       end_lock_byte;
+    UINT8       num_lock_bits;
+    UINT8       total_bits;
+
+
+    /* Prepare lock_attr for the current segment */
+    memset (p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof (UINT8));
+
+    block_count                 = 0;
+    if (p_t2t->segment == 0)
+    {
+        /* Update lock_attributes based on static lock bytes */
+        xx                      = 0;
+        num_static_lock_bytes   = 0;
+        block_count             = 0;
+        num_lock_bits           = TAG_BITS_PER_BYTE;
+
+        while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES)
+        {
+            /* Update lock attribute based on 2 static locks */
+            while (xx < num_lock_bits)
+            {
+                p_t2t->lock_attr[block_count] = 0x00;
+
+                if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] & rw_t2t_mask_bits[xx++])
+                {
+                    /* If the bit is set then 1 block is locked */
+                    p_t2t->lock_attr[block_count] = 0x0F;
+                }
+
+                if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] & rw_t2t_mask_bits[xx++])
+                {
+                    /* If the bit is set then 1 block is locked */
+                    p_t2t->lock_attr[block_count] |= 0xF0;
+                }
+                block_count++;
+            }
+            num_static_lock_bytes++;
+            xx = 0;
+        }
+        /* UID is always locked, irrespective of the lock value */
+        p_t2t->lock_attr[0x00] = 0xFF;
+    }
+
+    /* Get lock bits applicable for the current segment */
+    if ((total_bits = rw_t2t_get_lock_bits_for_segment (p_t2t->segment,&start_lock_byte, &start_lock_bit, &end_lock_byte)) != 0)
+    {
+        /* update lock_attributes based on current segment using dynamic lock bytes */
+        xx                            = start_lock_bit;
+        num_dyn_lock_bytes            = start_lock_byte;
+        bits_covered                  = 0;
+        bytes_covered                 = 0;
+        num_lock_bits                 = TAG_BITS_PER_BYTE;
+        p_t2t->lock_attr[block_count] = 0;
+
+        while (num_dyn_lock_bytes <= end_lock_byte)
+        {
+            bytes_locked_per_lock_bit  = p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].bytes_locked_per_bit;
+            /* Find number of bits in the byte are lock bits */
+            b_all_bits_are_locks = ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits);
+            num_lock_bits        =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+            while (xx < num_lock_bits)
+            {
+                bytes_covered = 0;
+                while (bytes_covered < bytes_locked_per_lock_bit)
+                {
+                    if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte & rw_t2t_mask_bits[xx])
+                    {
+                        /* If the bit is set then it is locked */
+                        p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
+                    }
+                    bytes_covered++;
+                    bits_covered++;
+                    if (bits_covered == TAG_BITS_PER_BYTE)
+                    {
+                        /* Move to next 8 bytes */
+                        bits_covered = 0;
+                        block_count++;
+                        /* Assume unlocked before updating using locks */
+                        if (block_count < RW_T2T_SEGMENT_SIZE)
+                            p_t2t->lock_attr[block_count] = 0;
+                    }
+                }
+                xx++;
+            }
+            num_dyn_lock_bytes++;
+            xx = 0;
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_is_lock_res_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a lock or reserved or otp byte and return
+**                  TRUE or FALSE
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          TRUE, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t2t_is_lock_res_byte (UINT16 index)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+
+    p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES);
+
+    if (p_t2t->attr_seg != p_t2t->segment)
+    {
+        /* Update attributes for the current segment */
+        rw_t2t_update_attributes ();
+        p_t2t->attr_seg = p_t2t->segment;
+    }
+
+    index = index % RW_T2T_SEGMENT_BYTES;
+    /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a lock/reserved byte or not
+     * So, each array element in p_t2t->attr covers two blocks in the tag as T2 block size is 4 and array element size is 8
+     * Find the block and offset for the index (passed as argument) and Check if the offset bit in the
+     * p_t2t->attr[block/2] is set or not. If the bit is set then it is a lock/reserved byte, otherwise not */
+
+    return ((p_t2t->attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_is_read_only_byte
+**
+** Description      This function will check if the tag index passed as
+**                  argument is a locked and return
+**                  TRUE or FALSE
+**
+** Parameters:      index, the index of the byte in the tag
+**
+**
+** Returns          TRUE, if the specified index in the tag is a locked or
+**                        reserved or otp byte
+**                  FALSE, otherwise
+**
+*******************************************************************************/
+static BOOLEAN rw_t2t_is_read_only_byte (UINT16 index)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+
+    p_t2t->segment = (UINT8) (index / RW_T2T_SEGMENT_BYTES);
+
+    if (p_t2t->lock_attr_seg != p_t2t->segment)
+    {
+        /* Update lock attributes for the current segment */
+        rw_t2t_update_lock_attributes ();
+        p_t2t->lock_attr_seg = p_t2t->segment;
+    }
+
+    index = index % RW_T2T_SEGMENT_BYTES;
+    /* Every bit in p_t2t->lock_attr indicates one specific byte of the tag is a read only byte or read write byte
+     * So, each array element in p_t2t->lock_attr covers two blocks of the tag as T2 block size is 4 and array element size is 8
+     * Find the block and offset for the index (passed as argument) and Check if the offset bit in
+     * p_t2t->lock_attr[block/2] is set or not. If the bit is set then it is a read only byte, otherwise read write byte */
+
+    return ((p_t2t->lock_attr[index /8] & rw_t2t_mask_bits[index % 8]) == 0) ? FALSE:TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_set_dynamic_lock_bits
+**
+** Description      This function will set dynamic lock bits as part of
+**                  configuring tag as read only
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to set dynamic lock bits
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_dynamic_lock_bits (UINT8 *p_data)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    UINT8       write_block[T2T_BLOCK_SIZE];
+    UINT16      offset;
+    UINT16      next_offset;
+    UINT8       num_bits;
+    UINT8       next_num_bits;
+    tNFC_STATUS status      = NFC_STATUS_FAILED;
+    UINT8       num_locks;
+    UINT8       lock_count;
+    BOOLEAN     b_all_bits_are_locks = TRUE;
+
+    num_locks = 0;
+
+    memcpy (write_block, p_data, T2T_BLOCK_SIZE);
+    while (num_locks < p_t2t->num_lockbytes)
+    {
+        if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED)
+        {
+            offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset + p_t2t->lockbyte[num_locks].byte_index;
+
+            /* Check if all bits are lock bits in the byte */
+            b_all_bits_are_locks = ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
+            num_bits             =  b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+            write_block[(UINT8) (offset%T2T_BLOCK_SIZE)] |=  tags_pow (2,num_bits) - 1;
+            lock_count = num_locks + 1;
+
+            /* Set all the lock bits in the block using a sing block write command */
+            while (lock_count < p_t2t->num_lockbytes)
+            {
+                next_offset          = p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset + p_t2t->lockbyte[lock_count].byte_index;
+
+                /* Check if all bits are lock bits in the byte */
+                b_all_bits_are_locks = ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <= p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
+                next_num_bits        = b_all_bits_are_locks ? TAG_BITS_PER_BYTE : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits % TAG_BITS_PER_BYTE;
+
+                if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE)
+                {
+                    write_block[(UINT8) (next_offset % T2T_BLOCK_SIZE)] |=  tags_pow (2, next_num_bits) - 1;
+                }
+                else
+                    break;
+                lock_count ++;
+            }
+
+            p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
+            /* send WRITE command to set dynamic lock bits */
+            if ((status = rw_t2t_write ((UINT8) (offset / T2T_BLOCK_SIZE), write_block)) == NFC_STATUS_OK)
+            {
+                while (lock_count >  num_locks)
+                {
+                    /* Set update initiated flag to indicate a write command is sent to set dynamic lock bits of the block */
+                    p_t2t->lockbyte[lock_count - 1].lock_status = RW_T2T_LOCK_UPDATE_INITIATED;
+                    lock_count --;
+                }
+            }
+            else
+                status = NFC_STATUS_FAILED;
+
+            break;
+
+        }
+        num_locks++;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_set_lock_tlv
+**
+** Description      This function will set lock control tlv on the blank
+**                  activated type 2 tag based on values read from version block
+**
+** Parameters:      TAG data memory size
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to set Lock TLV
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_lock_tlv (UINT16 addr, UINT8 num_dyn_lock_bits, UINT16 locked_area_size)
+{
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    INT8        PageAddr = 0;
+    INT8        BytePerPage = 0;
+    INT8        ByteOffset = 0;
+    UINT8       a;
+    UINT8       data_block[T2T_BLOCK_SIZE];
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+    UINT8       *p;
+    UINT8       xx;
+
+    for (xx = 15; xx >0; xx--)
+    {
+        a  = (UINT8) (addr / xx);
+        a += (addr % xx) ? 1:0;
+
+        BytePerPage = (INT8) tags_log2 (a);
+        ByteOffset  = (INT8) (addr - xx * tags_pow (2, BytePerPage));
+
+        if (ByteOffset < 16)
+        {
+            PageAddr = xx;
+            break;
+        }
+    }
+
+    if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16))
+    {
+        memset (data_block, 0, T2T_BLOCK_SIZE);
+        p = data_block;
+        UINT8_TO_BE_STREAM (p, T2T_TLV_TYPE_LOCK_CTRL);
+        UINT8_TO_BE_STREAM (p, T2T_TLEN_LOCK_CTRL_TLV);
+        UINT8_TO_BE_STREAM (p, (PageAddr << 4 | ByteOffset));
+        UINT8_TO_BE_STREAM (p, num_dyn_lock_bits);
+
+        p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
+        p_t2t->tlv_value[1] = num_dyn_lock_bits;
+        p_t2t->tlv_value[2] = (UINT8) (BytePerPage << 4 | tags_log2 (locked_area_size));
+
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
+
+        /* send WRITE-E8 command */
+        if ((status = rw_t2t_write (T2T_FIRST_DATA_BLOCK, data_block)) == NFC_STATUS_OK)
+        {
+            p_t2t->b_read_data = FALSE;
+        }
+        else
+            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    }
+    else
+        status = NFC_STATUS_REJECTED;
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_set_cc
+**
+** Description      This function will set Capability Container on the activated
+**                  type 2 tag with default values of CC0, CC1, CC4 and specified
+**                  CC3 value
+**
+** Parameters:      CC3 value of the tag
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to set CC
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_set_cc (UINT8 tms)
+{
+    UINT8               cc_block[T2T_BLOCK_SIZE];
+    tRW_T2T_CB          *p_t2t  = &rw_cb.tcb.t2t;
+    tNFC_STATUS         status  = NFC_STATUS_FAILED;
+    UINT8               *p;
+
+    memset (cc_block, 0, T2T_BLOCK_SIZE);
+    memset (p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
+    p = cc_block;
+
+    /* Prepare Capability Container */
+    UINT8_TO_BE_STREAM (p, T2T_CC0_NMN);
+    UINT8_TO_BE_STREAM (p, T2T_CC1_VNO);
+    UINT8_TO_BE_STREAM (p, tms);
+    UINT8_TO_BE_STREAM (p, T2T_CC3_RWA_RW);
+
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
+
+    /* send WRITE-E8 command */
+    if ((status = rw_t2t_write (T2T_CC_BLOCK, cc_block)) == NFC_STATUS_OK)
+    {
+        p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
+        p_t2t->b_read_hdr = FALSE;
+    }
+    else
+        p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_format_tag
+**
+** Description      This function will format tag based on Manufacturer ID
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to format Tag
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_format_tag (void)
+{
+    tRW_T2T_CB          *p_t2t  = &rw_cb.tcb.t2t;
+    const tT2T_INIT_TAG *p_ret;
+    UINT8               tms;
+    tNFC_STATUS         status  = NFC_STATUS_FAILED;
+    BOOLEAN             b_blank_tag = TRUE;
+
+    if ((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) == NULL)
+    {
+        RW_TRACE_WARNING1 ("rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the tag!", p_t2t->tag_hdr[0]);
+        return (NFC_STATUS_REJECTED);
+    }
+
+    if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0)
+    {
+        /* If OTP tag has valid NDEF Message, cannot format the tag */
+        if (  (p_t2t->ndef_msg_len > 0)
+            &&(p_ret->b_otp)  )
+        {
+            RW_TRACE_WARNING0 ("rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!");
+            return (NFC_STATUS_FAILED);
+        }
+
+        if (  ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) && (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN))
+            ||((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) && (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO)) )
+        {
+            RW_TRACE_WARNING0 ("rw_t2t_format_tag - Tag not blank to Format!");
+            return (NFC_STATUS_FAILED);
+        }
+        else
+        {
+            tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE];
+            b_blank_tag = FALSE;
+        }
+    }
+    else
+        tms = p_ret->tms;
+
+    memset (p_t2t->tag_data, 0, T2T_READ_DATA_LEN);
+
+    if (!b_blank_tag || !p_ret->b_multi_version)
+    {
+        status = rw_t2t_set_cc (tms);
+    }
+    else if (p_ret->version_block != 0)
+    {
+        /* If Version number is not read, READ it now */
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
+
+        if ((status = rw_t2t_read (p_ret->version_block)) == NFC_STATUS_OK)
+            p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
+        else
+            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    }
+    else
+    {
+        /* UID block is the version block */
+        p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
+        rw_t2t_handle_format_tag_rsp (p_t2t->tag_hdr);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t2t_soft_lock_tag
+**
+** Description      This function will soft lock the tag after validating CC.
+**
+** Returns
+**                  NFC_STATUS_OK, Command sent to soft lock the tag
+**                  NFC_STATUS_FAILED: otherwise
+**
+*******************************************************************************/
+tNFC_STATUS rw_t2t_soft_lock_tag (void)
+{
+    tRW_T2T_CB  *p_t2t  = &rw_cb.tcb.t2t;
+    tNFC_STATUS status  = NFC_STATUS_FAILED;
+    UINT8       write_block[T2T_BLOCK_SIZE];
+    UINT8       num_locks;
+
+    /* If CC block is read and cc3 is soft locked, reject the command */
+    if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
+    {
+        RW_TRACE_ERROR1 ("rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (p_t2t->b_hard_lock)
+    {
+        /* Should have performed NDEF Detection on dynamic memory structure tag, before permanently converting to Read only
+         * Even when no lock control tlv is present, default lock bytes should be present */
+
+        if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) && (p_t2t->num_lockbytes == 0))
+        {
+            RW_TRACE_ERROR0 ("rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard lock the tag");
+            return (NFC_STATUS_FAILED);
+        }
+
+        /* On dynamic memory structure tag, reset all lock bytes status to 'Not Updated' if not in Updated status */
+        num_locks = 0;
+        while (num_locks < p_t2t->num_lockbytes)
+        {
+            if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
+                p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
+            num_locks++;
+        }
+    }
+
+    memcpy (write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
+    write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
+
+    p_t2t->substate    = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
+    /* First Soft lock the tag */
+    if ((status = rw_t2t_write (T2T_CC_BLOCK, write_block)) == NFC_STATUS_OK)
+    {
+        p_t2t->state        = RW_T2T_STATE_SET_TAG_RO;
+        p_t2t->b_read_hdr   = FALSE;
+    }
+    else
+    {
+        p_t2t->substate     = RW_T2T_SUBSTATE_NONE;
+    }
+    return status;
+}
+
+/*****************************************************************************
+**
+** Function         RW_T2tFormatNDef
+**
+** Description
+**      Format Tag content
+**
+** Returns
+**      NFC_STATUS_OK, Command sent to format Tag
+**      NFC_STATUS_FAILED: otherwise
+**
+*****************************************************************************/
+tNFC_STATUS RW_T2tFormatNDef (void)
+{
+    tRW_T2T_CB          *p_t2t  = &rw_cb.tcb.t2t;
+    tNFC_STATUS         status  = NFC_STATUS_FAILED;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_WARNING1 ("RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (!p_t2t->b_read_hdr)
+    {
+        /* If UID is not read, READ it now */
+        p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
+
+        if ((status = rw_t2t_read (0)) == NFC_STATUS_OK)
+            p_t2t->state    = RW_T2T_STATE_FORMAT_TAG;
+        else
+            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    }
+    else
+        status = rw_t2t_format_tag ();
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tLocateTlv
+**
+** Description      This function is used to perform TLV detection on a Type 2
+**                  tag, and retrieve the tag's TLV attribute information.
+**
+**                  Before using this API, the application must call
+**                  RW_SelectTagType to indicate that a Type 2 tag has been
+**                  activated.
+**
+** Parameters:      tlv_type : TLV to detect
+**
+** Returns          NCI_STATUS_OK, if detection was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tLocateTlv (UINT8 tlv_type)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status;
+    UINT16      block;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_BUSY);
+    }
+
+    if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) && (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV))
+    {
+        RW_TRACE_API1 ("RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (  (tlv_type == TAG_LOCK_CTRL_TLV)
+        &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC)  )
+    {
+        RW_TRACE_API1 ("RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x", p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (  (tlv_type == TAG_NDEF_TLV)
+        &&(p_t2t->b_read_hdr)
+        &&(p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)  )
+    {
+        RW_TRACE_WARNING3 ("RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: 0x%02x", p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE], p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+        return (NFC_STATUS_FAILED);
+    }
+
+    p_t2t->work_offset = 0;
+    p_t2t->tlv_detect  = tlv_type;
+
+    /* Reset control block variables based on type of tlv to detect */
+    if (tlv_type == TAG_LOCK_CTRL_TLV)
+    {
+        p_t2t->num_lockbytes    = 0;
+        p_t2t->num_lock_tlvs    = 0;
+    }
+    else if (tlv_type == TAG_MEM_CTRL_TLV)
+    {
+        p_t2t->num_mem_tlvs     = 0;
+    }
+    else if (tlv_type == TAG_NDEF_TLV)
+    {
+        p_t2t->ndef_msg_offset  = 0;
+        p_t2t->num_lockbytes    = 0;
+        p_t2t->num_lock_tlvs    = 0;
+        p_t2t->num_mem_tlvs     = 0;
+        p_t2t->ndef_msg_len     = 0;
+        p_t2t->ndef_status      = T2T_NDEF_NOT_DETECTED;
+    }
+    else
+    {
+        p_t2t->prop_msg_len     = 0;
+    }
+
+    if (!p_t2t->b_read_hdr)
+    {
+        /* First read CC block */
+        block                   = 0;
+        p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_READ_CC;
+    }
+    else
+    {
+        /* Read first data block */
+        block                   = T2T_FIRST_DATA_BLOCK;
+        p_t2t->substate         = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
+    }
+
+    /* Start reading tag, looking for the specified TLV */
+    if ((status = rw_t2t_read ((UINT16) block)) == NFC_STATUS_OK)
+    {
+        p_t2t->state    = RW_T2T_STATE_DETECT_TLV;
+    }
+    else
+    {
+        p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    }
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tDetectNDef
+**
+** Description      This function is used to perform NDEF detection on a Type 2
+**                  tag, and retrieve the tag's NDEF attribute information.
+**
+**                  Before using this API, the application must call
+**                  RW_SelectTagType to indicate that a Type 2 tag has been
+**                  activated.
+**
+** Parameters:      none
+**
+** Returns          NCI_STATUS_OK,if detect op started.Otherwise,error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tDetectNDef (void)
+{
+    return RW_T2tLocateTlv (TAG_NDEF_TLV);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tReadNDef
+**
+** Description      Retrieve NDEF contents from a Type2 tag.
+**
+**                  The RW_T2T_NDEF_READ_EVT event is used to notify the
+**                  application after reading the NDEF message.
+**
+**                  Before using this API, the RW_T2tDetectNDef function must
+**                  be called to verify that the tag contains NDEF data, and to
+**                  retrieve the NDEF attributes.
+**
+**                  Internally, this command will be separated into multiple Tag2
+**                  Read commands (if necessary) - depending on the NDEF Msg size
+**
+** Parameters:      p_buffer:   The buffer into which to read the NDEF message
+**                  buf_len:    The length of the buffer
+**
+** Returns          NCI_STATUS_OK, if read was started. Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tReadNDef (UINT8 *p_buffer, UINT16 buf_len)
+{
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+    tNFC_STATUS status = NFC_STATUS_OK;
+    UINT16      block;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED)
+    {
+        RW_TRACE_ERROR0 ("RW_T2tReadNDef - Error: NDEF detection not performed yet");
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (buf_len < p_t2t->ndef_msg_len)
+    {
+        RW_TRACE_WARNING2 ("RW_T2tReadNDef - buffer size: %u  less than NDEF msg sise: %u", buf_len, p_t2t->ndef_msg_len);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (!p_t2t->ndef_msg_len)
+    {
+        RW_TRACE_WARNING1 ("RW_T2tReadNDef - NDEF Message length is zero ", p_t2t->ndef_msg_len);
+        return (NFC_STATUS_NOT_INITIALIZED);
+    }
+
+    p_t2t->p_ndef_buffer  = p_buffer;
+    p_t2t->work_offset    = 0;
+
+    block  = (UINT16) (p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
+    block -= block % T2T_READ_BLOCKS;
+
+    p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+
+    if (  (block == T2T_FIRST_DATA_BLOCK)
+        &&(p_t2t->b_read_data)  )
+    {
+        p_t2t->state        = RW_T2T_STATE_READ_NDEF;
+        p_t2t->block_read   = T2T_FIRST_DATA_BLOCK;
+        rw_t2t_handle_ndef_read_rsp (p_t2t->tag_data);
+    }
+    else
+    {
+        /* Start reading NDEF Message */
+        if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
+        {
+            p_t2t->state    = RW_T2T_STATE_READ_NDEF;
+        }
+    }
+
+    return (status);
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tWriteNDef
+**
+** Description      Write NDEF contents to a Type2 tag.
+**
+**                  Before using this API, the RW_T2tDetectNDef
+**                  function must be called to verify that the tag contains
+**                  NDEF data, and to retrieve the NDEF attributes.
+**
+**                  The RW_T2T_NDEF_WRITE_EVT callback event will be used to
+**                  notify the application of the response.
+**
+**                  Internally, this command will be separated into multiple Tag2
+**                  Write commands (if necessary) - depending on the NDEF Msg size
+**
+** Parameters:      msg_len:    The length of the buffer
+**                  p_msg:      The NDEF message to write
+**
+** Returns          NCI_STATUS_OK,if write was started. Otherwise, error status
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tWriteNDef (UINT16 msg_len, UINT8 *p_msg)
+{
+    tRW_T2T_CB  *p_t2t          = &rw_cb.tcb.t2t;
+    UINT16      block;
+    const       tT2T_INIT_TAG *p_ret;
+
+    tNFC_STATUS status          = NFC_STATUS_OK;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW)
+    {
+        RW_TRACE_ERROR1 ("RW_T2tWriteNDef - Write access not granted - CC3: %u", p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
+        return (NFC_STATUS_REFUSED);
+    }
+
+    if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED)
+    {
+        RW_TRACE_ERROR0 ("RW_T2tWriteNDef - Error: NDEF detection not performed!");
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Check if there is enough memory on the tag */
+    if (msg_len > p_t2t->max_ndef_msg_len)
+    {
+        RW_TRACE_ERROR1 ("RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes", p_t2t->max_ndef_msg_len);
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message as it may corrupt the tag */
+    if (  (p_t2t->ndef_msg_len > 0)
+        &&((p_ret = t2t_tag_init_data (p_t2t->tag_hdr[0], FALSE, 0)) != NULL)
+        &&(p_ret->b_otp)  )
+    {
+        RW_TRACE_WARNING0 ("RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!");
+        return (NFC_STATUS_FAILED);
+    }
+    p_t2t->p_new_ndef_buffer = p_msg;
+    p_t2t->new_ndef_msg_len  = msg_len;
+    p_t2t->work_offset       = 0;
+
+    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK;
+    /* Read first NDEF Block before updating NDEF */
+
+    block = (UINT16) (p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
+
+    if (  (block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS))
+        &&(p_t2t->b_read_data)  )
+    {
+        p_t2t->state        = RW_T2T_STATE_WRITE_NDEF;
+        p_t2t->block_read   = block;
+        rw_t2t_handle_ndef_write_rsp (&p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]);
+    }
+    else
+    {
+        if ((status = rw_t2t_read (block)) == NFC_STATUS_OK)
+            p_t2t->state    = RW_T2T_STATE_WRITE_NDEF;
+        else
+            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T2tSetTagReadOnly
+**
+** Description      This function can be called to set T2 tag as read only.
+**
+** Parameters:      b_hard_lock:   To indicate hard lock the tag or not
+**
+** Returns          NCI_STATUS_OK, if setting tag as read only was started.
+**                  Otherwise, error status.
+**
+*******************************************************************************/
+tNFC_STATUS RW_T2tSetTagReadOnly (BOOLEAN b_hard_lock)
+{
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+    tRW_T2T_CB  *p_t2t = &rw_cb.tcb.t2t;
+
+    if (p_t2t->state != RW_T2T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    p_t2t->b_hard_lock = b_hard_lock;
+
+    if (!p_t2t->b_read_hdr)
+    {
+        /* Read CC block before configuring tag as Read only */
+        p_t2t->substate    = RW_T2T_SUBSTATE_WAIT_READ_CC;
+        if ((status = rw_t2t_read ((UINT16) 0)) == NFC_STATUS_OK)
+        {
+            p_t2t->state    = RW_T2T_STATE_SET_TAG_RO;
+        }
+        else
+            p_t2t->substate = RW_T2T_SUBSTATE_NONE;
+    }
+    else
+        status = rw_t2t_soft_lock_tag ();
+
+    return status;
+}
+
+#endif /* (defined ((RW_NDEF_INCLUDED) && (RW_NDEF_INCLUDED == TRUE)) */
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/rw_t3t.c b/src/nfc/tags/rw_t3t.c
new file mode 100644
index 0000000..ea405e1
--- /dev/null
+++ b/src/nfc/tags/rw_t3t.c
@@ -0,0 +1,2713 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 3 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "nci_hmsgs.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+/* Definitions for constructing t3t command messages */
+#define RW_T3T_FL_PADDING   0x01        /* Padding needed for last NDEF block */
+#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)    /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are < 256) */
+#define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)    /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are >= 256) */
+
+/* Definitions for SENSF_RES */
+#define RW_T3T_SENSF_RES_RD_OFFSET      17  /* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES length) */
+#define RW_T3T_SENSF_RES_RD_LEN         2   /* Size of RD in SENSF_RES   */
+
+/* Timeout definitions for commands */
+#define RW_T3T_POLL_CMD_TIMEOUT_TICKS                               ((RW_T3T_TOUT_RESP*2*QUICK_TIMER_TICKS_PER_SEC) / 1000)
+#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS                            ((RW_T3T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000)
+#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS                          (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
+
+/* Macro to extract major version from NDEF version byte */
+#define T3T_GET_MAJOR_VERSION(ver)      (ver>>4)
+
+/* Enumeration of API commands */
+enum
+{
+    RW_T3T_CMD_DETECT_NDEF,
+    RW_T3T_CMD_CHECK_NDEF,
+    RW_T3T_CMD_UPDATE_NDEF,
+    RW_T3T_CMD_CHECK,
+    RW_T3T_CMD_UPDATE,
+    RW_T3T_CMD_SEND_RAW_FRAME,
+    RW_T3T_CMD_GET_SYSTEM_CODES,
+    RW_T3T_CMD_FORMAT,
+
+    RW_T3T_CMD_MAX
+};
+
+/* RW_CBACK events corresponding to API comands */
+const UINT8 rw_t3t_api_res_evt[RW_T3T_CMD_MAX] =
+{
+    RW_T3T_NDEF_DETECT_EVT,         /* RW_T3T_CMD_DETECT_NDEF */
+    RW_T3T_CHECK_CPLT_EVT,          /* RW_T3T_CMD_CHECK_NDEF  */
+    RW_T3T_UPDATE_CPLT_EVT,         /* RW_T3T_CMD_UPDATE_NDEF */
+    RW_T3T_CHECK_CPLT_EVT,          /* RW_T3T_CMD_CHECK */
+    RW_T3T_UPDATE_CPLT_EVT,         /* RW_T3T_CMD_UPDATE */
+    RW_T3T_RAW_FRAME_EVT,           /* RW_T3T_CMD_SEND_RAW_FRAME */
+    RW_T3T_GET_SYSTEM_CODES_EVT,    /* RW_T3T_CMD_GET_SYSTEM_CODES */
+    RW_T3T_FORMAT_CPLT_EVT          /* RW_T3T_CMD_FORMAT */
+};
+
+/* States */
+enum
+{
+    RW_T3T_STATE_NOT_ACTIVATED,
+    RW_T3T_STATE_IDLE,
+    RW_T3T_STATE_COMMAND_PENDING
+};
+
+/* Sub-states */
+enum
+{
+    /* Sub states for getting system codes */
+    RW_T3T_GET_SC_SST_POLL_WILDCARD,        /* Waiting for wilcard poll response */
+    RW_T3T_GET_SC_SST_POLL_NDEF,            /* Waiting for NDEF poll response */
+    RW_T3T_GET_SC_SST_REQUEST_SC,           /* Waiting for REQUEST_SYSTEM_CODE response */
+
+    /* Sub states for formatting Felica-Lite */
+    RW_T3T_FMT_SST_POLL_FELICA_LITE,        /* Waiting for POLL Felica-Lite response (for formatting) */
+    RW_T3T_FMT_SST_CHECK_MC_BLK,            /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
+    RW_T3T_FMT_SST_UPDATE_MC_BLK,           /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
+    RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB       /* Waiting for NDEF attribute block-write to complete */
+};
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_t3t_cmd_str (UINT8 cmd_id);
+static char *rw_t3t_state_str (UINT8 state_id);
+#endif
+
+
+/* Local static functions */
+static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[]);
+static BT_HDR *rw_t3t_get_cmd_buf (void);
+static tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg);
+static void rw_t3t_handle_get_system_codes_cplt (void);
+static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
+
+
+/* Default NDEF attribute information block (used when formatting Felica-Lite tags) */
+#define RW_T3T_DEFAULT_FELICALITE_NBR       4   /* NBr (max block reads per cmd)*/
+#define RW_T3T_DEFAULT_FELICALITE_NBW       1   /* NBw (max block write per cmd)*/
+#define RW_T3T_DEFAULT_FELICALITE_NMAXB     13  /* Nmaxb (max size in blocks)   */
+#define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM  ((T3T_MSG_NDEF_VERSION +                    \
+                                                            RW_T3T_DEFAULT_FELICALITE_NBR +         \
+                                                            RW_T3T_DEFAULT_FELICALITE_NBW +         \
+                                                            (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8) +  \
+                                                            (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF) +\
+                                                            T3T_MSG_NDEF_WRITEF_OFF +               \
+                                                            T3T_MSG_NDEF_RWFLAG_RW) & 0xFFFF)
+
+const UINT8 rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] =
+{
+    T3T_MSG_NDEF_VERSION,                   /* Ver                          */
+    RW_T3T_DEFAULT_FELICALITE_NBR,          /* NBr (max block reads per cmd)*/
+    RW_T3T_DEFAULT_FELICALITE_NBW,          /* NBw (max block write per cmd)*/
+    (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8),   /* Nmaxb (max size in blocks)   */
+    (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF), /* Nmaxb (max size in blocks)   */
+    0, 0, 0, 0,                             /* Unused                       */
+    T3T_MSG_NDEF_WRITEF_OFF,                /* WriteF                       */
+    T3T_MSG_NDEF_RWFLAG_RW,                 /* RW Flag                      */
+    0, 0, 0,                                /* Ln (current size in bytes)   */
+
+    (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >> 8),     /* checksum (high-byte) */
+    (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM & 0xFF)    /* checksum (low-byte)  */
+
+};
+
+/*****************************************************************************
+**  Type3 TAG COMMANDS
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         rw_t3t_process_error
+**
+** Description      Process error (timeout or CRC error)
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_process_error (tNFC_STATUS status)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    UINT8 evt;
+    tRW_DATA evt_data;
+    BT_HDR *p_cmd_buf;
+
+    if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING)
+    {
+        if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES)
+        {
+            /* For GetSystemCode: either tag did not respond to requested POLL, or REQUEST_SYSTEM_CODE command */
+            rw_t3t_handle_get_system_codes_cplt ();
+            return;
+        }
+        /* Retry sending command if retry-count < max */
+        else if (rw_cb.cur_retry < RW_MAX_RETRIES)
+        {
+            /* retry sending the command */
+            rw_cb.cur_retry++;
+
+            RW_TRACE_DEBUG2 ("T3T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
+
+            /* allocate a new buffer for message */
+            if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+            {
+                memcpy (p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof (BT_HDR) + p_cb->p_cur_cmd_buf->offset + p_cb->p_cur_cmd_buf->len);
+
+                if (rw_t3t_send_to_lower (p_cmd_buf) == NFC_STATUS_OK)
+                {
+                    /* Start timer for waiting for response */
+                    nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, p_cb->cur_tout);
+                    return;
+                }
+                else
+                {
+                    /* failure - could not send buffer */
+                    GKI_freebuf (p_cmd_buf);
+                }
+            }
+        }
+        else
+        {
+            RW_TRACE_DEBUG1 ("T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
+        }
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        /* update failure count */
+        rw_main_update_fail_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+        p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+        /* Notify app of result (if there was a pending command) */
+        if (p_cb->cur_cmd < RW_T3T_CMD_MAX)
+        {
+            /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise NFC_STATUS_TIMEOUT */
+            evt_data.status = status;
+            evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
+
+            /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
+            if (evt == RW_T3T_NDEF_DETECT_EVT)
+            {
+                evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
+            }
+
+            (*(rw_cb.p_cback)) (evt, &evt_data);
+        }
+    }
+    else
+    {
+        evt_data.status = status;
+        (*(rw_cb.p_cback)) (RW_T3T_INTF_ERROR_EVT, &evt_data);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_start_poll_timer
+**
+** Description      Start the timer for T3T POLL Command
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_start_poll_timer (tRW_T3T_CB *p_cb)
+{
+    nfc_start_quick_timer (&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE, RW_T3T_POLL_CMD_TIMEOUT_TICKS);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_handle_nci_poll_ntf
+**
+** Description      Handle NCI_T3T_POLLING_NTF
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+    tRW_DATA evt_data;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    /* stop timer for poll response */
+    nfc_stop_quick_timer (&p_cb->poll_timer);
+
+    /* Stop t3t timer (if started) */
+    if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
+    {
+        p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+        evt_data.status = nci_status;
+        p_cb->rw_state = RW_T3T_STATE_IDLE;
+        (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+    }
+    else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
+    {
+        /* Handle POLL ntf in response to get system codes */
+        p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
+        rw_t3t_handle_get_sc_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
+    }
+    else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
+    {
+        /* Handle POLL ntf in response to get system codes */
+        p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+        rw_t3t_handle_fmt_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
+    }
+    else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
+    {
+        /* Handle POLL ntf in response to ndef detection */
+        p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+        rw_t3t_handle_ndef_detect_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
+    }
+    else
+    {
+        /* Handle POLL ntf in response to RW_T3tPoll */
+        if ((evt_data.t3t_poll.status = nci_status) == NCI_STATUS_OK)
+        {
+            evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
+            evt_data.t3t_poll.response_num = num_responses;
+            evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
+            evt_data.t3t_poll.response_buf = p_sensf_res_buf;
+        }
+
+        p_cb->rw_state = RW_T3T_STATE_IDLE;
+        (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, &evt_data);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t3t_handle_get_system_codes_cplt
+**
+** Description      Notify upper layer of system codes
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_handle_get_system_codes_cplt (void)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    tRW_DATA evt_data;
+    UINT8 i;
+
+    evt_data.t3t_sc.status = NFC_STATUS_OK;
+    evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
+    evt_data.t3t_sc.p_system_codes   = p_cb->system_codes;
+
+    RW_TRACE_DEBUG1 ("rw_t3t_handle_get_system_codes_cplt, number of systems: %i", evt_data.t3t_sc.num_system_codes);
+    for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++)
+    {
+        RW_TRACE_DEBUG2 ("   system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
+    }
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    (*(rw_cb.p_cback)) (RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
+
+
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_format_cplt
+**
+** Description      Notify upper layer of format complete
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_format_cplt (tNFC_STATUS status)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    tRW_DATA evt_data;
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+    /* Notify upper layer of format complete */
+    evt_data.status = status;
+    (*(rw_cb.p_cback)) (RW_T3T_FORMAT_CPLT_EVT, &evt_data);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_process_timeout
+**
+** Description      Process timeout
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    tRW_DATA evt_data;
+
+    /* Check which timer timed out */
+    if (p_tle == &p_cb->timer)
+    {
+        /* UPDATE/CHECK response timeout */
+#if (BT_TRACE_VERBOSE == TRUE)
+        RW_TRACE_ERROR3 ("T3T timeout. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd));
+#else
+        RW_TRACE_ERROR2 ("T3T timeout. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
+#endif
+
+        rw_t3t_process_error (NFC_STATUS_TIMEOUT);
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("T3T POLL timeout.");
+
+        /* POLL response timeout */
+        if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
+        {
+            /* POLL timeout for presence check */
+            p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+            evt_data.status = NFC_STATUS_FAILED;
+            p_cb->rw_state = RW_T3T_STATE_IDLE;
+            (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
+        }
+        else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
+        {
+            /* POLL timeout for getting system codes */
+            p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
+            rw_t3t_handle_get_system_codes_cplt ();
+        }
+        else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
+        {
+            /* POLL timeout for formatting Felica Lite */
+            p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+            RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
+            rw_t3t_format_cplt (NFC_STATUS_FAILED);
+        }
+        else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
+        {
+            /* POLL timeout for ndef detection */
+            p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+            rw_t3t_handle_ndef_detect_poll_rsp (p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL);
+        }
+        else
+        {
+            /* Timeout waiting for response for RW_T3tPoll */
+            evt_data.t3t_poll.status = NFC_STATUS_FAILED;
+            p_cb->rw_state = RW_T3T_STATE_IDLE;
+            (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, (tRW_DATA *) &evt_data);
+        }
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t3t_process_frame_error
+**
+** Description      Process frame crc error
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_process_frame_error (void)
+{
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_ERROR3 ("T3T frame error. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd));
+#else
+    RW_TRACE_ERROR2 ("T3T frame error. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
+#endif
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Update stats */
+    rw_main_update_crc_error_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+    /* Process the error */
+    rw_t3t_process_error (NFC_STATUS_MSG_CORRUPTED);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_send_to_lower
+**
+** Description      Send command to lower layer
+**
+** Returns          status of the send
+**
+*******************************************************************************/
+tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg)
+{
+    UINT8 *p;
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    BOOLEAN is_retry;
+    /* Update stats */
+    rw_main_update_tx_stats (p_msg->len, ((rw_cb.cur_retry==0) ? FALSE : TRUE));
+#endif  /* RW_STATS_INCLUDED */
+
+    /* Set NFC-F SoD field (payload len + 1) */
+    p_msg->offset -= 1;         /* Point to SoD field */
+    p = (UINT8 *) (p_msg+1) + p_msg->offset;
+    UINT8_TO_STREAM (p, (p_msg->len+1));
+    p_msg->len += 1;            /* Increment len to include SoD */
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispT3TagMessage (p_msg, FALSE);
+#endif
+
+    return (NFC_SendData (NFC_RF_CONN_ID, p_msg));
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_get_cmd_buf
+**
+** Description      Get a buffer for sending T3T messages
+**
+** Returns          BT_HDR *
+**
+*****************************************************************************/
+BT_HDR *rw_t3t_get_cmd_buf (void)
+{
+    BT_HDR *p_cmd_buf;
+
+    if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
+    {
+        /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
+        p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
+        p_cmd_buf->len = 0;
+    }
+
+    return (p_cmd_buf);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_cmd
+**
+** Description      Send command to tag, and start timer for response
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_ms)
+{
+    tNFC_STATUS retval;
+
+    /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
+    rw_cb.cur_retry = 0;
+    memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (BT_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
+
+    p_cb->cur_cmd = rw_t3t_cmd;
+    p_cb->cur_tout = timeout_ms;
+    p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+
+    if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
+    {
+        /* Start timer for waiting for response */
+        nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ms);
+    }
+    else
+    {
+        /* Error sending */
+        p_cb->rw_state = RW_T3T_STATE_IDLE;
+    }
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_update_ndef_attribute_cmd
+**
+** Description      Send UPDATE command for Attribute Information
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd (tRW_T3T_CB *p_cb, BOOLEAN write_in_progress)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    BT_HDR *p_cmd_buf;
+    UINT8 *p_cmd_start, *p;
+    UINT16 checksum, i;
+    UINT8 write_f;
+    UINT32 ln;
+    UINT8 *p_ndef_attr_info_start;
+
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        /* Construct T3T message */
+        p = p_cmd_start  = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+        /* Add UPDATE opcode to message  */
+        UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
+
+        /* Add IDm to message */
+        ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+        /* Add Service code list */
+        UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
+        UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);     /* Service code (little-endian format) */
+
+        /* Add number of blocks in this UPDATE command */
+        UINT8_TO_STREAM (p, 1);                      /* Number of blocks to write in this command */
+
+        /* Block List element: the NDEF attribute information block (block 0) */
+        UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+        UINT8_TO_STREAM (p, 0);
+
+        /* Add payload (Attribute information block) */
+        p_ndef_attr_info_start = p;                              /* Save start of a NDEF attribute info block for checksum */
+        UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION);
+        UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);
+        UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);
+        UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);
+        UINT32_TO_STREAM (p, 0);
+
+        /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
+        if (write_in_progress)
+        {
+            write_f = T3T_MSG_NDEF_WRITEF_ON;
+            ln = p_cb->ndef_attrib.ln;
+        }
+        /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
+        else
+        {
+            write_f = T3T_MSG_NDEF_WRITEF_OFF;
+            ln = p_cb->ndef_msg_len;
+        }
+        UINT8_TO_STREAM (p, write_f);
+        UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag);
+        UINT8_TO_STREAM (p, (ln>>16) & 0xFF);    /* High byte (of 3) of Ln */
+        UINT8_TO_STREAM (p, (ln>>8) & 0xFF);     /* Middle byte (of 3) of Ln */
+        UINT8_TO_STREAM (p, (ln) & 0xFF);        /* Low byte (of 3) of Ln */
+
+        /* Calculate and append Checksum */
+        checksum = 0;
+        for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
+        {
+            checksum+=p_ndef_attr_info_start[i];
+        }
+        UINT16_TO_BE_STREAM (p, checksum);
+
+
+        /* Calculate length of message */
+        p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+        /* Send the T3T message */
+        retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+    }
+    else
+    {
+        retval = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_next_ndef_update_cmd
+**
+** Description      Send next segment of NDEF message to update
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_next_ndef_update_cmd (tRW_T3T_CB *p_cb)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    UINT16 block_id;
+    UINT16 first_block_to_write;
+    UINT16 ndef_blocks_to_write, ndef_blocks_remaining;
+    UINT32 ndef_bytes_remaining, ndef_padding = 0;
+    UINT8 flags = 0;
+    UINT8 *p_cur_ndef_src_offset;
+    BT_HDR *p_cmd_buf;
+    UINT8 *p_cmd_start, *p;
+    UINT8 blocks_per_update;
+    UINT32 timeout;
+
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        /* Construct T3T message */
+        p = p_cmd_start  = (UINT8 *) (p_cmd_buf + 1) + p_cmd_buf->offset;
+
+        /* Calculate number of ndef bytes remaining to write */
+        ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
+
+        /* Calculate number of blocks remaining to write */
+        ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4);      /* ndef blocks remaining (rounded upward) */
+
+        /* Calculate first NDEF block ID for this UPDATE command */
+        first_block_to_write = (UINT16) ((p_cb->ndef_msg_bytes_sent >> 4) + 1);
+
+        /* Calculate max number of blocks per write. */
+        if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100)
+        {
+            /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */
+            blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
+        }
+        else
+        {
+            /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */
+            blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
+        }
+
+        /* Check if blocks_per_update is bigger than what peer allows */
+        if (blocks_per_update > p_cb->ndef_attrib.nbw)
+            blocks_per_update = p_cb->ndef_attrib.nbw;
+
+        /* Check if remaining blocks can fit into one UPDATE command */
+        if (ndef_blocks_remaining <= blocks_per_update)
+        {
+            /* remaining blocks can fit into one UPDATE command */
+            ndef_blocks_to_write = ndef_blocks_remaining;
+        }
+        else
+        {
+            /* Remaining blocks cannot fit into one UPDATE command */
+            ndef_blocks_to_write = blocks_per_update;
+        }
+
+
+        /* Write to command header for UPDATE */
+
+        /* Add UPDATE opcode to message  */
+        UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
+
+        /* Add IDm to message */
+        ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+        /* Add Service code list */
+        UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
+        UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);     /* Service code (little-endian format) */
+
+
+        /* Add number of blocks in this UPDATE command */
+        UINT8_TO_STREAM (p, ndef_blocks_to_write);   /* Number of blocks to write in this command */
+        timeout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) ndef_blocks_to_write;
+
+        for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++)
+        {
+            if (block_id<256)
+            {
+                /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
+                UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);    /* byte0: len=1; access-mode=0; service code list order=0 */
+                UINT8_TO_STREAM (p, block_id);                                   /* byte1: block number */
+            }
+            else
+            {
+                /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
+                UINT8_TO_STREAM (p, 0x00);               /* byte0: len=0; access-mode=0; service code list order=0 */
+                UINT16_TO_STREAM (p, block_id);          /* byte1-2: block number in little-endian format */
+            }
+
+        }
+
+        /* Add NDEF payload */
+
+        /* If this sending last block of NDEF,  check if padding is needed to make payload a multiple of 16 bytes */
+        if (ndef_blocks_to_write == ndef_blocks_remaining)
+        {
+            ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
+            if (ndef_padding)
+            {
+                flags |= RW_T3T_FL_PADDING;
+                ndef_blocks_to_write--;         /* handle the last block separately if it needs padding */
+            }
+        }
+
+        /* Add NDEF payload to the message */
+        p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
+
+
+        ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
+        p_cb->ndef_msg_bytes_sent += ((UINT32) ndef_blocks_to_write * 16);
+
+        if (flags & RW_T3T_FL_PADDING)
+        {
+            /* Add last of the NDEF message */
+            p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
+            ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding));
+            p_cb->ndef_msg_bytes_sent += (16-ndef_padding);
+
+            /* Add padding */
+            memset (p, 0, ndef_padding);
+            p+=ndef_padding;
+        }
+
+        /* Calculate length of message */
+        p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+        /* Send the T3T message */
+        retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
+    }
+    else
+    {
+        retval = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return (retval);
+}
+
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_next_ndef_check_cmd
+**
+** Description      Send command for reading next segment of NDEF message
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    UINT16 block_id;
+    UINT16 ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
+    UINT32 ndef_bytes_remaining;
+    BT_HDR *p_cmd_buf;
+    UINT8 *p_cmd_start, *p;
+
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        /* Construct T3T message */
+        p = p_cmd_start  = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+        /* Calculate number of ndef bytes remaining to read */
+        ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
+
+        /* Calculate number of blocks remaining to read */
+        ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4);      /* ndef blocks remaining (rounded upward) */
+
+        /* Calculate first NDEF block ID */
+        first_block_to_read = (UINT16) ((p_cb->ndef_rx_offset >> 4) + 1);
+
+        /* Check if remaining blocks can fit into one CHECK command */
+        if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr)
+        {
+            /* remaining blocks can fit into one CHECK command */
+            cur_blocks_to_read = ndef_blocks_remaining;
+            p_cb->ndef_rx_readlen = ndef_bytes_remaining;
+            p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+        }
+        else
+        {
+            /* Remaining blocks cannot fit into one CHECK command */
+            cur_blocks_to_read = p_cb->ndef_attrib.nbr;            /* Read maximum number of blocks allowed by the peer */
+            p_cb->ndef_rx_readlen = ((UINT32) p_cb->ndef_attrib.nbr * 16);
+        }
+
+        RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
+            ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
+
+        /* Write to command header for UPDATE */
+
+        /* Add UPDATE opcode to message  */
+        UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
+
+        /* Add IDm to message */
+        ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+        /* Add Service code list */
+        UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
+
+        /* Service code (little-endian format) . If NDEF is read-only, then use T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
+        if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+        {
+            UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);
+        }
+        else
+        {
+            UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);
+        }
+
+        /* Add number of blocks in this UPDATE command */
+        UINT8_TO_STREAM (p, cur_blocks_to_read);     /* Number of blocks to check in this command */
+
+        for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++)
+        {
+            if (block_id<256)
+            {
+                /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
+                UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);    /* byte1: len=0; access-mode=0; service code list order=0 */
+                UINT8_TO_STREAM (p, block_id);                                   /* byte1: block number */
+            }
+            else
+            {
+                /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
+                UINT8_TO_STREAM (p, 0x00);           /* byte0: len=1; access-mode=0; service code list order=0 */
+                UINT16_TO_STREAM (p, block_id);      /* byte1-2: block number in little-endian format */
+            }
+
+        }
+
+        /* Calculate length of message */
+        p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+        /* Send the T3T message */
+        retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) cur_blocks_to_read);
+    }
+    else
+    {
+        retval = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return(retval);
+}
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_message_set_block_list
+**
+** Description      Add block list to T3T message
+**
+** Returns          Number of bytes added to message
+**
+*****************************************************************************/
+void rw_t3t_message_set_block_list (tRW_T3T_CB *p_cb, UINT8 **p, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
+{
+    UINT16 i, cur_service_code;
+    UINT8 service_code_idx, num_services = 0;
+    UINT8 *p_msg_num_services;
+    UINT16 service_list[T3T_MSG_SERVICE_LIST_MAX];
+
+    /* Add CHECK or UPDATE opcode to message  */
+    UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD));
+
+    /* Add IDm to message */
+    ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+    /* Skip over Number of Services field */
+    p_msg_num_services = (*p);      /* pointer to Number of Services offset */
+    (*p)++;
+
+    /* Count number of different services are specified in the list, and add services to Service Code list */
+    for (i = 0; i < num_blocks; i++)
+    {
+        cur_service_code = p_t3t_blocks[i].service_code;
+
+        /* Check if current service_code is already in the service_list */
+        for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
+        {
+            if (service_list[service_code_idx] == cur_service_code)
+                break;
+        }
+
+        if (service_code_idx == num_services)
+        {
+            /* Service not in the list yet. Add it. */
+            service_list[service_code_idx] = cur_service_code;
+            num_services++;
+
+            /* Add service code to T3T message */
+            UINT16_TO_STREAM ((*p), cur_service_code);
+        }
+    }
+
+    /* Add 'Number of Sservices' to the message */
+    *p_msg_num_services = num_services;
+
+    /* Add 'number of blocks' to the message */
+    UINT8_TO_STREAM ((*p), num_blocks);
+
+    /* Add block descriptors */
+    for (i = 0; i < num_blocks; i++)
+    {
+        cur_service_code = p_t3t_blocks[i].service_code;
+
+        /* Check if current service_code is already in the service_list */
+        for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
+        {
+            if (service_list[service_code_idx] == cur_service_code)
+                break;
+        }
+
+        /* Add decriptor to T3T message */
+        if (p_t3t_blocks[i].block_number > 0xFF)
+        {
+            UINT8_TO_STREAM ((*p), service_code_idx);
+            UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
+        }
+        else
+        {
+            service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
+            UINT8_TO_STREAM ((*p), service_code_idx);
+            UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
+        }
+    }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_check_cmd
+**
+** Description      Send CHECK command
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_check_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
+{
+    BT_HDR *p_cmd_buf;
+    UINT8 *p, *p_cmd_start;
+    tNFC_STATUS retval = NFC_STATUS_OK;
+
+    p_cb->cur_cmd = RW_T3T_CMD_CHECK;
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        /* Construct T3T message */
+        p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+        rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
+
+        /* Calculate length of message */
+        p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+        /* Send the T3T message */
+        retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks);
+    }
+    else
+    {
+        retval = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return(retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_update_cmd
+**
+** Description      Send UPDATE command
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_update_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks, UINT8 *p_data)
+{
+    BT_HDR *p_cmd_buf;
+    UINT8 *p, *p_cmd_start;
+    tNFC_STATUS retval = NFC_STATUS_OK;
+
+    p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        /* Construct T3T message */
+        p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+        rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
+
+        /* Add data blocks to the message */
+        ARRAY_TO_STREAM (p, p_data, num_blocks*16);
+
+        /* Calculate length of message */
+        p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+        /* Send the T3T message */
+        retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks);
+    }
+    else
+    {
+        retval = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return(retval);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_send_raw_frame
+**
+** Description      Send raw frame
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_send_raw_frame (tRW_T3T_CB *p_cb, UINT16 len, UINT8 *p_data)
+{
+    BT_HDR *p_cmd_buf;
+    UINT8 *p;
+    tNFC_STATUS retval = NFC_STATUS_OK;
+
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        /* Construct T3T message */
+        p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+        /* Add data blocks to the message */
+        ARRAY_TO_STREAM (p, p_data, len);
+
+        /* Calculate length of message */
+        p_cmd_buf->len = len;
+
+        /* Send the T3T message */
+        retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
+    }
+    else
+    {
+        retval = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return (retval);
+}
+
+
+/*****************************************************************************
+**  TAG RESPONSE HANDLERS
+*****************************************************************************/
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_ndef_detect_rsp
+**
+** Description      Handle response to NDEF detection
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    UINT8 *p;
+    UINT32 temp;
+    UINT8 i;
+    UINT16 checksum_calc, checksum_rx;
+    tRW_DETECT_NDEF_DATA evt_data;
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+
+    evt_data.status = NFC_STATUS_FAILED;
+    evt_data.flags  = RW_NDEF_FL_UNKNOWN;
+
+    /* Check if response code is CHECK resp (for reading NDEF attribute block) */
+    if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+    {
+        RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+    /* Validate status code and NFCID2 response from tag */
+    else if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                          /* verify response status code */
+             ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+    else
+    {
+        /* Get checksum from received ndef attribute msg */
+        p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE];
+        BE_STREAM_TO_UINT16 (checksum_rx, p);
+
+        /* Calculate checksum - move check for checsum to beginning */
+        checksum_calc = 0;
+        p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
+        for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
+        {
+            checksum_calc+=p[i];
+        }
+
+        /* Validate checksum */
+        if (checksum_calc != checksum_rx)
+        {
+            p_cb->ndef_attrib.status = NFC_STATUS_FAILED;       /* only ok or failed passed to the app. can be boolean*/
+
+            RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed");
+        }
+        else
+        {
+            p_cb->ndef_attrib.status = NFC_STATUS_OK;
+
+            /* Validate version number */
+            STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p);
+
+            if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version))
+            {
+                /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */
+                RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
+                p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
+                evt_data.status = NFC_STATUS_BAD_RESP;
+            }
+            else
+            {
+                /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */
+
+                /* Update NDEF info */
+                STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p);              /* NBr: number of blocks that can be read using one Check command */
+                STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p);              /* Nbw: number of blocks that can be written using one Update command */
+                BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p);        /* Nmaxb: maximum number of blocks available for NDEF data */
+                BE_STREAM_TO_UINT32 (temp, p);
+                STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p);           /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
+                STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p);           /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
+
+                /* Get length (3-byte, big-endian) */
+                STREAM_TO_UINT8 (temp, p);                               /* Ln: high-byte */
+                BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p);           /* Ln: lo-word */
+                p_cb->ndef_attrib.ln += (temp << 16);
+
+
+                RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
+                RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i",
+                    p_cb->ndef_attrib.nbr,
+                    p_cb->ndef_attrib.nbw,
+                    p_cb->ndef_attrib.nmaxb,
+                    p_cb->ndef_attrib.writef,
+                    p_cb->ndef_attrib.rwflag,
+                    p_cb->ndef_attrib.ln);
+
+                /* Set data for RW_T3T_NDEF_DETECT_EVT */
+                evt_data.status = p_cb->ndef_attrib.status;
+                evt_data.cur_size = p_cb->ndef_attrib.ln;
+                evt_data.max_size = (UINT32) p_cb->ndef_attrib.nmaxb * 16;
+                evt_data.protocol = NFC_PROTOCOL_T3T;
+                evt_data.flags    = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
+                if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
+                    evt_data.flags    |= RW_NDEF_FL_READ_ONLY;
+            }
+        }
+    }
+
+    RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status);
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+    /* Notify app of NDEF detection result */
+    (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data);
+
+    GKI_freebuf (p_msg_rsp);
+}
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_check_rsp
+**
+** Description      Handle response to CHECK command
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+    tRW_READ_DATA evt_data;
+    tNFC_STATUS nfc_status = NFC_STATUS_OK;
+
+    /* Validate response from tag */
+    if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
+        ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
+    {
+        nfc_status = NFC_STATUS_FAILED;
+        GKI_freebuf (p_msg_rsp);
+    }
+    else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+    {
+        RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+        nfc_status = NFC_STATUS_FAILED;
+        GKI_freebuf (p_msg_rsp);
+    }
+    else
+    {
+        /* Copy incoming data into buffer */
+        p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA;     /* Skip over t3t header */
+        p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
+        evt_data.status = NFC_STATUS_OK;
+        evt_data.p_data = p_msg_rsp;
+        (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data);
+    }
+
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+    (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_update_rsp
+**
+** Description      Handle response to UPDATE command
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+    tRW_READ_DATA evt_data;
+
+    /* Validate response from tag */
+    if (   (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                          /* verify response status code */
+        ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+    else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+    {
+        RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+    else
+    {
+        /* Copy incoming data into buffer */
+        evt_data.status = NFC_STATUS_OK;
+    }
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+    (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data);
+
+    GKI_freebuf (p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_raw_senddata_rsp
+**
+** Description      Handle response to NDEF detection
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_raw_senddata_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    tRW_READ_DATA evt_data;
+
+    /* Copy incoming data into buffer */
+    evt_data.status = NFC_STATUS_OK;
+    evt_data.p_data = p_msg_rsp;
+
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+
+    (*(rw_cb.p_cback)) (RW_T3T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_check_ndef_rsp
+**
+** Description      Handle response to NDEF read segment
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    BOOLEAN check_complete = TRUE;
+    tNFC_STATUS nfc_status = NFC_STATUS_OK;
+    tRW_READ_DATA read_data;
+    tRW_DATA evt_data;
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+    UINT8 rsp_num_bytes_rx;
+
+    /* Validate response from tag */
+    if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                      /* verify response status code */
+        ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */
+        ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4))  )     /* verify length of response */
+    {
+        RW_TRACE_ERROR2 ("Response error: bad status, nfcid2, or invalid len: %i %i", p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS], ((p_cb->ndef_rx_readlen+15)>>4));
+        nfc_status = NFC_STATUS_FAILED;
+        GKI_freebuf (p_msg_rsp);
+    }
+    else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+    {
+        RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+        nfc_status = NFC_STATUS_FAILED;
+        GKI_freebuf (p_msg_rsp);
+    }
+    else
+    {
+        /* Notify app of NDEF segment received */
+        rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16;    /* Number of bytes received, according to header */
+        p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
+        read_data.status = NFC_STATUS_OK;
+        p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA;     /* Skip over t3t header (point to block data) */
+        p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
+
+        /* Verify that the bytes received is really the amount indicated in the check-response header */
+        if (rsp_num_bytes_rx > p_msg_rsp->len)
+        {
+            RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len);
+            nfc_status = NFC_STATUS_FAILED;
+            GKI_freebuf (p_msg_rsp);
+        }
+        else
+        {
+            /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */
+            if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F))
+            {
+                rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
+            }
+
+            p_msg_rsp->len = rsp_num_bytes_rx;
+            read_data.p_data = p_msg_rsp;
+            (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data);
+
+            /* Send CHECK cmd for next NDEF segment, if needed */
+            if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT))
+            {
+                if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK)
+                {
+                    /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */
+                    check_complete = FALSE;
+                }
+            }
+        }
+    }
+
+    /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */
+    if (check_complete)
+    {
+        p_cb->rw_state = RW_T3T_STATE_IDLE;
+        evt_data.status = nfc_status;
+        (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data);
+    }
+}
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_update_ndef_rsp
+**
+** Description      Handle response to NDEF write segment
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    BOOLEAN update_complete = TRUE;
+    tNFC_STATUS nfc_status = NFC_STATUS_OK;
+    tRW_DATA evt_data;
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+
+    /* Check nfcid2 and status of response */
+    if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
+        ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
+    {
+        nfc_status = NFC_STATUS_FAILED;
+    }
+    /* Validate response opcode */
+    else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+    {
+        RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+        nfc_status = NFC_STATUS_FAILED;
+    }
+    /* If this is response to final UPDATE, then update NDEF local size */
+    else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)
+    {
+        /* If successful, update current NDEF size */
+        p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
+    }
+    /*  If any more NDEF bytes to update, then send next UPDATE command */
+    else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len)
+    {
+        /* Send UPDATE command for next segment of NDEF */
+        if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK)
+        {
+            /* Wait for update response */
+            update_complete = FALSE;
+        }
+    }
+    /*  Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */
+    else
+    {
+        p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+        if ((nfc_status = rw_t3t_send_update_ndef_attribute_cmd (p_cb, FALSE)) == NFC_STATUS_OK)
+        {
+            /* Wait for update response */
+            update_complete = FALSE;
+        }
+    }
+
+    /* If update is completed, then notify app */
+    if (update_complete)
+    {
+        p_cb->rw_state = RW_T3T_STATE_IDLE;
+        evt_data.status = nfc_status;
+        (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data);
+    }
+
+
+    GKI_freebuf (p_msg_rsp);
+
+    return;
+}
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_get_sc_poll_rsp
+**
+** Description      Handle POLL response for getting system codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+    BT_HDR *p_cmd_buf;
+    UINT8 *p, *p_cmd_start;
+    UINT16 sc;
+    tNFC_STATUS status = NFC_STATUS_FAILED;
+
+    /* If waiting for wildcard POLL */
+    if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_WILDCARD)
+    {
+        /* Get the system code from the response */
+        if (  (nci_status == NCI_STATUS_OK)
+            &&(num_responses > 0)
+            &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))  )
+        {
+            p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
+            BE_STREAM_TO_UINT16 (sc, p);
+
+            /* Handle felica lite */
+            if (sc == T3T_SYSTEM_CODE_FELICA_LITE)
+            {
+                RW_TRACE_DEBUG1 ("FeliCa Lite tag detected (system code %04X)", sc);
+                /* Store system code */
+                p_cb->system_codes[p_cb->num_system_codes++] = sc;
+
+                /* Poll for NDEF system code */
+                if ((status = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+                {
+                    p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_NDEF;
+                    p_cb->cur_poll_rc = 0;
+                    p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
+
+                    /* start timer for waiting for responses */
+                    rw_t3t_start_poll_timer (p_cb);
+                }
+            }
+            else
+            {
+                /* All other types, send REQUEST_SYSTEM_CODE command */
+                if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+                {
+                    p_cb->rw_substate = RW_T3T_GET_SC_SST_REQUEST_SC;
+
+                    /* Construct T3T message */
+                    p_cmd_start = p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+                    UINT8_TO_STREAM (p, T3T_MSG_OPC_REQ_SYSTEMCODE_CMD);
+                    ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+                    /* Fill in length field */
+                    p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+                    /* Send the T3T message */
+                    status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_GET_SYSTEM_CODES, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+                }
+            }
+        }
+
+        /* Error proceeding. Notify upper layer of system codes found so far */
+        if (status != NFC_STATUS_OK)
+        {
+            rw_t3t_handle_get_system_codes_cplt ();
+        }
+    }
+    /* If waiting for NDEF POLL */
+    else if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_NDEF)
+    {
+        /* Validate response for NDEF poll */
+        if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
+        {
+            /* Tag responded for NDEF poll */
+            p_cb->system_codes[p_cb->num_system_codes++] = T3T_SYSTEM_CODE_NDEF;
+        }
+        rw_t3t_handle_get_system_codes_cplt ();
+    }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_ndef_detect_poll_rsp
+**
+** Description      Handle POLL response for getting system codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+    BT_HDR *p_cmd_buf;
+    UINT8 *p, *p_cmd_start;
+    tRW_DATA evt_data;
+
+    /* Validate response for NDEF poll */
+    if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
+    {
+        /* Tag responded for NDEF poll */
+
+        /* Read NDEF attribute block */
+        if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+        {
+            /* Construct T3T message */
+            p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+            /* Add CHECK opcode to message  */
+            UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
+
+            /* Add IDm to message */
+            ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+            /* Add Service code list */
+            UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
+            UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);     /* Service code (little-endian format) */
+
+            /* Number of blocks */
+            UINT8_TO_STREAM (p, 1);                       /* Number of blocks (only 1 block: NDEF Attribute Information ) */
+
+            /* Block List element: the NDEF attribute information block (block 0) */
+            UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+            UINT8_TO_STREAM (p, 0);
+
+            /* Calculate length of message */
+            p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+            /* Send the T3T message */
+            if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS)) == NFC_STATUS_OK)
+            {
+                /* CHECK command sent. Wait for response */
+                return;
+            }
+        }
+        nci_status = NFC_STATUS_FAILED;
+    }
+
+    /* NDEF detection failed */
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    evt_data.ndef.status = nci_status;
+    evt_data.ndef.flags  = RW_NDEF_FL_UNKNOWN;
+    (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, &evt_data);
+}
+
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_get_sc_rsp
+**
+** Description      Handle response for getting system codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_get_sc_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+    UINT8 *p;
+    UINT16 sc;
+    UINT8 num_sc, i;
+
+    /* Validate response opcode */
+    if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_REQ_SYSTEMCODE_RSP)
+    {
+        RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_REQ_SYSTEMCODE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+    }
+    else
+    {
+        /* Point to number of systems parameter */
+        p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMSYS];
+        STREAM_TO_UINT8 (num_sc, p);
+
+        /* Validate maximum */
+        if (num_sc>T3T_MAX_SYSTEM_CODES)
+        {
+            RW_TRACE_DEBUG2 ("Tag's number of systems (%i) exceeds NFA max (%i)", num_sc, T3T_MAX_SYSTEM_CODES);
+            num_sc = T3T_MAX_SYSTEM_CODES;
+        }
+
+        for (i = 0; i < num_sc; i++)
+        {
+            BE_STREAM_TO_UINT16 (sc, p);
+            p_cb->system_codes[p_cb->num_system_codes++] = sc;
+        }
+    }
+    rw_t3t_handle_get_system_codes_cplt ();
+
+    GKI_freebuf (p_msg_rsp);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_update_block
+**
+** Description      Send UPDATE command for single block (for formatting)
+**
+** Returns          tNFC_STATUS
+**
+*****************************************************************************/
+tNFC_STATUS rw_t3t_update_block (tRW_T3T_CB *p_cb, UINT8 block_id, UINT8 *p_block_data)
+{
+    UINT8 *p_dst, *p_cmd_start;
+    BT_HDR *p_cmd_buf;
+    tNFC_STATUS status;
+
+    if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+    {
+        p_dst = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+        /* Add UPDATE opcode to message  */
+        UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD);
+
+        /* Add IDm to message */
+        ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+        /* Add Service code list */
+        UINT8_TO_STREAM (p_dst, 1);                      /* Number of services (only 1 service: NDEF) */
+        UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW);    /* Service code (little-endian format) */
+
+        /* Number of blocks */
+        UINT8_TO_STREAM (p_dst, 1);
+
+        /* Add Block list element for MC */
+        UINT8_TO_STREAM (p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+        UINT8_TO_STREAM (p_dst, block_id);
+
+        /* Copy MC data to UPDATE message */
+        ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
+
+        /* Calculate length of message */
+        p_cmd_buf->len = (UINT16) (p_dst - p_cmd_start);
+
+        /* Send the T3T message */
+        status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_FORMAT, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+    }
+    else
+    {
+        /* Unable to send UPDATE command */
+        status = NFC_STATUS_NO_BUFFERS;
+    }
+
+    return (status);
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_handle_fmt_poll_rsp
+**
+** Description      Handle POLL response for formatting felica-lite
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
+{
+    BT_HDR *p_cmd_buf;
+    UINT8 *p, *p_cmd_start;
+    tRW_DATA evt_data;
+
+    evt_data.status = NFC_STATUS_OK;
+
+    /* Validate response for poll response */
+    if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
+    {
+        /* Tag responded for Felica-Lite poll */
+        /* Get MemoryControl block */
+        RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
+
+        /* Read NDEF attribute block */
+        if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
+        {
+            p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
+
+            /* Construct T3T message */
+            p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
+
+            /* Add CHECK opcode to message  */
+            UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
+
+            /* Add IDm to message */
+            ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
+
+            /* Add Service code list */
+            UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
+            UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);     /* Service code (little-endian format) */
+
+            /* Number of blocks */
+            UINT8_TO_STREAM (p, 1);                       /* Number of blocks (only 1 block: NDEF Attribute Information ) */
+
+            /* Block List element: the NDEF attribute information block (block 0) */
+            UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
+            UINT8_TO_STREAM (p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
+
+            /* Calculate length of message */
+            p_cmd_buf->len = (UINT16) (p - p_cmd_start);
+
+            /* Send the T3T message */
+            evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_FORMAT, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+        }
+        else
+        {
+            RW_TRACE_ERROR0 ("Unable to allocate buffer to read MC block");
+            evt_data.status = NFC_STATUS_NO_BUFFERS;
+        }
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
+        evt_data.status = NFC_STATUS_FAILED;
+    }
+
+    /* If error, notify upper layer */
+    if (evt_data.status != NFC_STATUS_OK)
+    {
+        rw_t3t_format_cplt (evt_data.status);
+    }
+}
+
+/*****************************************************************************
+**
+** Function         rw_t3t_act_handle_fmt_rsp
+**
+** Description      Handle response for formatting codes
+**
+** Returns          Nothing
+**
+*****************************************************************************/
+void rw_t3t_act_handle_fmt_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
+{
+    UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
+    UINT8 *p_mc;
+    tRW_DATA evt_data;
+
+    evt_data.status = NFC_STATUS_OK;
+
+    /* Check tags's response for reading MemoryControl block */
+    if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK)
+    {
+        /* Validate response opcode */
+        if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
+        {
+            RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
+            evt_data.status = NFC_STATUS_FAILED;
+        }
+        /* Validate status code and NFCID2 response from tag */
+        else if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
+                 ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
+        {
+            evt_data.status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
+            p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];  /* Point to MC data of CHECK response */
+
+            if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
+            {
+                /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */
+
+                /* Set SYS_OP field to 0x01 (enable NDEF) */
+                p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
+
+                /* Construct and send UPDATE message to write MC block */
+                p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
+                evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
+            }
+            else
+            {
+                /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
+                p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
+                evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
+            }
+        }
+
+        /* If error, notify upper layer */
+        if (evt_data.status != NFC_STATUS_OK)
+        {
+            rw_t3t_format_cplt (evt_data.status);
+        }
+    }
+    else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK)
+    {
+        /* Validate response opcode */
+        if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+            ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)  )
+
+        {
+            RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+            evt_data.status = NFC_STATUS_FAILED;
+        }
+        else
+        {
+            /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
+            p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
+            evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
+        }
+
+        /* If error, notify upper layer */
+        if (evt_data.status != NFC_STATUS_OK)
+        {
+            rw_t3t_format_cplt (evt_data.status);
+        }
+    }
+    else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB)
+    {
+        /* Validate response opcode */
+        if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
+            ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)  )
+
+        {
+            RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
+            evt_data.status = NFC_STATUS_FAILED;
+        }
+
+
+        rw_t3t_format_cplt (evt_data.status);
+    }
+
+    GKI_freebuf (p_msg_rsp);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t3t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_data_cback (UINT8 conn_id, BT_HDR *p_msg)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    BOOLEAN free_msg = FALSE;           /* if TRUE, free msg buffer before returning */
+    UINT8 *p, sod;
+
+    /* Stop rsponse timer */
+    nfc_stop_quick_timer (&p_cb->timer);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Update rx stats */
+    rw_main_update_rx_stats (p_msg->len);
+#endif  /* RW_STATS_INCLUDED */
+
+    /* Check if we are expecting a response */
+    if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING)
+    {
+        /*
+        **  This must be raw frame response
+        **  send raw frame to app with SoD
+        */
+        rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_msg);
+    }
+    /* Sanity check: verify msg len is big enough to contain t3t header */
+    else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN)
+    {
+        RW_TRACE_ERROR1 ("T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
+        free_msg = TRUE;
+
+        rw_t3t_process_frame_error ();
+    }
+    else
+    {
+        /* Check for RF frame error */
+        p = (UINT8 *) (p_msg+1) + p_msg->offset;
+        sod = p[0];
+        if (p[sod] != NCI_STATUS_OK)
+        {
+            RW_TRACE_ERROR1 ("T3T: rf frame error (crc status=%i)", p[sod]);
+            GKI_freebuf (p_msg);
+
+            rw_t3t_process_frame_error ();
+            return;
+        }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+        DispT3TagMessage (p_msg, TRUE);
+#endif
+
+        /* Skip over SoD */
+        p_msg->offset++;
+        p_msg->len--;
+
+        /* Get response code */
+        switch (p_cb->cur_cmd)
+        {
+            case RW_T3T_CMD_DETECT_NDEF:
+                rw_t3t_act_handle_ndef_detect_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_CHECK_NDEF:
+                rw_t3t_act_handle_check_ndef_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_UPDATE_NDEF:
+                rw_t3t_act_handle_update_ndef_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_CHECK:
+                rw_t3t_act_handle_check_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_UPDATE:
+                rw_t3t_act_handle_update_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_SEND_RAW_FRAME:
+                rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_GET_SYSTEM_CODES:
+                rw_t3t_act_handle_get_sc_rsp (p_cb, p_msg);
+                break;
+
+            case RW_T3T_CMD_FORMAT:
+                rw_t3t_act_handle_fmt_rsp (p_cb, p_msg);
+                break;
+
+            default:
+                GKI_freebuf (p_msg);
+                break;
+        }
+    }
+
+    if (free_msg)
+    {
+        GKI_freebuf (p_msg);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t3t_conn_cback
+**
+** Description      This callback function receives the events/data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t3t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
+
+    /* Only handle NFC_RF_CONN_ID conn_id */
+    if (conn_id != NFC_RF_CONN_ID)
+    {
+        return;
+    }
+
+    switch (event)
+    {
+    case NFC_DEACTIVATE_CEVT:
+        rw_t3t_unselect (NULL);
+        break;
+
+    case NFC_DATA_CEVT:     /* check for status in tNFC_CONN */
+        if (p_data->data.status == NFC_STATUS_OK)
+        {
+            rw_t3t_data_cback (conn_id, p_data->data.p_data);
+            break;
+        }
+        /* Data event with error status...fall through to NFC_ERROR_CEVT case */
+
+
+    case NFC_ERROR_CEVT:
+        nfc_stop_quick_timer (&p_cb->timer);
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+        rw_main_update_trans_error_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+        if (event == NFC_ERROR_CEVT)
+            rw_t3t_process_error (NFC_STATUS_TIMEOUT);
+        else
+            rw_t3t_process_error (p_data->status);
+        break;
+
+    default:
+        break;
+
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t3t_select
+**
+** Description      Called by NFC manager when a Type3 tag has been activated
+**
+** Returns          NFC_STATUS_OK
+**
+*******************************************************************************/
+tNFC_STATUS rw_t3t_select (UINT8 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API0 ("rw_t3t_select");
+
+    memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */
+    p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED;  /* Indicate that NDEF detection has not been performed yet */
+    p_cb->rw_state = RW_T3T_STATE_IDLE;
+    p_cb->flags = 0;
+
+    /* Alloc cmd buf for retransmissions */
+    if (p_cb->p_cur_cmd_buf ==  NULL)
+    {
+        if ((p_cb->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
+        {
+            RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission");
+            p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
+            return (NFC_STATUS_FAILED);
+        }
+    }
+
+
+    NFC_SetStaticRfCback (rw_t3t_conn_cback);
+
+    return NFC_STATUS_OK;
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t3t_unselect
+**
+** Description      Called by NFC manager when a Type3 tag has been de-activated
+**
+** Returns          NFC_STATUS_OK
+**
+*******************************************************************************/
+static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[])
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+#if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
+    /* Display stats */
+    rw_main_log_stats ();
+#endif  /* RW_STATS_INCLUDED */
+
+    /* Stop t3t timer (if started) */
+    nfc_stop_quick_timer (&p_cb->timer);
+
+    /* Free cmd buf for retransmissions */
+    if (p_cb->p_cur_cmd_buf)
+    {
+        GKI_freebuf (p_cb->p_cur_cmd_buf);
+        p_cb->p_cur_cmd_buf = NULL;
+    }
+
+    p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
+    NFC_SetStaticRfCback (NULL);
+
+    return NFC_STATUS_OK;
+}
+
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         rw_t3t_cmd_str
+**
+** Description      Converts cmd_id to command string for logging
+**
+** Returns          command string
+**
+*******************************************************************************/
+static char *rw_t3t_cmd_str (UINT8 cmd_id)
+{
+    switch (cmd_id)
+    {
+    case RW_T3T_CMD_DETECT_NDEF:
+        return "RW_T3T_CMD_DETECT_NDEF";
+
+    case RW_T3T_CMD_CHECK_NDEF:
+        return "RW_T3T_CMD_CHECK_NDEF";
+
+    case RW_T3T_CMD_UPDATE_NDEF:
+        return "RW_T3T_CMD_UPDATE_NDEF";
+
+    case RW_T3T_CMD_CHECK:
+        return "RW_T3T_CMD_CHECK";
+
+    case RW_T3T_CMD_UPDATE:
+        return "RW_T3T_CMD_UPDATE";
+
+    case RW_T3T_CMD_SEND_RAW_FRAME:
+        return "RW_T3T_CMD_SEND_RAW_FRAME";
+
+    case RW_T3T_CMD_GET_SYSTEM_CODES:
+        return "RW_T3T_CMD_GET_SYSTEM_CODES";
+
+    default:
+        return "Unknown";
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t3t_state_str
+**
+** Description      Converts state_id to command string for logging
+**
+** Returns          command string
+**
+*******************************************************************************/
+static char *rw_t3t_state_str (UINT8 state_id)
+{
+    switch (state_id)
+    {
+    case RW_T3T_STATE_NOT_ACTIVATED:
+        return "RW_T3T_STATE_NOT_ACTIVATED";
+
+    case RW_T3T_STATE_IDLE:
+        return "RW_T3T_STATE_IDLE";
+
+    case RW_T3T_STATE_COMMAND_PENDING:
+        return "RW_T3T_STATE_COMMAND_PENDING";
+
+    default:
+        return "Unknown";
+    }
+}
+#endif
+
+/*****************************************************************************
+**  Type3 Tag API Functions
+*****************************************************************************/
+
+
+/*****************************************************************************
+**
+** Function         RW_T3tDetectNDef
+**
+** Description
+**      This function is used to perform NDEF detection on a Type 3 tag, and
+**      retrieve the tag's NDEF attribute information (block 0).
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tDetectNDef (void)
+{
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+    tNFC_STATUS retval = NFC_STATUS_OK;
+
+    RW_TRACE_API0 ("RW_T3tDetectNDef");
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+    {
+        p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
+        p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+        p_cb->cur_poll_rc = 0;
+        p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+        p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
+
+        /* start timer for waiting for responses */
+        rw_t3t_start_poll_timer (p_cb);
+    }
+
+    return (retval);
+}
+
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheckNDef
+**
+** Description
+**      Retrieve NDEF contents from a Type3 tag.
+**
+**      The RW_T3T_CHECK_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to
+**      notify the application all segments have been received.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Check
+**      commands (if necessary) - depending on the tag's Nbr (max number of
+**      blocks per read) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tCheckNDef (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API0 ("RW_T3tCheckNDef");
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+    else if (p_cb->ndef_attrib.status != NFC_STATUS_OK)       /* NDEF detection not performed yet? */
+    {
+        RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
+        return (NFC_STATUS_NOT_INITIALIZED);
+    }
+    else if (p_cb->ndef_attrib.ln == 0)
+    {
+        RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message");
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Check number of blocks needed for this update */
+    p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+    p_cb->ndef_rx_offset = 0;
+    retval = rw_t3t_send_next_ndef_check_cmd (p_cb);
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdateNDef
+**
+** Description
+**      Write NDEF contents to a Type3 tag.
+**
+**      The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
+**      application of the response.
+**
+**      Before using this API, the RW_T3tDetectNDef function must be called to
+**      verify that the tag contains NDEF data, and to retrieve the NDEF
+**      attributes.
+**
+**      Internally, this command will be separated into multiple Tag 3 Update
+**      commands (if necessary) - depending on the tag's Nbw (max number of
+**      blocks per write) attribute.
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_REFUSED: tag is read-only
+**      NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len);
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+    else if (p_cb->ndef_attrib.status != NFC_STATUS_OK)       /* NDEF detection not performed yet? */
+    {
+        RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
+        return (NFC_STATUS_NOT_INITIALIZED);
+    }
+    else if (len > (((UINT32)p_cb->ndef_attrib.nmaxb) * 16))                /* Len exceed's tag's NDEF memory? */
+    {
+        return (NFC_STATUS_BUFFER_FULL);
+    }
+    else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */
+    {
+        return (NFC_STATUS_REFUSED);
+    }
+
+    /* Check number of blocks needed for this update */
+    p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
+    p_cb->ndef_msg_bytes_sent = 0;
+    p_cb->ndef_msg_len = len;
+    p_cb->ndef_msg = p_data;
+
+    /* Send initial UPDATE command for NDEF Attribute Info */
+    retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, TRUE);
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tCheck
+**
+** Description
+**      Read (non-NDEF) contents from a Type3 tag.
+**
+**      The RW_READ_EVT event is used to notify the application for each
+**      segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
+**      notify the application all segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the
+**      tag's Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks);
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Send the CHECK command */
+    retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks);
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tUpdate
+**
+** Description
+**      Write (non-NDEF) contents to a Type3 tag.
+**
+**      The RW_WRITE_CPLT_EVT event is used to notify the application all
+**      segments have been received.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated, and to provide the tag's
+**      Manufacture ID (IDm) .
+**
+** Returns
+**      NFC_STATUS_OK: check command started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks);
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Send the UPDATE command */
+    retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data);
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tPresenceCheck (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_DATA evt_data;
+    tRW_CB *p_rw_cb = &rw_cb;
+
+    RW_TRACE_API0 ("RW_T3tPresenceCheck");
+
+    /* If RW_SelectTagType was not called (no conn_callback) return failure */
+    if (!(p_rw_cb->p_cback))
+    {
+        retval = NFC_STATUS_FAILED;
+    }
+    /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
+    else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED)
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+        (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    /* If command is pending */
+    else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING)
+    {
+        /* If already performing presence check, return error */
+        if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
+        {
+            RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress");
+            retval = NFC_STATUS_FAILED;
+        }
+        /* If busy with any other command, assume that the tag is present */
+        else
+        {
+            evt_data.status = NFC_STATUS_OK;
+            (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+        }
+    }
+    else
+    {
+        /* IDLE state: send POLL command */
+        if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+        {
+            p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
+            p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
+            p_rw_cb->tcb.t3t.cur_poll_rc = 0;
+
+            /* start timer for waiting for responses */
+            rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t);
+        }
+        else
+        {
+            RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval);
+        }
+    }
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tPoll
+**
+** Description
+**      Send POLL command
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API0 ("RW_T3tPoll");
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (system_code, (UINT8) rc, tsn)) == NCI_STATUS_OK)
+    {
+        /* start timer for waiting for responses */
+        p_cb->cur_poll_rc = rc;
+        p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+        rw_t3t_start_poll_timer (p_cb);
+    }
+
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tSendRawFrame
+**
+** Description
+**      This function is called to send a raw data frame to the peer device.
+**      When type 3 tag receives response from peer, the callback function
+**      will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+**      The raw frame should be a properly formatted Type 3 tag message.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len);
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+
+    /* Send the UPDATE command */
+    retval = rw_t3t_send_raw_frame (p_cb, len ,p_data);
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tGetSystemCodes
+**
+** Description
+**      Get systems codes supported by the activated tag:
+**              Poll for wildcard (FFFF):
+**                  - If felica-lite code then poll for ndef (12fc)
+**                  - Otherwise send RequestSystmCode command to get
+**                    system codes.
+**
+**      Before using this API, the application must call RW_SelectTagType to
+**      indicate that a Type 3 tag has been activated.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tGetSystemCodes (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API0 ("RW_T3tGetSystemCodes");
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+    else
+    {
+        if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+        {
+            p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
+            p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+            p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+            p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+            p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_WILDCARD;
+            p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
+            p_cb->num_system_codes = 0;
+
+            /* start timer for waiting for responses */
+            rw_t3t_start_poll_timer (p_cb);
+        }
+    }
+
+
+
+    return (retval);
+}
+
+/*****************************************************************************
+**
+** Function         RW_T3tFormatNDef
+**
+** Description
+**      Format a type-3 tag for NDEF.
+**
+**      Only Felica-Lite tags are supported by this API. The
+**      RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
+**
+** Returns
+**      NFC_STATUS_OK: ndef detection procedure started
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T3tFormatNDef (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+
+    RW_TRACE_API0 ("RW_T3tFormatNDef");
+
+    /* Check if we are in valid state to handle this API */
+    if (p_cb->rw_state != RW_T3T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
+        return (NFC_STATUS_FAILED);
+    }
+    else
+    {
+        /* Poll tag, to see if Felica-Lite system is supported */
+        if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
+        {
+            p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
+            p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
+            p_cb->cur_poll_rc = T3T_POLL_RC_SC;
+            p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+            p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
+            p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
+
+            /* start timer for waiting for responses */
+            rw_t3t_start_poll_timer (p_cb);
+        }
+    }
+
+
+
+    return (retval);
+}
diff --git a/src/nfc/tags/rw_t4t.c b/src/nfc/tags/rw_t4t.c
new file mode 100644
index 0000000..7b61339
--- /dev/null
+++ b/src/nfc/tags/rw_t4t.c
@@ -0,0 +1,1437 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the implementation for Type 4 tag in Reader/Writer
+ *  mode.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_target.h"
+#include "bt_types.h"
+#include "trace_api.h"
+
+#if (NFC_INCLUDED == TRUE)
+
+#include "nfc_api.h"
+#include "nfc_int.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+#include "gki.h"
+
+/* main state */
+#define RW_T4T_STATE_NOT_ACTIVATED              0x00    /* T4T is not activated                 */
+#define RW_T4T_STATE_IDLE                       0x01    /* waiting for upper layer API          */
+#define RW_T4T_STATE_DETECT_NDEF                0x02    /* performing NDEF detection precedure  */
+#define RW_T4T_STATE_READ_NDEF                  0x03    /* performing read NDEF procedure       */
+#define RW_T4T_STATE_UPDATE_NDEF                0x04    /* performing update NDEF procedure     */
+#define RW_T4T_STATE_PRESENCE_CHECK             0x05    /* checking presence of tag             */
+
+/* sub state */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_APP         0x00    /* waiting for response of selecting AID    */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_CC          0x01    /* waiting for response of selecting CC     */
+#define RW_T4T_SUBSTATE_WAIT_CC_FILE            0x02    /* waiting for response of reading CC       */
+#define RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE   0x03    /* waiting for response of selecting NDEF   */
+#define RW_T4T_SUBSTATE_WAIT_READ_NLEN          0x04    /* waiting for response of reading NLEN     */
+#define RW_T4T_SUBSTATE_WAIT_READ_RESP          0x05    /* waiting for response of reading file     */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_RESP        0x06    /* waiting for response of updating file    */
+#define RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN        0x07    /* waiting for response of updating NLEN    */
+
+#if (BT_TRACE_VERBOSE == TRUE)
+static char *rw_t4t_get_state_name (UINT8 state);
+static char *rw_t4t_get_sub_state_name (UINT8 sub_state);
+#endif
+
+static BOOLEAN rw_t4t_send_to_lower (BT_HDR *p_c_apdu);
+static BOOLEAN rw_t4t_select_file (UINT16 file_id);
+static BOOLEAN rw_t4t_read_file (UINT16 offset, UINT16 length, BOOLEAN is_continue);
+static BOOLEAN rw_t4t_update_nlen (UINT16 ndef_len);
+static BOOLEAN rw_t4t_update_file (void);
+static BOOLEAN rw_t4t_select_application (UINT8 version);
+static BOOLEAN rw_t4t_validate_cc_file (void);
+static void rw_t4t_handle_error (tNFC_STATUS status, UINT8 sw1, UINT8 sw2);
+static void rw_t4t_sm_detect_ndef (BT_HDR *p_r_apdu);
+static void rw_t4t_sm_read_ndef (BT_HDR *p_r_apdu);
+static void rw_t4t_sm_update_ndef (BT_HDR  *p_r_apdu);
+static void rw_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data);
+
+/*******************************************************************************
+**
+** Function         rw_t4t_send_to_lower
+**
+** Description      Send C-APDU to lower layer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_send_to_lower (BT_HDR *p_c_apdu)
+{
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispRWT4Tags (p_c_apdu, FALSE);
+#endif
+
+    if (NFC_SendData (NFC_RF_CONN_ID, p_c_apdu) != NFC_STATUS_OK)
+    {
+        RW_TRACE_ERROR0 ("rw_t4t_send_to_lower (): NFC_SendData () failed");
+        return FALSE;
+    }
+
+    nfc_start_quick_timer (&rw_cb.tcb.t4t.timer, NFC_TTYPE_RW_T4T_RESPONSE,
+                           (RW_T4T_TOUT_RESP * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_select_file
+**
+** Description      Send Select Command (by File ID) to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_select_file (UINT16 file_id)
+{
+    BT_HDR      *p_c_apdu;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG1 ("rw_t4t_select_file (): File ID:0x%04X", file_id);
+
+    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_c_apdu)
+    {
+        RW_TRACE_ERROR0 ("rw_t4t_select_file (): Cannot allocate buffer");
+        return FALSE;
+    }
+
+    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_FILE_ID);
+
+    /* if current version mapping is V2.0 */
+    if (rw_cb.tcb.t4t.version == T4T_VERSION_2_0)
+    {
+        UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_0CH);
+    }
+    else /* version 1.0 */
+    {
+        UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
+    }
+
+    UINT8_TO_BE_STREAM (p, T4T_FILE_ID_SIZE);
+    UINT16_TO_BE_STREAM (p, file_id);
+
+    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE;
+
+    if (!rw_t4t_send_to_lower (p_c_apdu))
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_read_file
+**
+** Description      Send ReadBinary Command to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_read_file (UINT16 offset, UINT16 length, BOOLEAN is_continue)
+{
+    tRW_T4T_CB      *p_t4t = &rw_cb.tcb.t4t;
+    BT_HDR          *p_c_apdu;
+    UINT8           *p;
+
+    RW_TRACE_DEBUG3 ("rw_t4t_read_file () offset:%d, length:%d, is_continue:%d, ",
+                      offset, length, is_continue);
+
+    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_c_apdu)
+    {
+        RW_TRACE_ERROR0 ("rw_t4t_read_file (): Cannot allocate buffer");
+        return FALSE;
+    }
+
+    /* if this is the first reading */
+    if (is_continue == FALSE)
+    {
+        /* initialise starting offset and total length */
+        /* these will be updated when receiving response */
+        p_t4t->rw_offset = offset;
+        p_t4t->rw_length = length;
+    }
+
+    /* adjust reading length if payload is bigger than max size per single command */
+    if (length > p_t4t->max_read_size)
+    {
+        length = (UINT8) (p_t4t->max_read_size);
+    }
+
+    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_READ_BINARY);
+    UINT16_TO_BE_STREAM (p, offset);
+    UINT8_TO_BE_STREAM (p, length); /* Le */
+
+    p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 1; /* adding Le */
+
+    if (!rw_t4t_send_to_lower (p_c_apdu))
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_update_nlen
+**
+** Description      Send UpdateBinary Command to update NLEN to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_update_nlen (UINT16 ndef_len)
+{
+    BT_HDR          *p_c_apdu;
+    UINT8           *p;
+
+    RW_TRACE_DEBUG1 ("rw_t4t_update_nlen () NLEN:%d", ndef_len);
+
+    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_c_apdu)
+    {
+        RW_TRACE_ERROR0 ("rw_t4t_update_nlen (): Cannot allocate buffer");
+        return FALSE;
+    }
+
+    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY);
+    UINT16_TO_BE_STREAM (p, 0x0000);                    /* offset for NLEN */
+    UINT8_TO_BE_STREAM (p, T4T_FILE_LENGTH_SIZE);
+    UINT16_TO_BE_STREAM (p, ndef_len);
+
+    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_LENGTH_SIZE;
+
+    if (!rw_t4t_send_to_lower (p_c_apdu))
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_update_file
+**
+** Description      Send UpdateBinary Command to peer
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_update_file (void)
+{
+    tRW_T4T_CB      *p_t4t = &rw_cb.tcb.t4t;
+    BT_HDR          *p_c_apdu;
+    UINT8           *p;
+    UINT16          length;
+
+    RW_TRACE_DEBUG2 ("rw_t4t_update_file () rw_offset:%d, rw_length:%d",
+                      p_t4t->rw_offset, p_t4t->rw_length);
+
+    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_c_apdu)
+    {
+        RW_TRACE_ERROR0 ("rw_t4t_write_file (): Cannot allocate buffer");
+        return FALSE;
+    }
+
+    /* try to send all of remaining data */
+    length = p_t4t->rw_length;
+
+    /* adjust updating length if payload is bigger than max size per single command */
+    if (length > p_t4t->max_update_size)
+    {
+        length = (UINT8) (p_t4t->max_update_size);
+    }
+
+    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY);
+    UINT16_TO_BE_STREAM (p, p_t4t->rw_offset);
+    UINT8_TO_BE_STREAM (p, length);
+
+    memcpy (p, p_t4t->p_update_data, length);
+
+    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length;
+
+    if (!rw_t4t_send_to_lower (p_c_apdu))
+    {
+        return FALSE;
+    }
+
+    /* adjust offset, length and pointer for remaining data */
+    p_t4t->rw_offset     += length;
+    p_t4t->rw_length     -= length;
+    p_t4t->p_update_data += length;
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_select_application
+**
+** Description      Select Application
+**
+**                  NDEF Tag Application Select - C-APDU
+**
+**                        CLA INS P1 P2 Lc Data(AID)      Le
+**                  V1.0: 00  A4  04 00 07 D2760000850100 -
+**                  V2.0: 00  A4  04 00 07 D2760000850101 00
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_select_application (UINT8 version)
+{
+    BT_HDR      *p_c_apdu;
+    UINT8       *p;
+
+    RW_TRACE_DEBUG1 ("rw_t4t_select_application () version:0x%X", version);
+
+    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);
+
+    if (!p_c_apdu)
+    {
+        RW_TRACE_ERROR0 ("rw_t4t_select_application (): Cannot allocate buffer");
+        return FALSE;
+    }
+
+    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
+    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;
+
+    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_NAME);
+    UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
+
+    if (version == T4T_VERSION_1_0)   /* this is for V1.0 */
+    {
+        UINT8_TO_BE_STREAM (p, T4T_V10_NDEF_TAG_AID_LEN);
+
+        memcpy (p, t4t_v10_ndef_tag_aid, T4T_V10_NDEF_TAG_AID_LEN);
+
+        p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V10_NDEF_TAG_AID_LEN;
+    }
+    else if (version == T4T_VERSION_2_0)   /* this is for V2.0 */
+    {
+        UINT8_TO_BE_STREAM (p, T4T_V20_NDEF_TAG_AID_LEN);
+
+        memcpy (p, t4t_v20_ndef_tag_aid, T4T_V20_NDEF_TAG_AID_LEN);
+        p += T4T_V20_NDEF_TAG_AID_LEN;
+
+        UINT8_TO_BE_STREAM (p, 0x00); /* Le set to 0x00 */
+
+        p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_V20_NDEF_TAG_AID_LEN + 1;
+    }
+    else
+    {
+        return FALSE;
+    }
+
+    if (!rw_t4t_send_to_lower (p_c_apdu))
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_validate_cc_file
+**
+** Description      Validate CC file and mandatory NDEF TLV
+**
+** Returns          TRUE if success
+**
+*******************************************************************************/
+static BOOLEAN rw_t4t_validate_cc_file (void)
+{
+    tRW_T4T_CB  *p_t4t = &rw_cb.tcb.t4t;
+
+    RW_TRACE_DEBUG0 ("rw_t4t_validate_cc_file ()");
+
+    if (p_t4t->cc_file.cclen < T4T_CC_FILE_MIN_LEN)
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): CCLEN (%d) is too short",
+                         p_t4t->cc_file.cclen);
+        return FALSE;
+    }
+
+    if (T4T_GET_MAJOR_VERSION (p_t4t->cc_file.version) != T4T_GET_MAJOR_VERSION (p_t4t->version))
+    {
+        RW_TRACE_ERROR2 ("rw_t4t_validate_cc_file (): Peer version (0x%02X) is matched to ours (0x%02X)",
+                         p_t4t->cc_file.version, p_t4t->version);
+        return FALSE;
+    }
+
+    if (p_t4t->cc_file.max_le < 0x000F)
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): MaxLe (%d) is too small",
+                         p_t4t->cc_file.max_le);
+        return FALSE;
+    }
+
+    if (p_t4t->cc_file.max_lc < 0x0001)
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): MaxLc (%d) is too small",
+                         p_t4t->cc_file.max_lc);
+        return FALSE;
+    }
+
+    if (  (p_t4t->cc_file.ndef_fc.file_id == T4T_CC_FILE_ID)
+        ||(p_t4t->cc_file.ndef_fc.file_id == 0xE102)
+        ||(p_t4t->cc_file.ndef_fc.file_id == 0xE103)
+        ||((p_t4t->cc_file.ndef_fc.file_id == 0x0000) && (p_t4t->cc_file.version == 0x20))
+        ||(p_t4t->cc_file.ndef_fc.file_id == 0x3F00)
+        ||(p_t4t->cc_file.ndef_fc.file_id == 0x3FFF)
+        ||(p_t4t->cc_file.ndef_fc.file_id == 0xFFFF)  )
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): File ID (0x%04X) is invalid",
+                          p_t4t->cc_file.ndef_fc.file_id);
+        return FALSE;
+    }
+
+    if (  (p_t4t->cc_file.ndef_fc.max_file_size < 0x0005)
+        ||(p_t4t->cc_file.ndef_fc.max_file_size == 0xFFFF)  )
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): max_file_size (%d) is reserved",
+                         p_t4t->cc_file.ndef_fc.max_file_size);
+        return FALSE;
+    }
+
+    if (p_t4t->cc_file.ndef_fc.read_access != T4T_FC_READ_ACCESS)
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): Read Access (0x%02X) is invalid",
+                          p_t4t->cc_file.ndef_fc.read_access);
+        return FALSE;
+    }
+
+    if (  (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS)
+        &&(p_t4t->cc_file.ndef_fc.write_access != T4T_FC_NO_WRITE_ACCESS)  )
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_validate_cc_file (): Write Access (0x%02X) is invalid",
+                          p_t4t->cc_file.ndef_fc.write_access);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_handle_error
+**
+** Description      notify error to application and clean up
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_handle_error (tNFC_STATUS status, UINT8 sw1, UINT8 sw2)
+{
+    tRW_T4T_CB  *p_t4t = &rw_cb.tcb.t4t;
+    tRW_DATA    rw_data;
+    tRW_EVENT   event;
+
+    RW_TRACE_DEBUG4 ("rw_t4t_handle_error (): status:0%02X, sw1:0x%02X, sw2:0x%02X, state:0x%X",
+                      status, sw1, sw2, p_t4t->state);
+
+    nfc_stop_quick_timer (&p_t4t->timer);
+
+    if (rw_cb.p_cback)
+    {
+        rw_data.status = status;
+
+        rw_data.t4t_sw.sw1    = sw1;
+        rw_data.t4t_sw.sw2    = sw2;
+
+        switch (p_t4t->state)
+        {
+        case RW_T4T_STATE_DETECT_NDEF:
+            rw_data.ndef.flags  = RW_NDEF_FL_UNKNOWN;
+            event = RW_T4T_NDEF_DETECT_EVT;
+            break;
+
+        case RW_T4T_STATE_READ_NDEF:
+            event = RW_T4T_NDEF_READ_FAIL_EVT;
+            break;
+
+        case RW_T4T_STATE_UPDATE_NDEF:
+            event = RW_T4T_NDEF_UPDATE_FAIL_EVT;
+            break;
+
+        case RW_T4T_STATE_PRESENCE_CHECK:
+            event = RW_T4T_PRESENCE_CHECK_EVT;
+            rw_data.status = NFC_STATUS_FAILED;
+            break;
+
+        default:
+            event = RW_T4T_MAX_EVT;
+            break;
+        }
+
+        p_t4t->state = RW_T4T_STATE_IDLE;
+
+        if (event != RW_T4T_MAX_EVT)
+        {
+            (*(rw_cb.p_cback)) (event, &rw_data);
+        }
+    }
+    else
+    {
+        p_t4t->state = RW_T4T_STATE_IDLE;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_detect_ndef
+**
+** Description      State machine for NDEF detection procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_detect_ndef (BT_HDR *p_r_apdu)
+{
+    tRW_T4T_CB  *p_t4t = &rw_cb.tcb.t4t;
+    UINT8       *p, type, length;
+    UINT16      status_words, nlen;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_t4t_sm_detect_ndef (): sub_state:%s (%d)",
+                      rw_t4t_get_sub_state_name (p_t4t->sub_state), p_t4t->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_t4t_sm_detect_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+    /* get status words */
+    p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+    p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+    BE_STREAM_TO_UINT16 (status_words, p);
+
+    if (status_words != T4T_RSP_CMD_CMPLTED)
+    {
+        /* try V1.0 after failing of V2.0 */
+        if (  (p_t4t->sub_state == RW_T4T_SUBSTATE_WAIT_SELECT_APP)
+            &&(p_t4t->version   == T4T_VERSION_2_0)  )
+        {
+            p_t4t->version = T4T_VERSION_1_0;
+
+            RW_TRACE_DEBUG1 ("rw_t4t_sm_detect_ndef (): retry with version=0x%02X",
+                              p_t4t->version);
+
+            if (!rw_t4t_select_application (T4T_VERSION_1_0))
+            {
+                rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+            }
+            return;
+        }
+
+        p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+        rw_t4t_handle_error (NFC_STATUS_CMD_NOT_CMPLTD, *(p-2), *(p-1));
+        return;
+    }
+
+    switch (p_t4t->sub_state)
+    {
+    case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
+
+        /* NDEF Tag application has been selected then select CC file */
+        if (!rw_t4t_select_file (T4T_CC_FILE_ID))
+        {
+            rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+        }
+        else
+        {
+            p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+        }
+        break;
+
+    case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
+
+        /* CC file has been selected then read mandatory part of CC file */
+        if (!rw_t4t_read_file (0x00, T4T_CC_FILE_MIN_LEN, FALSE))
+        {
+            rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+        }
+        else
+        {
+            p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_CC_FILE;
+        }
+        break;
+
+    case RW_T4T_SUBSTATE_WAIT_CC_FILE:
+
+        /* CC file has been read then validate and select mandatory NDEF file */
+        if (p_r_apdu->len >= T4T_CC_FILE_MIN_LEN + T4T_RSP_STATUS_WORDS_SIZE)
+        {
+            p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+
+            BE_STREAM_TO_UINT16 (p_t4t->cc_file.cclen, p);
+            BE_STREAM_TO_UINT8 (p_t4t->cc_file.version, p);
+            BE_STREAM_TO_UINT16 (p_t4t->cc_file.max_le, p);
+            BE_STREAM_TO_UINT16 (p_t4t->cc_file.max_lc, p);
+
+            BE_STREAM_TO_UINT8 (type, p);
+            BE_STREAM_TO_UINT8 (length, p);
+
+            if (  (type == T4T_NDEF_FILE_CONTROL_TYPE)
+                &&(length == T4T_FILE_CONTROL_LENGTH)  )
+            {
+                BE_STREAM_TO_UINT16 (p_t4t->cc_file.ndef_fc.file_id, p);
+                BE_STREAM_TO_UINT16 (p_t4t->cc_file.ndef_fc.max_file_size, p);
+                BE_STREAM_TO_UINT8 (p_t4t->cc_file.ndef_fc.read_access, p);
+                BE_STREAM_TO_UINT8 (p_t4t->cc_file.ndef_fc.write_access, p);
+
+#if (BT_TRACE_VERBOSE == TRUE)
+                RW_TRACE_DEBUG0 ("Capability Container (CC) file");
+                RW_TRACE_DEBUG1 ("  CCLEN:  0x%04X",    p_t4t->cc_file.cclen);
+                RW_TRACE_DEBUG1 ("  Version:0x%02X",    p_t4t->cc_file.version);
+                RW_TRACE_DEBUG1 ("  MaxLe:  0x%04X",    p_t4t->cc_file.max_le);
+                RW_TRACE_DEBUG1 ("  MaxLc:  0x%04X",    p_t4t->cc_file.max_lc);
+                RW_TRACE_DEBUG0 ("  NDEF File Control TLV");
+                RW_TRACE_DEBUG1 ("    FileID:      0x%04X", p_t4t->cc_file.ndef_fc.file_id);
+                RW_TRACE_DEBUG1 ("    MaxFileSize: 0x%04X", p_t4t->cc_file.ndef_fc.max_file_size);
+                RW_TRACE_DEBUG1 ("    ReadAccess:  0x%02X", p_t4t->cc_file.ndef_fc.read_access);
+                RW_TRACE_DEBUG1 ("    WriteAccess: 0x%02X", p_t4t->cc_file.ndef_fc.write_access);
+#endif
+
+                if (rw_t4t_validate_cc_file ())
+                {
+                    if (!rw_t4t_select_file (p_t4t->cc_file.ndef_fc.file_id))
+                    {
+                        rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+                    }
+                    else
+                    {
+                        p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE;
+                    }
+                    break;
+                }
+            }
+        }
+
+        /* invalid response or CC file */
+        p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+        rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+        break;
+
+    case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
+
+        /* NDEF file has been selected then read the first 2 bytes (NLEN) */
+        if (!rw_t4t_read_file (0, T4T_FILE_LENGTH_SIZE, FALSE))
+        {
+            rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+        }
+        else
+        {
+            p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_READ_NLEN;
+        }
+        break;
+
+    case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
+
+        /* NLEN has been read then report upper layer */
+        if (p_r_apdu->len == T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE)
+        {
+            /* get length of NDEF */
+            p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+            BE_STREAM_TO_UINT16 (nlen, p);
+
+            if (nlen <= p_t4t->cc_file.ndef_fc.max_file_size - T4T_FILE_LENGTH_SIZE)
+            {
+                p_t4t->ndef_status = RW_T4T_NDEF_STATUS_NDEF_DETECTED;
+
+                if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS)
+                {
+                    p_t4t->ndef_status |= RW_T4T_NDEF_STATUS_NDEF_READ_ONLY;
+                }
+
+                /* Get max bytes to read per command */
+                if (p_t4t->cc_file.max_le >= RW_T4T_MAX_DATA_PER_READ)
+                {
+                    p_t4t->max_read_size = RW_T4T_MAX_DATA_PER_READ;
+                }
+                else
+                {
+                    p_t4t->max_read_size = p_t4t->cc_file.max_le;
+                }
+
+                /* Le: valid range is 0x01 to 0xFF */
+                if (p_t4t->max_read_size >= T4T_MAX_LENGTH_LE)
+                {
+                    p_t4t->max_read_size = T4T_MAX_LENGTH_LE;
+                }
+
+                /* Get max bytes to update per command */
+                if (p_t4t->cc_file.max_lc >= RW_T4T_MAX_DATA_PER_WRITE)
+                {
+                    p_t4t->max_update_size = RW_T4T_MAX_DATA_PER_WRITE;
+                }
+                else
+                {
+                    p_t4t->max_update_size = p_t4t->cc_file.max_lc;
+                }
+
+                /* Lc: valid range is 0x01 to 0xFF */
+                if (p_t4t->max_update_size >= T4T_MAX_LENGTH_LC)
+                {
+                    p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
+                }
+
+                p_t4t->ndef_length = nlen;
+                p_t4t->state       = RW_T4T_STATE_IDLE;
+
+                if (rw_cb.p_cback)
+                {
+                    rw_data.ndef.status   = NFC_STATUS_OK;
+                    rw_data.ndef.protocol = NFC_PROTOCOL_ISO_DEP;
+                    rw_data.ndef.max_size = (UINT32) (p_t4t->cc_file.ndef_fc.max_file_size - (UINT16) T4T_FILE_LENGTH_SIZE);
+                    rw_data.ndef.cur_size = nlen;
+                    rw_data.ndef.flags    = RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED;
+                    if (p_t4t->cc_file.ndef_fc.write_access != T4T_FC_WRITE_ACCESS)
+                    {
+                        rw_data.ndef.flags    |= RW_NDEF_FL_READ_ONLY;
+                    }
+
+                    (*(rw_cb.p_cback)) (RW_T4T_NDEF_DETECT_EVT, &rw_data);
+
+                    RW_TRACE_DEBUG0 ("rw_t4t_sm_detect_ndef (): Sent RW_T4T_NDEF_DETECT_EVT");
+                }
+            }
+            else
+            {
+                /* NLEN should be less than max file size */
+                RW_TRACE_ERROR2 ("rw_t4t_sm_detect_ndef (): NLEN (%d) + 2 must be <= max file size (%d)",
+                                 nlen, p_t4t->cc_file.ndef_fc.max_file_size);
+
+                p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+                rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+            }
+        }
+        else
+        {
+            /* response payload size should be T4T_FILE_LENGTH_SIZE */
+            RW_TRACE_ERROR2 ("rw_t4t_sm_detect_ndef (): Length (%d) of R-APDU must be %d",
+                             p_r_apdu->len, T4T_FILE_LENGTH_SIZE + T4T_RSP_STATUS_WORDS_SIZE);
+
+            p_t4t->ndef_status &= ~ (RW_T4T_NDEF_STATUS_NDEF_DETECTED);
+            rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+        }
+        break;
+
+    default:
+        RW_TRACE_ERROR1 ("rw_t4t_sm_detect_ndef (): unknown sub_state=%d", p_t4t->sub_state);
+        rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_read_ndef
+**
+** Description      State machine for NDEF read procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_read_ndef (BT_HDR *p_r_apdu)
+{
+    tRW_T4T_CB  *p_t4t = &rw_cb.tcb.t4t;
+    UINT8       *p;
+    UINT16      status_words;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_t4t_sm_read_ndef (): sub_state:%s (%d)",
+                      rw_t4t_get_sub_state_name (p_t4t->sub_state), p_t4t->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_t4t_sm_read_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+    /* get status words */
+    p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+    p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+    BE_STREAM_TO_UINT16 (status_words, p);
+
+    if (status_words != T4T_RSP_CMD_CMPLTED)
+    {
+        rw_t4t_handle_error (NFC_STATUS_CMD_NOT_CMPLTD, *(p-2), *(p-1));
+        GKI_freebuf (p_r_apdu);
+        return;
+    }
+
+    switch (p_t4t->sub_state)
+    {
+    case RW_T4T_SUBSTATE_WAIT_READ_RESP:
+
+        /* Read partial or complete data */
+        p_r_apdu->len -= T4T_RSP_STATUS_WORDS_SIZE;
+
+        if ((p_r_apdu->len > 0) && (p_r_apdu->len <= p_t4t->rw_length))
+        {
+            p_t4t->rw_length -= p_r_apdu->len;
+            p_t4t->rw_offset += p_r_apdu->len;
+
+            if (rw_cb.p_cback)
+            {
+                rw_data.data.status = NFC_STATUS_OK;
+                rw_data.data.p_data = p_r_apdu;
+
+                /* if need to read more data */
+                if (p_t4t->rw_length > 0)
+                {
+                    (*(rw_cb.p_cback)) (RW_T4T_NDEF_READ_EVT, &rw_data);
+
+                    if (!rw_t4t_read_file (p_t4t->rw_offset, p_t4t->rw_length, TRUE))
+                    {
+                        rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+                    }
+                }
+                else
+                {
+                    p_t4t->state = RW_T4T_STATE_IDLE;
+
+                    (*(rw_cb.p_cback)) (RW_T4T_NDEF_READ_CPLT_EVT, &rw_data);
+
+                    RW_TRACE_DEBUG0 ("rw_t4t_sm_read_ndef (): Sent RW_T4T_NDEF_READ_CPLT_EVT");
+
+                }
+
+                p_r_apdu = NULL;
+            }
+            else
+            {
+                p_t4t->rw_length = 0;
+                p_t4t->state = RW_T4T_STATE_IDLE;
+            }
+        }
+        else
+        {
+            RW_TRACE_ERROR2 ("rw_t4t_sm_read_ndef (): invalid payload length (%d), rw_length (%d)",
+                             p_r_apdu->len, p_t4t->rw_length);
+            rw_t4t_handle_error (NFC_STATUS_BAD_RESP, 0, 0);
+        }
+        break;
+
+    default:
+        RW_TRACE_ERROR1 ("rw_t4t_sm_read_ndef (): unknown sub_state = %d", p_t4t->sub_state);
+        rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+        break;
+    }
+
+    if (p_r_apdu)
+        GKI_freebuf (p_r_apdu);
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_sm_update_ndef
+**
+** Description      State machine for NDEF update procedure
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_sm_update_ndef (BT_HDR  *p_r_apdu)
+{
+    tRW_T4T_CB  *p_t4t = &rw_cb.tcb.t4t;
+    UINT8       *p;
+    UINT16      status_words;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("rw_t4t_sm_update_ndef (): sub_state:%s (%d)",
+                      rw_t4t_get_sub_state_name (p_t4t->sub_state), p_t4t->sub_state);
+#else
+    RW_TRACE_DEBUG1 ("rw_t4t_sm_update_ndef (): sub_state=%d", p_t4t->sub_state);
+#endif
+
+    /* Get status words */
+    p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;
+    p += (p_r_apdu->len - T4T_RSP_STATUS_WORDS_SIZE);
+    BE_STREAM_TO_UINT16 (status_words, p);
+
+    if (status_words != T4T_RSP_CMD_CMPLTED)
+    {
+        rw_t4t_handle_error (NFC_STATUS_CMD_NOT_CMPLTD, *(p-2), *(p-1));
+        return;
+    }
+
+    switch (p_t4t->sub_state)
+    {
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
+
+        /* NLEN has been updated */
+        /* if need to update data */
+        if (p_t4t->p_update_data)
+        {
+            p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_RESP;
+
+            if (!rw_t4t_update_file ())
+            {
+                rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+                p_t4t->p_update_data = NULL;
+            }
+        }
+        else
+        {
+            p_t4t->state = RW_T4T_STATE_IDLE;
+
+            /* just finished last step of updating (updating NLEN) */
+            if (rw_cb.p_cback)
+            {
+                rw_data.status = NFC_STATUS_OK;
+
+                (*(rw_cb.p_cback)) (RW_T4T_NDEF_UPDATE_CPLT_EVT, &rw_data);
+                RW_TRACE_DEBUG0 ("rw_t4t_sm_update_ndef (): Sent RW_T4T_NDEF_UPDATE_CPLT_EVT");
+            }
+        }
+        break;
+
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
+
+        /* if updating is not completed */
+        if (p_t4t->rw_length > 0)
+        {
+            if (!rw_t4t_update_file ())
+            {
+                rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+                p_t4t->p_update_data = NULL;
+            }
+        }
+        else
+        {
+            p_t4t->p_update_data = NULL;
+
+            /* update NLEN as last step of updating file */
+            if (!rw_t4t_update_nlen (p_t4t->ndef_length))
+            {
+                rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+            }
+            else
+            {
+                p_t4t->sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
+            }
+        }
+        break;
+
+    default:
+        RW_TRACE_ERROR1 ("rw_t4t_sm_update_ndef (): unknown sub_state = %d", p_t4t->sub_state);
+        rw_t4t_handle_error (NFC_STATUS_FAILED, 0, 0);
+        break;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_process_timeout
+**
+** Description      process timeout event
+**
+** Returns          none
+**
+*******************************************************************************/
+void rw_t4t_process_timeout (TIMER_LIST_ENT *p_tle)
+{
+    RW_TRACE_DEBUG1 ("rw_t4t_process_timeout () event=%d", p_tle->event);
+
+    if (p_tle->event == NFC_TTYPE_RW_T4T_RESPONSE)
+    {
+        rw_t4t_handle_error (NFC_STATUS_TIMEOUT, 0, 0);
+    }
+    else
+    {
+        RW_TRACE_ERROR1 ("rw_t4t_process_timeout () unknown event=%d", p_tle->event);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_data_cback
+**
+** Description      This callback function receives the data from NFCC.
+**
+** Returns          none
+**
+*******************************************************************************/
+static void rw_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
+{
+    tRW_T4T_CB *p_t4t    = &rw_cb.tcb.t4t;
+    BT_HDR     *p_r_apdu = (BT_HDR *) p_data->data.p_data;
+    tRW_DATA    rw_data;
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    UINT8  begin_state   = p_t4t->state;
+#endif
+
+    RW_TRACE_DEBUG1 ("rw_t4t_data_cback () event = 0x%X", event);
+    nfc_stop_quick_timer (&p_t4t->timer);
+
+    switch (event)
+    {
+    case NFC_DEACTIVATE_CEVT:
+        NFC_SetStaticRfCback (NULL);
+        p_t4t->state = RW_T4T_STATE_NOT_ACTIVATED;
+        return;
+
+    case NFC_ERROR_CEVT:
+        if (p_t4t->state == RW_T4T_STATE_PRESENCE_CHECK)
+        {
+            p_t4t->state   = RW_T4T_STATE_IDLE;
+            rw_data.status = NFC_STATUS_FAILED;
+            (*(rw_cb.p_cback)) (RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
+        }
+        else
+        {
+            p_t4t->state   = RW_T4T_STATE_IDLE;
+            rw_data.status = (tNFC_STATUS) (*(UINT8*) p_data);
+            (*(rw_cb.p_cback)) (RW_T4T_INTF_ERROR_EVT, &rw_data);
+        }
+        return;
+
+    case NFC_DATA_CEVT:
+        break;
+
+    default:
+        return;
+    }
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+    DispRWT4Tags (p_r_apdu, TRUE);
+#endif
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    RW_TRACE_DEBUG2 ("RW T4T state: <%s (%d)>",
+                        rw_t4t_get_state_name (p_t4t->state), p_t4t->state);
+#else
+    RW_TRACE_DEBUG1 ("RW T4T state: %d", p_t4t->state);
+#endif
+
+    switch (p_t4t->state)
+    {
+    case RW_T4T_STATE_IDLE:
+        /* Unexpected R-APDU, it should be raw frame response */
+        /* forward to upper layer without parsing */
+        if (rw_cb.p_cback)
+        {
+            rw_data.raw_frame.status = NFC_STATUS_OK;
+            rw_data.raw_frame.p_data = p_r_apdu;
+            (*(rw_cb.p_cback)) (RW_T4T_RAW_FRAME_EVT, &rw_data);
+            p_r_apdu = NULL;
+        }
+        else
+        {
+            GKI_freebuf (p_r_apdu);
+        }
+        break;
+    case RW_T4T_STATE_DETECT_NDEF:
+        rw_t4t_sm_detect_ndef (p_r_apdu);
+        GKI_freebuf (p_r_apdu);
+        break;
+    case RW_T4T_STATE_READ_NDEF:
+        rw_t4t_sm_read_ndef (p_r_apdu);
+        /* p_r_apdu may send upper lyaer */
+        break;
+    case RW_T4T_STATE_UPDATE_NDEF:
+        rw_t4t_sm_update_ndef (p_r_apdu);
+        GKI_freebuf (p_r_apdu);
+        break;
+    case RW_T4T_STATE_PRESENCE_CHECK:
+        /* if any response, send presence check with ok */
+        rw_data.status = NFC_STATUS_OK;
+        p_t4t->state = RW_T4T_STATE_IDLE;
+        (*(rw_cb.p_cback)) (RW_T4T_PRESENCE_CHECK_EVT, &rw_data);
+        GKI_freebuf (p_r_apdu);
+        break;
+    default:
+        RW_TRACE_ERROR1 ("rw_t4t_data_cback (): invalid state=%d", p_t4t->state);
+        GKI_freebuf (p_r_apdu);
+        break;
+    }
+
+#if (BT_TRACE_VERBOSE == TRUE)
+    if (begin_state != p_t4t->state)
+    {
+        RW_TRACE_DEBUG2 ("RW T4T state changed:<%s> -> <%s>",
+                          rw_t4t_get_state_name (begin_state),
+                          rw_t4t_get_state_name (p_t4t->state));
+    }
+#endif
+}
+
+
+/*******************************************************************************
+**
+** Function         rw_t4t_select
+**
+** Description      Initialise T4T
+**
+** Returns          NFC_STATUS_OK if success
+**
+*******************************************************************************/
+tNFC_STATUS rw_t4t_select (void)
+{
+    tRW_T4T_CB  *p_t4t = &rw_cb.tcb.t4t;
+
+    RW_TRACE_DEBUG0 ("rw_t4t_select ()");
+
+    NFC_SetStaticRfCback (rw_t4t_data_cback);
+
+    p_t4t->state   = RW_T4T_STATE_IDLE;
+    p_t4t->version = T4T_MY_VERSION;
+
+    /* set it min of max R-APDU data size before reading CC file */
+    p_t4t->cc_file.max_le = T4T_MIN_MLE;
+
+    /* These will be udated during NDEF detection */
+    p_t4t->max_read_size   = T4T_MAX_LENGTH_LE;
+    p_t4t->max_update_size = T4T_MAX_LENGTH_LC;
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tDetectNDef
+**
+** Description      This function performs NDEF detection procedure
+**
+**                  RW_T4T_NDEF_DETECT_EVT will be returned
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tDetectNDef (void)
+{
+    RW_TRACE_API0 ("RW_T4tDetectNDef ()");
+
+    if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_T4tDetectNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.t4t.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED)
+    {
+        /* NDEF Tag application has been selected then select CC file */
+        if (!rw_t4t_select_file (T4T_CC_FILE_ID))
+        {
+            return NFC_STATUS_FAILED;
+        }
+        rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_CC;
+    }
+    else
+    {
+        /* Select NDEF Tag Application */
+        if (!rw_t4t_select_application (rw_cb.tcb.t4t.version))
+        {
+            return NFC_STATUS_FAILED;
+        }
+        rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_SELECT_APP;
+    }
+
+    rw_cb.tcb.t4t.state     = RW_T4T_STATE_DETECT_NDEF;
+
+    return NFC_STATUS_OK;
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tReadNDef
+**
+** Description      This function performs NDEF read procedure
+**                  Note: RW_T4tDetectNDef () must be called before using this
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_READ_EVT for each segmented NDEF message
+**                      RW_T4T_NDEF_READ_CPLT_EVT for the last segment or complete NDEF
+**                      RW_T4T_NDEF_READ_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tReadNDef (void)
+{
+    RW_TRACE_API0 ("RW_T4tReadNDef ()");
+
+    if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_T4tReadNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.t4t.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    /* if NDEF has been detected */
+    if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED)
+    {
+        /* start reading NDEF */
+        if (!rw_t4t_read_file (T4T_FILE_LENGTH_SIZE, rw_cb.tcb.t4t.ndef_length, FALSE))
+        {
+            return NFC_STATUS_FAILED;
+        }
+
+        rw_cb.tcb.t4t.state     = RW_T4T_STATE_READ_NDEF;
+        rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_READ_RESP;
+
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("RW_T4tReadNDef ():No NDEF detected");
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*******************************************************************************
+**
+** Function         RW_T4tUpdateNDef
+**
+** Description      This function performs NDEF update procedure
+**                  Note: RW_T4tDetectNDef () must be called before using this
+**                        Updating data must not be removed until returning event
+**
+**                  The following event will be returned
+**                      RW_T4T_NDEF_UPDATE_CPLT_EVT for complete
+**                      RW_T4T_NDEF_UPDATE_FAIL_EVT for failure
+**
+** Returns          NFC_STATUS_OK if success
+**                  NFC_STATUS_FAILED if T4T is busy or other error
+**
+*******************************************************************************/
+tNFC_STATUS RW_T4tUpdateNDef (UINT16 length, UINT8 *p_data)
+{
+    RW_TRACE_API1 ("RW_T4tUpdateNDef () length:%d", length);
+
+    if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+    {
+        RW_TRACE_ERROR1 ("RW_T4tUpdateNDef ():Unable to start command at state (0x%X)",
+                          rw_cb.tcb.t4t.state);
+        return NFC_STATUS_FAILED;
+    }
+
+    /* if NDEF has been detected */
+    if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_DETECTED)
+    {
+        /* if read-only */
+        if (rw_cb.tcb.t4t.ndef_status & RW_T4T_NDEF_STATUS_NDEF_READ_ONLY)
+        {
+            RW_TRACE_ERROR0 ("RW_T4tUpdateNDef ():NDEF is read-only");
+            return NFC_STATUS_FAILED;
+        }
+
+        if (rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size < length + T4T_FILE_LENGTH_SIZE)
+        {
+            RW_TRACE_ERROR2 ("RW_T4tUpdateNDef ():data (%d bytes) plus NLEN is more than max file size (%d)",
+                              length, rw_cb.tcb.t4t.cc_file.ndef_fc.max_file_size);
+            return NFC_STATUS_FAILED;
+        }
+
+        /* store NDEF length and data */
+        rw_cb.tcb.t4t.ndef_length   = length;
+        rw_cb.tcb.t4t.p_update_data = p_data;
+
+        rw_cb.tcb.t4t.rw_offset     = T4T_FILE_LENGTH_SIZE;
+        rw_cb.tcb.t4t.rw_length     = length;
+
+        /* set NLEN to 0x0000 for the first step */
+        if (!rw_t4t_update_nlen (0x0000))
+        {
+            return NFC_STATUS_FAILED;
+        }
+
+        rw_cb.tcb.t4t.state     = RW_T4T_STATE_UPDATE_NDEF;
+        rw_cb.tcb.t4t.sub_state = RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN;
+
+        return NFC_STATUS_OK;
+    }
+    else
+    {
+        RW_TRACE_ERROR0 ("RW_T4tUpdateNDef ():No NDEF detected");
+        return NFC_STATUS_FAILED;
+    }
+}
+
+/*****************************************************************************
+**
+** Function         RW_T4tPresenceCheck
+**
+** Description
+**      Check if the tag is still in the field.
+**
+**      The RW_T4T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
+**      or non-presence.
+**
+** Returns
+**      NFC_STATUS_OK, if raw data frame sent
+**      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
+**      NFC_STATUS_FAILED: other error
+**
+*****************************************************************************/
+tNFC_STATUS RW_T4tPresenceCheck (void)
+{
+    tNFC_STATUS retval = NFC_STATUS_OK;
+    tRW_DATA    evt_data;
+
+    RW_TRACE_API0 ("RW_T4tPresenceCheck ()");
+
+    /* If RW_SelectTagType was not called (no conn_callback) return failure */
+    if (!rw_cb.p_cback)
+    {
+        retval = NFC_STATUS_FAILED;
+    }
+    /* If we are not activated, then RW_T4T_PRESENCE_CHECK_EVT with NFC_STATUS_FAILED */
+    else if (rw_cb.tcb.t4t.state == RW_T4T_STATE_NOT_ACTIVATED)
+    {
+        evt_data.status = NFC_STATUS_FAILED;
+        (*rw_cb.p_cback) (RW_T4T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    /* If command is pending, assume tag is still present */
+    else if (rw_cb.tcb.t4t.state != RW_T4T_STATE_IDLE)
+    {
+        evt_data.status = NFC_STATUS_OK;
+        (*rw_cb.p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
+    }
+    else
+    {
+        if (rw_t4t_read_file (0, 1, FALSE))
+        {
+            rw_cb.tcb.t4t.state = RW_T4T_STATE_PRESENCE_CHECK;
+        }
+        else
+        {
+            retval = NFC_STATUS_NO_BUFFERS;
+        }
+    }
+
+    return (retval);
+}
+
+#if (BT_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function         rw_t4t_get_state_name
+**
+** Description      This function returns the state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_t4t_get_state_name (UINT8 state)
+{
+    switch (state)
+    {
+    case RW_T4T_STATE_NOT_ACTIVATED:
+        return ("NOT_ACTIVATED");
+    case RW_T4T_STATE_IDLE:
+        return ("IDLE");
+    case RW_T4T_STATE_DETECT_NDEF:
+        return ("NDEF_DETECTION");
+    case RW_T4T_STATE_READ_NDEF:
+        return ("READ_NDEF");
+    case RW_T4T_STATE_UPDATE_NDEF:
+        return ("UPDATE_NDEF");
+    case RW_T4T_STATE_PRESENCE_CHECK:
+        return ("PRESENCE_CHECK");
+    default:
+        return ("???? UNKNOWN STATE");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         rw_t4t_get_sub_state_name
+**
+** Description      This function returns the sub_state name.
+**
+** NOTE             conditionally compiled to save memory.
+**
+** Returns          pointer to the name
+**
+*******************************************************************************/
+static char *rw_t4t_get_sub_state_name (UINT8 sub_state)
+{
+    switch (sub_state)
+    {
+    case RW_T4T_SUBSTATE_WAIT_SELECT_APP:
+        return ("WAIT_SELECT_APP");
+    case RW_T4T_SUBSTATE_WAIT_SELECT_CC:
+        return ("WAIT_SELECT_CC");
+    case RW_T4T_SUBSTATE_WAIT_CC_FILE:
+        return ("WAIT_CC_FILE");
+    case RW_T4T_SUBSTATE_WAIT_SELECT_NDEF_FILE:
+        return ("WAIT_SELECT_NDEF_FILE");
+    case RW_T4T_SUBSTATE_WAIT_READ_NLEN:
+        return ("WAIT_READ_NLEN");
+
+    case RW_T4T_SUBSTATE_WAIT_READ_RESP:
+        return ("WAIT_READ_RESP");
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_RESP:
+        return ("WAIT_UPDATE_RESP");
+    case RW_T4T_SUBSTATE_WAIT_UPDATE_NLEN:
+        return ("WAIT_UPDATE_NLEN");
+    default:
+        return ("???? UNKNOWN SUBSTATE");
+    }
+}
+#endif
+
+#endif /* (NFC_INCLUDED == TRUE) */
diff --git a/src/nfc/tags/tags_int.c b/src/nfc/tags/tags_int.c
new file mode 100644
index 0000000..ce7266b
--- /dev/null
+++ b/src/nfc/tags/tags_int.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the common data types shared by Reader/Writer mode
+ *  and Card Emulation.
+ *
+ ******************************************************************************/
+#include "nfc_target.h"
+#include "bt_types.h"
+
+#if (NFC_INCLUDED == TRUE)
+#include "nfc_api.h"
+#include "rw_api.h"
+#include "rw_int.h"
+#include "tags_int.h"
+
+#define T1T_MAX_NUM_OPCODES         9
+#define T1T_STATIC_OPCODES          5
+#define T1T_MAX_TAG_MODELS          2
+
+const tT1T_CMD_RSP_INFO t1t_cmd_rsp_infos[] =
+{
+    /* Note: the order of these commands can not be changed.
+     * If new events are added, add them after T1T_CMD_WRITE_NE8 */
+/*   opcode         cmd_len,  uid_offset,  rsp_len */
+    {T1T_CMD_RID,       7,          3,      6},
+    {T1T_CMD_RALL,      7,          3,      122},
+    {T1T_CMD_READ,      7,          3,      2},
+    {T1T_CMD_WRITE_E,   7,          3,      2},
+    {T1T_CMD_WRITE_NE,  7,          3,      2},
+    {T1T_CMD_RSEG,      14,         10,     129},
+    {T1T_CMD_READ8,     14,         10,     9},
+    {T1T_CMD_WRITE_E8,  14,         10,     9},
+    {T1T_CMD_WRITE_NE8, 14,         10,     9}
+};
+
+const tT1T_INIT_TAG t1t_init_content[] =
+{
+/*  Tag Name            CC3,        is dynamic, ltv[0]  ltv[1]  ltv[2]  mtv[0]  mtv[1]  mtv[2]*/
+    {RW_T1T_IS_TOPAZ96, 0x0E,       FALSE,      {0,      0,      0},      {0,      0,      0}},
+    {RW_T1T_IS_TOPAZ512,0x3F,       TRUE,       {0xF2,   0x30,   0x33},   {0xF0,   0x02,   0x03}}
+};
+
+#define T2T_MAX_NUM_OPCODES         3
+#define T2T_MAX_TAG_MODELS          7
+
+const tT2T_CMD_RSP_INFO t2t_cmd_rsp_infos[] =
+{
+    /* Note: the order of these commands can not be changed.
+     * If new events are added, add them after T2T_CMD_SEC_SEL */
+/*  opcode            cmd_len,   rsp_len, nack_rsp_len */
+    {T2T_CMD_READ,      2,          16,     1},
+    {T2T_CMD_WRITE,     6,          1,      1},
+    {T2T_CMD_SEC_SEL,   2,          1,      1}
+};
+
+const tT2T_INIT_TAG t2t_init_content[] =
+{
+/*  Tag Name        is_multi_v  Ver Block                   Ver No                               Vbitmask   to_calc_cc CC3      OTP     BLPB */
+    {TAG_MIFARE_MID,    TRUE,   T2T_MIFARE_VERSION_BLOCK,   T2T_MIFARE_ULTRALIGHT_VER_NO,        0xFFFF,    FALSE,     0x06,    FALSE,  T2T_DEFAULT_LOCK_BLPB},
+    {TAG_MIFARE_MID,    TRUE,   T2T_MIFARE_VERSION_BLOCK,   T2T_MIFARE_ULTRALIGHT_FAMILY_VER_NO, 0xFFFF,    TRUE,      0x00,    FALSE,  T2T_DEFAULT_LOCK_BLPB},
+    {TAG_KOVIO_MID,     FALSE,  0x00,                       0x00,                                0x0000,    FALSE,     0x1D,    TRUE,   0x04},
+    {TAG_INFINEON_MID,  TRUE,   T2T_INFINEON_VERSION_BLOCK, T2T_INFINEON_MYD_MOVE_LEAN,          0xFFF0,    FALSE,     0x06,    FALSE,  T2T_DEFAULT_LOCK_BLPB},
+    {TAG_INFINEON_MID,  TRUE,   T2T_INFINEON_VERSION_BLOCK, T2T_INFINEON_MYD_MOVE,               0xFFF0,    FALSE,     0x10,    FALSE,  T2T_DEFAULT_LOCK_BLPB},
+    {TAG_BRCM_MID,      TRUE,   T2T_BRCM_VERSION_BLOCK,     T2T_BRCM_STATIC_MEM,                 0xFFFF,    FALSE,     0x06,    FALSE,  T2T_DEFAULT_LOCK_BLPB},
+    {TAG_BRCM_MID,      TRUE,   T2T_BRCM_VERSION_BLOCK,     T2T_BRCM_DYNAMIC_MEM,                0xFFFF,    FALSE,     0x3C,    FALSE,  T2T_DEFAULT_LOCK_BLPB}
+
+};
+
+const UINT8 t4t_v10_ndef_tag_aid[T4T_V10_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};
+const UINT8 t4t_v20_ndef_tag_aid[T4T_V20_NDEF_TAG_AID_LEN] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+const char * const t1t_cmd_str[] = {
+    "T1T_RID",
+    "T1T_RALL",
+    "T1T_READ",
+    "T1T_WRITE_E",
+    "T1T_WRITE_NE",
+    "T1T_RSEG",
+    "T1T_READ8",
+    "T1T_WRITE_E8",
+    "T1T_WRITE_NE8"
+};
+
+const char * const t2t_cmd_str[] = {
+    "T2T_CMD_READ",
+    "T2T_CMD_WRITE",
+    "T2T_CMD_SEC_SEL"
+};
+#endif
+
+static unsigned int tags_ones32 (register unsigned int x);
+
+/*******************************************************************************
+**
+** Function         t1t_cmd_to_rsp_info
+**
+** Description      This function maps the given opcode to tT1T_CMD_RSP_INFO.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT1T_CMD_RSP_INFO * t1t_cmd_to_rsp_info (UINT8 opcode)
+{
+    const tT1T_CMD_RSP_INFO *p_ret = NULL, *p;
+    int xx;
+
+    for (xx = 0, p=&t1t_cmd_rsp_infos[0]; xx<T1T_MAX_NUM_OPCODES; xx++, p++)
+    {
+        if (opcode == p->opcode)
+        {
+            if ((xx < T1T_STATIC_OPCODES) || (rw_cb.tcb.t1t.hr[0] != T1T_STATIC_HR0))
+                p_ret = p;
+            break;
+        }
+    }
+
+    return p_ret;
+}
+
+
+/*******************************************************************************
+**
+** Function         t1t_tag_init_data
+**
+** Description      This function maps the given opcode to tT1T_INIT_TAG.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT1T_INIT_TAG * t1t_tag_init_data (UINT8 tag_model)
+{
+    const tT1T_INIT_TAG *p_ret = NULL, *p;
+    int xx;
+
+    for (xx = 0, p = &t1t_init_content[0]; xx < T1T_MAX_TAG_MODELS; xx++, p++)
+    {
+        if (tag_model == p->tag_model)
+        {
+            p_ret = p;
+            break;
+        }
+    }
+
+    return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t2t_tag_init_data
+**
+** Description      This function maps the given manufacturer id and version to
+**                  tT2T_INIT_TAG.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT2T_INIT_TAG * t2t_tag_init_data (UINT8 manufacturer_id, BOOLEAN b_valid_ver, UINT16 version_no)
+{
+    const tT2T_INIT_TAG *p_ret = NULL, *p;
+    int xx;
+
+    for (xx = 0, p = &t2t_init_content[0]; xx < T2T_MAX_TAG_MODELS; xx++, p++)
+    {
+        if (manufacturer_id == p->manufacturer_id)
+        {
+            if (  (!p->b_multi_version)
+                ||(!b_valid_ver)
+                ||(p->version_no == (version_no & p->version_bmask))  )
+            {
+                p_ret = p;
+                break;
+            }
+        }
+    }
+
+    return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t2t_cmd_to_rsp_info
+**
+** Description      This function maps the given opcode to tT2T_CMD_RSP_INFO.
+**
+** Returns          tNFC_STATUS
+**
+*******************************************************************************/
+const tT2T_CMD_RSP_INFO * t2t_cmd_to_rsp_info (UINT8 opcode)
+{
+    const tT2T_CMD_RSP_INFO *p_ret = NULL, *p;
+    int xx;
+
+    for (xx = 0, p = &t2t_cmd_rsp_infos[0]; xx < T2T_MAX_NUM_OPCODES; xx++, p++)
+    {
+        if (opcode == p->opcode)
+        {
+            p_ret = p;
+            break;
+        }
+    }
+
+    return p_ret;
+}
+
+/*******************************************************************************
+**
+** Function         t1t_info_to_evt
+**
+** Description      This function maps the given tT1T_CMD_RSP_INFO to RW/CE event code
+**
+** Returns          RW/CE event code
+**
+*******************************************************************************/
+UINT8 t1t_info_to_evt (const tT1T_CMD_RSP_INFO * p_info)
+{
+    return ((UINT8) (p_info - t1t_cmd_rsp_infos) + RW_T1T_FIRST_EVT);
+}
+
+/*******************************************************************************
+**
+** Function         t2t_info_to_evt
+**
+** Description      This function maps the given tT2T_CMD_RSP_INFO to RW/CE event code
+**
+** Returns          RW/CE event code
+**
+*******************************************************************************/
+UINT8 t2t_info_to_evt (const tT2T_CMD_RSP_INFO * p_info)
+{
+    return ((UINT8) (p_info - t2t_cmd_rsp_infos) + RW_T2T_FIRST_EVT);
+}
+
+#if (BT_TRACE_PROTOCOL == TRUE)
+/*******************************************************************************
+**
+** Function         t1t_info_to_str
+**
+** Description      This function maps the given tT1T_CMD_RSP_INFO to T1T cmd str
+**
+** Returns          T1T cmd str
+**
+*******************************************************************************/
+const char * t1t_info_to_str (const tT1T_CMD_RSP_INFO * p_info)
+{
+    int ind = (int) (p_info - t1t_cmd_rsp_infos);
+    if (ind < T1T_MAX_NUM_OPCODES)
+        return (const char *) t1t_cmd_str[ind];
+    else
+        return "";
+}
+
+/*******************************************************************************
+**
+** Function         t2t_info_to_str
+**
+** Description      This function maps the given tT2T_CMD_RSP_INFO to T2T cmd str
+**
+** Returns          T2T cmd str
+**
+*******************************************************************************/
+const char * t2t_info_to_str (const tT2T_CMD_RSP_INFO * p_info)
+{
+    int ind = (int) (p_info - t2t_cmd_rsp_infos);
+    if (ind < T2T_MAX_NUM_OPCODES)
+        return (const char *) t2t_cmd_str[ind];
+    else
+        return "";
+}
+#endif
+
+/*******************************************************************************
+**
+** Function         tags_pow
+**
+** Description      This function calculates x(base) power of y.
+**
+** Returns          int
+**
+*******************************************************************************/
+int tags_pow (int x, int y)
+{
+    int i, ret = 1;
+    for (i = 0; i < y; i++)
+    {
+        ret *= x;
+    }
+    return ret;
+}
+
+/*******************************************************************************
+**
+** Function         ones32
+**
+** Description      This function returns number of bits set in an unsigned
+**                  integer variable
+**
+** Returns          int
+**
+*******************************************************************************/
+static unsigned int tags_ones32 (register unsigned int x)
+{
+        /* 32-bit recursive reduction using SWAR...
+	   but first step is mapping 2-bit values
+	   into sum of 2 1-bit values in sneaky way
+	*/
+        x -= ((x >> 1) & 0x55555555);
+        x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+        x = (((x >> 4) + x) & 0x0f0f0f0f);
+        x += (x >> 8);
+        x += (x >> 16);
+        return (x & 0x0000003f);
+}
+
+/*******************************************************************************
+**
+** Function         tags_log2
+**
+** Description      This function calculates log to the base  2.
+**
+** Returns          int
+**
+*******************************************************************************/
+unsigned int tags_log2 (register unsigned int x)
+{
+        x |= (x >> 1);
+        x |= (x >> 2);
+        x |= (x >> 4);
+        x |= (x >> 8);
+        x |= (x >> 16);
+
+        return (tags_ones32 (x) - 1);
+}
+
+#endif /* NFC_INCLUDED == TRUE*/
diff --git a/src/stack-info.txt b/src/stack-info.txt
new file mode 100644
index 0000000..3e8b16b
--- /dev/null
+++ b/src/stack-info.txt
@@ -0,0 +1,24 @@
+This file contains version information for the NFC stack code.
+
+# reset nv data on Clear All Pipe CMD Ntf
+element * .../main_prasadk_1747333/LATEST
+
+# turn off NFC when in power-off-sleep mode
+element * .../main_sherrys_1747155/LATEST
+
+# reading NDEF message in T3T
+element * .../main_darinlee_1726051/LATEST
+
+# NFA_RwT3TWrite crash
+element * .../main_darinlee_1721357/LATEST
+
+# handle deleted connectivity pipe
+element * .../main_prasadk_1722753/LATEST
+
+# handle missing EEPROM
+element * .../main_sherrys_1706383/LATEST
+
+# warm-reset Oberthur secure element
+element * .../main_sherrys_1704686/LATEST
+
+element * NFA_MI_1.03.45
diff --git a/src/udrv/include/uamp_api.h b/src/udrv/include/uamp_api.h
new file mode 100755
index 0000000..9eb733c
--- /dev/null
+++ b/src/udrv/include/uamp_api.h
@@ -0,0 +1,168 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains serial definitions from WIDCOMM's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+#ifndef UAMP_API_H
+#define UAMP_API_H
+
+/*****************************************************************************
+**  Constant and Type Definitions
+*****************************************************************************/
+
+/* UAMP identifiers */
+#define UAMP_ID_1   1
+#define UAMP_ID_2   2
+typedef UINT8 tUAMP_ID;
+
+/* UAMP event ids (used by UAMP_CBACK) */
+#define UAMP_EVT_RX_READY           0   /* Data from AMP controller is ready to be read */
+#define UAMP_EVT_CTLR_REMOVED       1   /* Controller removed */
+#define UAMP_EVT_CTLR_READY         2   /* Controller added/ready */
+typedef UINT8 tUAMP_EVT;
+
+
+/* UAMP Channels */
+#define UAMP_CH_HCI_CMD            0   /* HCI Command channel */
+#define UAMP_CH_HCI_EVT            1   /* HCI Event channel */
+#define UAMP_CH_HCI_DATA           2   /* HCI ACL Data channel */
+typedef UINT8 tUAMP_CH;
+
+/* tUAMP_EVT_DATA: union for event-specific data, used by UAMP_CBACK */
+typedef union {
+    tUAMP_CH channel;       /* UAMP_EVT_RX_READY: channel for which rx occured */
+} tUAMP_EVT_DATA;
+
+
+
+
+/*****************************************************************************
+**
+** Function:    UAMP_CBACK
+**
+** Description: Callback for events. Register callback using UAMP_Init.
+**
+** Parameters   amp_id:         AMP device identifier that generated the event
+**              amp_evt:        event id
+**              p_amp_evt_data: pointer to event-specific data
+**
+*****************************************************************************/
+typedef void (tUAMP_CBACK)(tUAMP_ID amp_id, tUAMP_EVT amp_evt, tUAMP_EVT_DATA *p_amp_evt_data);
+
+/*****************************************************************************
+**  external function declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************************************************************************
+**
+** Function:    UAMP_Init
+**
+** Description: Initialize UAMP driver
+**
+** Parameters   p_cback:    Callback function for UAMP event notification
+**
+*****************************************************************************/
+BT_API BOOLEAN UAMP_Init(tUAMP_CBACK *p_cback);
+
+
+/*****************************************************************************
+**
+** Function:    UAMP_Open
+**
+** Description: Open connection to local AMP device.
+**
+** Parameters   app_id: Application specific AMP identifer. This value
+**                      will be included in AMP messages sent to the
+**                      BTU task, to identify source of the message
+**
+*****************************************************************************/
+BT_API BOOLEAN UAMP_Open(tUAMP_ID amp_id);
+
+/*****************************************************************************
+**
+** Function:    UAMP_Close
+**
+** Description: Close connection to local AMP device.
+**
+** Parameters   app_id: Application specific AMP identifer.
+**
+*****************************************************************************/
+BT_API void UAMP_Close(tUAMP_ID amp_id);
+
+
+/*****************************************************************************
+**
+** Function:    UAMP_Write
+**
+** Description: Send buffer to AMP device.
+**
+**
+** Parameters:  app_id:     AMP identifer.
+**              p_buf:      pointer to buffer to write
+**              num_bytes:  number of bytes to write
+**              channel:    UAMP_CH_HCI_ACL, or UAMP_CH_HCI_CMD
+**
+** Returns:     number of bytes written
+**
+*****************************************************************************/
+BT_API UINT16 UAMP_Write(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 num_bytes, tUAMP_CH channel);
+
+
+/*****************************************************************************
+**
+** Function:    UAMP_WriteBuf
+**
+** Description: Send GKI buffer to AMP device. Frees GKI buffer when done.
+**
+** Parameters   app_amp_id: AMP identifer (BTM_AMP_1, BTM_AMP_2, ...)
+**              p_msg:      message to send.
+**
+*****************************************************************************/
+BT_API UINT16 UAMP_WriteBuf(tUAMP_ID amp_id, BT_HDR *p_msg);
+
+
+/*****************************************************************************
+**
+** Function:    UAMP_Read
+**
+** Description: Read incoming data from AMP. Call after receiving a
+**              UAMP_EVT_RX_READY callback event.
+**
+** Parameters:  app_id:     AMP identifer.
+**              p_buf:      pointer to buffer for holding incoming AMP data
+**              buf_size:   size of p_buf
+**              channel:    UAMP_CH_HCI_ACL, or UAMP_CH_HCI_EVT
+**
+** Returns:     number of bytes read
+**
+*****************************************************************************/
+BT_API UINT16 UAMP_Read(tUAMP_ID amp_id, UINT8 *p_buf, UINT16 buf_size, tUAMP_CH channel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UAMP_API_H */
diff --git a/src/udrv/include/ucodec.h b/src/udrv/include/ucodec.h
new file mode 100755
index 0000000..6178fdc
--- /dev/null
+++ b/src/udrv/include/ucodec.h
@@ -0,0 +1,385 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains codec definitions from Widcomm's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UCODEC_H
+#define UCODEC_H
+
+#include "bt_target.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*******************************************************************************
+** Codec APIs
+*******************************************************************************/
+
+/**** Codec IDs ****/
+#define UCODEC_ID_1             0
+#define UCODEC_ID_2             1
+#define UCODEC_ID_3             2
+#define UCODEC_ID_4             3
+#define UCODEC_NUMBER           4
+
+typedef UINT8 tUCODEC_ID;
+
+/**** Status ****/
+#define UCODEC_SUCCESS              0x00
+#define UCODEC_TX_DONE              0x01
+#define UCODEC_RX_READY             0x02
+#define UCODEC_FLOW_CTRL_ON         0x03
+#define UCODEC_FLOW_CTRL_OFF        0x04
+#define UCODEC_OVERFLOW             0x05
+#define UCODEC_UNSUPORTED_CNF       0x06
+#define UCODEC_WRONG_PARAM          0x07
+#define UCODEC_NOT_CONFIGURED       0x08
+#define UCODEC_OUT_OF_MEMORY        0x09
+#define UCODEC_GENERIC_ERROR        0x0a
+#define UCODEC_RECOVERABLE_ERROR    0x0b
+#define UCODEC_UNRECOVERABLE_ERROR  0x0c
+#define UCODEC_LOW_LEVEL_DRIVER_ERROR   (0x0d)
+
+typedef UINT8 tUCODEC_STATUS;
+
+/**** Media type ****/
+#define UCODEC_MEDIA_TYPE_AUDIO 0
+#define UCODEC_MEDIA_TYPE_VIDEO 1
+#define UCODEC_MEDIA_TYPE_MULTI 2
+
+typedef UINT8 tUCODEC_MEDIA_TYPE;
+
+/**** Audio Codec type ****/
+#define UCODEC_AUDIO_SBC        0
+#define UCODEC_AUDIO_M12_LAYER1 1   /* layer1 (mp1) */
+#define UCODEC_AUDIO_M12_LAYER2 2   /* layer2 (mp2) */
+#define UCODEC_AUDIO_M12_LAYER3 3   /* layer3 (mp3) */
+#define UCODEC_AUDIO_M24_2LC    4   /* MPEG-2 AAC LC */
+#define UCODEC_AUDIO_M24_4LC    5   /* MPEG-4 AAC LC */
+#define UCODEC_AUDIO_M24_4LTP   6   /* MPEG-4 AAC LTP */
+#define UCODEC_AUDIO_M24_4S     7   /* MPEG-4 AAC scalable */
+#define UCODEC_AUDIO_VOLUME     8   /* Volume settings */
+#define UCODEC_AUDIO_BALANCE    9   /* Balance settings */
+
+typedef UINT8 tUCODEC_AUDIO_FEAT_TYPE;
+
+/**** Video Codec type -> TODO ****/
+/*TBD*/
+
+typedef UINT8 tUCODEC_VIDEO_FEAT_TYPE;
+
+/**** SBC sample frequency ****/
+#define UCODEC_SBC_SMP_FREQ_16    0  /* 16 */
+#define UCODEC_SBC_SMP_FREQ_32    1  /* 23 */
+#define UCODEC_SBC_SMP_FREQ_44    2  /* 44.1 */
+#define UCODEC_SBC_SMP_FREQ_48    3  /* 48 */
+
+typedef UINT8 tUCODEC_SBC_SMP_FREQ;
+
+/**** SBC sample frequency ****/
+#define UCODEC_SBC_SUBBAND_4    4
+#define UCODEC_SBC_SUBBAND_8    8
+
+typedef UINT8 tUCODEC_SBC_SUBBAND;
+/**** Allocation method ****/
+#define UCODEC_SBC_ALLOC_MD_S   0   /* SNR */
+#define UCODEC_SBC_ALLOC_MD_L   1   /* loundess */
+
+typedef UINT8 tUCODEC_SBC_ALLOC_MD;
+
+/**** MPEG sample frequency ****/
+#define UCODEC_M12_SMP_FREQ_16    0   /* 16 */
+#define UCODEC_M12_SMP_FREQ_22    1   /* 22 */
+#define UCODEC_M12_SMP_FREQ_24    2  /* 24 */
+#define UCODEC_M12_SMP_FREQ_32    3  /* 32 */
+#define UCODEC_M12_SMP_FREQ_44    4  /* 44 */
+#define UCODEC_M12_SMP_FREQ_48    5  /* 48 */
+
+typedef UINT8 tUCODEC_M12_SMP_FREQ;
+
+/**** Channel mode ****/
+#define UCODEC_CHN_MONO            0
+#define UCODEC_CHN_DUAL            1
+#define UCODEC_CHN_STEREO          2
+#define UCODEC_CHN_JOINT_STEREO    3
+
+typedef UINT8 tUCODEC_CH_MODE;
+/**** Audio Codec type ****/
+#define UCODEC_M24_SMP_FREQ_8     0   /*  8 */
+#define UCODEC_M24_SMP_FREQ_11    1   /* 11 */
+#define UCODEC_M24_SMP_FREQ_12    2   /* 12 */
+#define UCODEC_M24_SMP_FREQ_16    3   /* 16 */
+#define UCODEC_M24_SMP_FREQ_22    4   /* 22.05 */
+#define UCODEC_M24_SMP_FREQ_24    5   /* 24 */
+#define UCODEC_M24_SMP_FREQ_32    6   /* 32 */
+#define UCODEC_M24_SMP_FREQ_44    7   /* 44.1 */
+#define UCODEC_M24_SMP_FREQ_48    8   /* 48 */
+#define UCODEC_M24_SMP_FREQ_64    9   /* 64 */
+#define UCODEC_M24_SMP_FREQ_88    10  /* 88 */
+#define UCODEC_M24_SMP_FREQ_96    11  /* 96 */
+
+typedef UINT8 tUCODEC_M24_SMP_FREQ;
+
+/**** Codec configuration structure ****/
+typedef struct tUCODEC_CNF_SBC_TAG
+{
+    tUCODEC_SBC_SMP_FREQ    SampleFreq;
+    tUCODEC_CH_MODE         ChannelMode;
+    UINT16                  Offset;     /* GKI buffer based offset for UCODEC_ReadBuf */
+    UINT16                  MtuSize;    /* Max buffer len for UCODEC_ReadBuf*/
+    UINT8                   PoolId;     /* GKI pool ID for UCODEC_ReadBuf */
+    UINT8                   NumBlock;   /* Number of block in block unit : 4 blocks 8 blocks 12 blocks 16 blocks are the possible value */
+    UINT8                   Subband;
+    tUCODEC_SBC_ALLOC_MD    AllocMthd;
+    UINT8                   MinBitPool;
+    UINT8                   MaxBitPool;
+} tUCODEC_CNF_SBC;
+
+typedef struct tUCODEC_CNF_M12_TAG
+{
+    tUCODEC_CH_MODE         ChannelMode; /* Mono, Dual, stereo, joint stereo */
+    tUCODEC_M12_SMP_FREQ    SampleFreq; /* Sample freq: 16, 22, 24, 32, 44, 48 */
+    UINT16                  BitRate;    /* Bit rate in bit per sec */
+    UINT16                  Offset;     /* GKI buffer based offset for UCODEC_ReadBuf */
+    UINT16                  MtuSize;    /* Max buffer len for UCODEC_ReadBuf*/
+    UINT8                   PoolId;     /* GKI pool ID for UCODEC_ReadBuf */
+    BOOLEAN                 VBR;        /* Variable Bit Rate */
+    BOOLEAN                 CRC_On;     /* CRC error detection */
+    BOOLEAN                 MPF;        /* Media payload format */
+} tUCODEC_CNF_M12;
+
+typedef struct tUCODEC_CNF_M24_TAG
+{
+    tUCODEC_M24_SMP_FREQ    SampleFreq; /* Sample freq: 8, 11, 12, 16, 22.05, 24, 32, 44.1, 48, 64, 88, 96 */
+    UINT32                  BitRate;    /* Bit rate */
+    UINT16                  Offset;     /* GKI buffer based offset for UCODEC_ReadBuf */
+    UINT16                  MtuSize;    /* Max buffer len for UCODEC_ReadBuf*/
+    UINT8                   PoolId;     /* GKI pool ID for UCODEC_ReadBuf */
+    UINT8                   Chanels;    /* 1 or 2 chanels */
+} tUCODEC_CNF_M24;
+
+
+typedef union tUCODEC_CODEC_TYPE_TAG
+{
+    tUCODEC_AUDIO_FEAT_TYPE AudioType;
+    tUCODEC_VIDEO_FEAT_TYPE VideoType;
+} tUCODEC_CODEC_TYPE;
+
+typedef union tUCODEC_FEATURE_TAG
+{
+    /* Add here the audio feature structure */
+    tUCODEC_CNF_SBC SBCConfig;
+    tUCODEC_CNF_M12 M12Config;
+    tUCODEC_CNF_M24 M24Config;
+    UINT8           Volume;     /* 0 to mute. 0xFF for the max volume */
+    UINT8           Balance;    /* 0->100% right, 255->100% left */
+    /* Add here the video feature structure */
+    /* TBD */
+} tUCODEC_FEATURE;
+
+typedef struct tUCODEC_CNF_TAG
+{
+    tUCODEC_MEDIA_TYPE  MediaType;
+    tUCODEC_CODEC_TYPE  Type;
+    tUCODEC_FEATURE     Feature;
+} tUCODEC_CNF;
+
+typedef struct tUCODEC_BUF_INFO_TAG
+{
+    UINT8       NumOfFrames;
+    UINT32      TimesStamp;
+} tUCODEC_BUF_INFO;
+
+
+/******************************************************************************
+**
+** Function         tUCODEC_CBACK_PTR
+**
+** Description      This call back report CODEC indication.
+**                  It report codec error as well as flow onfrol indication.
+**
+**                  Input : CodecId: Id of the codec that calls this call back.
+**                          Status: ->UCODEC_FLOW_CTRL_OFF if the Tx Q just
+**                                  went below the low watermark
+**                                  ->UCODEC_RX_READY if data are ready to be
+**                                  read. This olny hapens when the Rx Q was
+**                                  empty before receiving data.
+**                                  ->UCODEC_INTERNAL_ERROR if something went
+**                                  wrong with the driver
+**
+**                  Output Parameters : None
+**
+** Returns          None.
+**
+******************************************************************************/
+typedef void (* tUCODEC_CBACK_PTR)(tUCODEC_ID, tUCODEC_STATUS);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+/******************************************************************************
+**
+** Function         UCODEC_Init
+**
+** Description      Startup initialisation function. This function is called
+**                  before any orther function of UCODEC it initialize UCODEC
+**                  internal structure an the external codec.
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS if The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS    UCODEC_Init       (void *);
+
+/******************************************************************************
+**
+** Function         UCODEC_Configure
+**
+** Description      Initialise the CODEC for a particular stream.
+**
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**                          CbackPrt: Call back pointer for codec feedback.
+**                          pConfig: Pointer on a codec configuration structure.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS if The action was performed with sucess.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS    UCODEC_Configure  (tUCODEC_ID, tUCODEC_CBACK_PTR, tUCODEC_CNF *);
+
+/******************************************************************************
+**
+** Function         UCODEC_FlushTx
+**
+** Description      Fluch Tx buffer Q.
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS if The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS    UCODEC_FlushTx      (tUCODEC_ID);
+
+/******************************************************************************
+**
+** Function         UCODEC_FlushRx
+**
+** Description      Fluch Rx buffer Q.
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS if The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS    UCODEC_FlushRx      (tUCODEC_ID);
+
+/******************************************************************************
+**
+** Function         UCODEC_WriteBuf
+**
+** Description      Send a buffer to the codec.
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**                          pBuf: Pointer onto the GKI buffer to be send to the CODEC.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS if The action was performed with sucess.
+**                  UCODEC_FLOW_CTRL_ON if The codec buffer Q had reach a UCODEC_HIGH_WM
+**                                      watermark. The buffer is queued
+**                  UCODEC_OVERFLOW if The codec buffer Q had reach a critical
+**                                     watermark. The buffer is dropped.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS    UCODEC_WriteBuf   (tUCODEC_ID, BT_HDR *);
+
+/******************************************************************************
+**
+** Function         UCODEC_ReadBuf
+**
+** Description      Get a buffer from the codec.
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**
+**                  Output Parameters : None
+**
+** Returns          Pointer on the GKI buffer. NULL if the Rx Q is empty
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS  UCODEC_ReadBuf    (tUCODEC_ID, BT_HDR **, tUCODEC_BUF_INFO *);
+
+/******************************************************************************
+**
+** Function         UCODEC_Close
+**
+** Description      This function is called to put the codec in low power mode
+**
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS : The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS   UCODEC_Close   (tUCODEC_ID);
+
+/******************************************************************************
+**
+** Function         UCODEC_Open
+**
+** Description      This function is called to resume the codec from low power
+**                  mode after UCODEC_Close had been called. It will put the
+**                  codec in the state it was before UCODEC_Close being called.
+**
+**                  Input : CodecId: Id of the codec to perform the operation on.
+**
+**                  Output Parameters : None
+**
+** Returns          UCODEC_SUCCESS : The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUCODEC_STATUS   UCODEC_Open     (tUCODEC_ID);
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif /* UCODEC_H */
diff --git a/src/udrv/include/udac.h b/src/udrv/include/udac.h
new file mode 100755
index 0000000..a2d7ab1
--- /dev/null
+++ b/src/udrv/include/udac.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Definitions for UDAC driver
+ *
+ ******************************************************************************/
+#ifndef UDAC_H
+#define UDAC_H
+
+
+#define UDAC_GAIN_MAX     0x00FFF
+typedef UINT16 tUDAC_GAIN;
+
+/* API functions for DAC driver */
+
+
+/*****************************************************************************
+**
+** Function         DAC_Init
+**
+** Description
+**      Initialize the DAC subsystem
+**
+** Input parameters
+**      Nothing
+**
+** Output parameters
+**      Nothing
+**
+** Returns
+**      Nothing
+**
+*****************************************************************************/
+void UDAC_Init(void *p_cfg);
+
+
+/*****************************************************************************
+**
+** Function         DAC_Read
+**
+** Description
+**      Read current DAC gain
+**
+** Input parameters
+**      Nothing
+**
+** Output parameters
+**      Nothing
+**
+** Returns
+**      Current gain setting
+**
+*****************************************************************************/
+tUDAC_GAIN UDAC_Read(void);
+
+
+/*****************************************************************************
+**
+** Function         DAC_Set
+**
+** Description
+**      Set the DAC gain
+**
+** Input parameters
+**      gain        Gain setting
+**
+** Output parameters
+**      Nothing
+**
+** Returns
+**      Nothing
+**
+*****************************************************************************/
+void UDAC_Set(tUDAC_GAIN gain);
+
+#endif /* #ifndef UDAC_H */
diff --git a/src/udrv/include/uipc.h b/src/udrv/include/uipc.h
new file mode 100755
index 0000000..0d6358a
--- /dev/null
+++ b/src/udrv/include/uipc.h
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2007-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  UIPC wrapper interface
+ *
+ ******************************************************************************/
+#ifndef UIPC_H
+#define UIPC_H
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+
+#define UIPC_CH_ID_ALL  0   /* used to address all the ch id at once */
+#define UIPC_CH_ID_0    1   /* shared mem interface */
+#define UIPC_CH_ID_1    2   /* TCP socket (GPS) */
+#define UIPC_CH_ID_2    3   /* BSA control socket */
+#define UIPC_CH_ID_3    4   /* BSA HH */
+#define UIPC_CH_ID_4    5   /* Future usage */
+#define UIPC_CH_ID_5    6   /* Future usage */
+#define UIPC_CH_ID_6    7   /* Future usage */
+#define UIPC_CH_ID_7    8   /* Future usage */
+#define UIPC_CH_ID_8    9   /* Future usage */
+#define UIPC_CH_ID_9    10  /* Future usage */
+#define UIPC_CH_ID_10   11  /* Future usage */
+#define UIPC_CH_ID_11   12  /* Future usage */
+#define UIPC_CH_ID_12   13  /* Future usage */
+#define UIPC_CH_ID_13   14  /* Future usage */
+#define UIPC_CH_ID_14   15  /* Future usage */
+#define UIPC_CH_ID_15   16  /* Future usage */
+#define UIPC_CH_ID_16   17  /* Future usage */
+#define UIPC_CH_ID_17   18  /* Future usage */
+#define UIPC_CH_ID_18   19  /* Future usage */
+#define UIPC_CH_ID_19   20  /* Future usage */
+#define UIPC_CH_ID_20   21  /* Future usage */
+#define UIPC_CH_ID_21   22  /* Future usage */
+#define UIPC_CH_ID_22   23  /* Future usage */
+#define UIPC_CH_ID_23   24  /* Future usage */
+#define UIPC_CH_ID_24   25  /* Future usage */
+
+
+
+#define UIPC_CH_NUM 25
+
+typedef UINT8 tUIPC_CH_ID;
+
+
+typedef void (tUIPC_RCV_CBACK)(BT_HDR *p_msg); /* points to BT_HDR which describes event type and length of data; len contains the number of bytes of entire message (sizeof(BT_HDR) + offset + size of data) */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*******************************************************************************
+**
+** Function         UIPC_Init
+**
+** Description      Initialize UIPC module
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern void UIPC_Init(void *);
+
+/*******************************************************************************
+**
+** Function         UIPC_Open
+**
+** Description      Open UIPC interface
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         UIPC_Close
+**
+** Description      Close UIPC interface
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern void UIPC_Close(tUIPC_CH_ID ch_id);
+
+/*******************************************************************************
+**
+** Function         UIPC_SendBuf
+**
+** Description      Called to transmit a message over UIPC.
+**                  Message buffer will be freed by UIPC_SendBuf.
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_SendBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg);
+
+/*******************************************************************************
+**
+** Function         UIPC_Send
+**
+** Description      Called to transmit a message over UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf, UINT16 msglen);
+
+/*******************************************************************************
+**
+** Function         UIPC_Read
+**
+** Description      Called to read a message from UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len);
+
+/*******************************************************************************
+**
+** Function         UIPC_Ioctl
+**
+** Description      Called to control UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+UDRV_API extern BOOLEAN UIPC_Ioctl(tUIPC_CH_ID ch_id, UINT32 request, void *param);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif  /* UIPC_H */
+
+
diff --git a/src/udrv/include/unv.h b/src/udrv/include/unv.h
new file mode 100755
index 0000000..7964021
--- /dev/null
+++ b/src/udrv/include/unv.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2002-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains NV definitions from WIDCOMM's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UNV_H
+#define UNV_H
+
+#include "data_types.h"
+
+/*******************************************************************************
+** NV APIs
+*******************************************************************************/
+
+/**** Storage preferences ****/
+#define UNV_BLOCK         1
+#define UNV_BYTE          2
+#define UNV_NOPREF        3
+
+typedef UINT8 tUNV_STORAGE_PREF;
+
+/**** Status ****/
+#define UNV_REINIT      (-1)
+#define UNV_WRITELOCKED (-2)
+#define UNV_ERROR       (-3)
+
+typedef INT16 tUNV_STATUS;
+
+/* Prototype for function to restore defaults to a block */
+typedef void  (tUNV_DEFAULT_FUNC)(void);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef UDRV_API
+#define UDRV_API
+#endif
+
+UDRV_API extern void        UNV_Init(void *);
+UDRV_API extern BOOLEAN     UNV_MapBlock(UINT16, tUNV_STORAGE_PREF, UINT16,
+                                         UINT16, UINT16 *, void *);
+UDRV_API extern BOOLEAN     UNV_ReadMap(UINT16, tUNV_STORAGE_PREF *, UINT16 *,
+                                        UINT16 *, UINT16 *);
+UDRV_API extern BOOLEAN     UNV_EraseBlock(UINT16);
+UDRV_API extern void        UNV_Default(UINT16);
+UDRV_API extern tUNV_STATUS UNV_Read(UINT16, UINT16, UINT16, UINT16, void *);
+UDRV_API extern tUNV_STATUS UNV_Write(UINT16, UINT16, UINT16, UINT16, void *);
+UDRV_API extern tUNV_STATUS UNV_ReadBlock(UINT16, UINT16, void *);
+UDRV_API extern tUNV_STATUS UNV_WriteBlock(UINT16, void *);
+UDRV_API extern UINT32      UNV_BytesRemaining(void);
+UDRV_API extern void        UNV_Consolidate(void);
+UDRV_API extern tUNV_STATUS UNV_ReadPtr(UINT16, UINT16, UINT8 **);
+UDRV_API extern tUNV_STATUS UNV_FreePtr(UINT16, UINT16);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UNV_H */
diff --git a/src/udrv/include/upio.h b/src/udrv/include/upio.h
new file mode 100755
index 0000000..41ac97c
--- /dev/null
+++ b/src/udrv/include/upio.h
@@ -0,0 +1,374 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Definitions for UPIO driver
+ *
+ ******************************************************************************/
+#ifndef UPIO_H
+#define UPIO_H
+
+#include "bt_target.h"
+
+/* Enumeration of UPIO features                                         */
+/* Not all features enumerated here are supported by the hardware.      */
+/* Use UPIO_Feature() to determine support of a particular feature.     */
+enum
+{
+    /* LEDs */
+    UPIO_FEAT_LED1,
+    UPIO_FEAT_LED2,
+    UPIO_FEAT_LED3,
+    UPIO_FEAT_LED4,
+    UPIO_FEAT_LED5,
+    UPIO_FEAT_LED6,
+    UPIO_FEAT_LED7,
+    UPIO_FEAT_LED8,
+
+    /* Switches */
+    UPIO_FEAT_SWITCH1,
+    UPIO_FEAT_SWITCH2,
+    UPIO_FEAT_SWITCH3,
+    UPIO_FEAT_SWITCH4,
+    UPIO_FEAT_SWITCH5,
+    UPIO_FEAT_SWITCH6,
+    UPIO_FEAT_SWITCH7,
+    UPIO_FEAT_SWITCH8,
+    UPIO_FEAT_SWITCH9,
+    UPIO_FEAT_SWITCH10,
+    UPIO_FEAT_SWITCH11,
+    UPIO_FEAT_SWITCH12,
+    UPIO_FEAT_SWITCH13,
+    UPIO_FEAT_SWITCH14,
+    UPIO_FEAT_SWITCH15,
+    UPIO_FEAT_SWITCH16,
+
+    /* Jumpers */
+    UPIO_FEAT_JUMPER1,
+    UPIO_FEAT_JUMPER2,
+    UPIO_FEAT_JUMPER3,
+    UPIO_FEAT_JUMPER4,
+    UPIO_FEAT_JUMPER5,
+    UPIO_FEAT_JUMPER6,
+    UPIO_FEAT_JUMPER7,
+    UPIO_FEAT_JUMPER8,
+
+    /* Push buttons */
+    UPIO_FEAT_BUTTON1,
+    UPIO_FEAT_BUTTON2,
+    UPIO_FEAT_BUTTON3,
+    UPIO_FEAT_BUTTON4,
+    UPIO_FEAT_BUTTON5,
+    UPIO_FEAT_BUTTON6,
+    UPIO_FEAT_BUTTON7,
+    UPIO_FEAT_BUTTON8,
+
+    /* General purpose */
+    UPIO_FEAT_GENERAL1,
+    UPIO_FEAT_GENERAL2,
+    UPIO_FEAT_GENERAL3,
+    UPIO_FEAT_GENERAL4,
+    UPIO_FEAT_GENERAL5,
+    UPIO_FEAT_GENERAL6,
+    UPIO_FEAT_GENERAL7,
+    UPIO_FEAT_GENERAL8,
+    UPIO_FEAT_GENERAL9,
+    UPIO_FEAT_GENERAL10,
+    UPIO_FEAT_GENERAL11,
+    UPIO_FEAT_GENERAL12,
+    UPIO_FEAT_GENERAL13,
+    UPIO_FEAT_GENERAL14,
+    UPIO_FEAT_GENERAL15,
+    UPIO_FEAT_GENERAL16,
+    UPIO_FEAT_GENERAL17,
+    UPIO_FEAT_GENERAL18,
+    UPIO_FEAT_GENERAL19,
+    UPIO_FEAT_GENERAL20,
+    UPIO_FEAT_GENERAL21,
+    UPIO_FEAT_GENERAL22,
+    UPIO_FEAT_GENERAL23,
+    UPIO_FEAT_GENERAL24,
+    UPIO_FEAT_GENERAL25,
+    UPIO_FEAT_GENERAL26,
+    UPIO_FEAT_GENERAL27,
+    UPIO_FEAT_GENERAL28,
+    UPIO_FEAT_GENERAL29,
+    UPIO_FEAT_GENERAL30,
+    UPIO_FEAT_GENERAL31,
+    UPIO_FEAT_GENERAL32,
+
+    UPIO_FEAT_IN_HIGH,          /* Support for input with interrupt on high signal level. */
+    UPIO_FEAT_IN_LOW,           /* Support for input with interrupt on low signal level. */
+    UPIO_FEAT_IN_RISE,          /* Support for input with interrupt on rising edge. */
+    UPIO_FEAT_IN_FALL           /* Support for input with interrupt on falling. */
+
+};
+typedef UINT8 tUPIO_FEATURE;
+
+
+/* Enumeration of UPIO configurations */
+enum
+{
+    UPIO_OUT,
+    UPIO_IN,
+    UPIO_IN_EDGE,
+    UPIO_IN_LEVEL,
+    UPIO_NONE
+};
+typedef UINT8 tUPIO_CONFIG;
+
+
+/* Enumeration of UPIO types */
+enum
+{
+    UPIO_LED,                   /* LED */
+    UPIO_SWITCH,                /* Switch */
+    UPIO_JUMPER,                /* Jumper */
+    UPIO_BUTTON,                /* Push-button switch */
+    UPIO_GENERAL,               /* General purpose I/O */
+
+    UPIO_NUMBER_OF_TYPES
+};
+typedef UINT8 tUPIO_TYPE;
+
+
+/* Enumeration of UPIO states */
+enum
+{
+    UPIO_OFF,
+    UPIO_ON,
+    UPIO_TOGGLE
+};
+typedef UINT8 tUPIO_STATE;
+
+
+enum
+{
+    UPIO_SW_BANK2,
+    UPIO_SW_BANK3
+};
+typedef UINT8 tUPIO_SW_BANK;
+
+/* Jumper masks */
+#define UPIO_JUMPER1    0x00000001
+#define UPIO_JUMPER2    0x00000002
+#define UPIO_JUMPER3    0x00000004
+#define UPIO_JUMPER4    0x00000008
+#define UPIO_JUMPER5    0x00000010
+#define UPIO_JUMPER6    0x00000020
+#define UPIO_JUMPER7    0x00000040
+#define UPIO_JUMPER8    0x00000080
+
+/* General purpose i/o masks */
+#define UPIO_GENERAL1   0x00000001
+#define UPIO_GENERAL2   0x00000002
+#define UPIO_GENERAL3   0x00000004
+#define UPIO_GENERAL4   0x00000008
+#define UPIO_GENERAL5   0x00000010
+#define UPIO_GENERAL6   0x00000020
+#define UPIO_GENERAL7   0x00000040
+#define UPIO_GENERAL8   0x00000080
+#define UPIO_GENERAL9   0x00000100
+#define UPIO_GENERAL10  0x00000200
+#define UPIO_GENERAL11  0x00000400
+#define UPIO_GENERAL12  0x00000800
+#define UPIO_GENERAL13  0x00001000
+#define UPIO_GENERAL14  0x00002000
+#define UPIO_GENERAL15  0x00004000
+#define UPIO_GENERAL16  0x00008000
+#define UPIO_GENERAL17  0x00010000
+#define UPIO_GENERAL18  0x00020000
+#define UPIO_GENERAL19  0x00040000
+#define UPIO_GENERAL20  0x00080000
+#define UPIO_GENERAL21  0x00100000
+#define UPIO_GENERAL22  0x00200000
+#define UPIO_GENERAL23  0x00400000
+#define UPIO_GENERAL24  0x00800000
+#define UPIO_GENERAL25  0x01000000
+#define UPIO_GENERAL26  0x02000000
+#define UPIO_GENERAL27  0x04000000
+#define UPIO_GENERAL28  0x08000000
+#define UPIO_GENERAL29  0x10000000
+#define UPIO_GENERAL30  0x20000000
+#define UPIO_GENERAL31  0x40000000
+#define UPIO_GENERAL32  0x80000000
+
+typedef UINT32 tUPIO;
+
+/* LED masks */
+#define UPIO_LED1       0x00000001
+#define UPIO_LED2       0x00000002
+#define UPIO_LED3       0x00000004
+#define UPIO_LED4       0x00000008
+#define UPIO_LED5       0x00000010
+#define UPIO_LED6       0x00000020
+#define UPIO_LED7       0x00000040
+#define UPIO_LED8       0x00000080
+
+#define UPIO_LED_ALL    (UPIO_LED1 | UPIO_LED2 | UPIO_LED3 | UPIO_LED4 | \
+                        UPIO_LED5 | UPIO_LED6 | UPIO_LED7 | UPIO_LED8)
+
+
+/* Switch masks */
+#define UPIO_SWITCH1    0x00000001
+#define UPIO_SWITCH2    0x00000002
+#define UPIO_SWITCH3    0x00000004
+#define UPIO_SWITCH4    0x00000008
+#define UPIO_SWITCH5    0x00000010
+#define UPIO_SWITCH6    0x00000020
+#define UPIO_SWITCH7    0x00000040
+#define UPIO_SWITCH8    0x00000080
+#define UPIO_SWITCH9    0x00000100
+#define UPIO_SWITCH10   0x00000200
+#define UPIO_SWITCH11   0x00000400
+#define UPIO_SWITCH12   0x00000800
+#define UPIO_SWITCH13   0x00001000
+#define UPIO_SWITCH14   0x00002000
+#define UPIO_SWITCH15   0x00004000
+#define UPIO_SWITCH16   0x00008000
+
+/* Push button masks */
+#define UPIO_BUTTON1    0x00000001
+#define UPIO_BUTTON2    0x00000002
+#define UPIO_BUTTON3    0x00000004
+#define UPIO_BUTTON4    0x00000008
+#define UPIO_BUTTON5    0x00000010
+#define UPIO_BUTTON6    0x00000020
+#define UPIO_BUTTON7    0x00000040
+#define UPIO_BUTTON8    0x00000080
+
+typedef void (tUPIO_CBACK)(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* API functions for UPIO driver */
+
+/*****************************************************************************
+**
+** Function         UPIO_Init
+**
+** Description
+**      Initialize the GPIO service.
+**      This function is typically called once upon system startup.
+**
+** Returns          nothing
+**
+*****************************************************************************/
+UDRV_API void UPIO_Init(void *p_cfg);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Set
+**
+** Description
+**      This function sets one or more GPIO devices to the given state.
+**      Multiple GPIOs of the same type can be masked together to set more
+**      than one GPIO. This function can only be used on types UPIO_LED and
+**      UPIO_GENERAL.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      state   The desired state.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE state);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Read
+**
+** Description
+**      Read the state of a GPIO. This function can be used for any type of
+**      device. Parameter pio can only indicate a single GPIO; multiple GPIOs
+**      cannot be masked together.
+**
+** Input Parameters:
+**      Type:	The type of device.
+**      pio:    Indicates the particular GUPIO.
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      State of GPIO (UPIO_ON or UPIO_OFF).
+**
+*****************************************************************************/
+UDRV_API tUPIO_STATE UPIO_Read(tUPIO_TYPE type, tUPIO pio);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Config
+**
+** Description      - Configure GPIOs of type UPIO_GENERAL as inputs or outputs
+**                  - Configure GPIOs to be polled or interrupt driven
+**
+**                  Currently only support polled GPIOs.
+**
+** Input Parameters:
+**      type    The type of device.
+**      pio     Indicates the particular GPIOs.
+**      config
+**      cback
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Config(tUPIO_TYPE type, tUPIO pio, tUPIO_CONFIG config, tUPIO_CBACK *cback);
+
+
+/*****************************************************************************
+**
+** Function         UPIO_Feature
+**
+** Description
+**      Checks whether a feature of the pio API is supported
+**
+** Input Parameter:
+**      feature     The feature to check
+**
+** Output Parameter:
+**      None.
+**
+** Returns:
+**      TRUE if feature is supported, FALSE if it is not.
+**
+*****************************************************************************/
+UDRV_API BOOLEAN UPIO_Feature(tUPIO_FEATURE feature);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* ifdef UPIO_H */
diff --git a/src/udrv/include/usb.h b/src/udrv/include/usb.h
new file mode 100755
index 0000000..c9ecda0
--- /dev/null
+++ b/src/udrv/include/usb.h
@@ -0,0 +1,232 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains serial definitions from WIDCOMM's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef USB_H
+#define USB_H
+
+/*******************************************************************************
+** Serial APIs
+*******************************************************************************/
+
+/**** port IDs ****/
+#define USB_PORT_1            0
+#define USB_PORT_2            1
+#define USB_PORT_3            2
+#define USB_PORT_4            3
+
+typedef UINT8 tUSB_PORT;
+
+/**** baud rates ****/
+#define USB_BAUD_300          0
+#define USB_BAUD_600          1
+#define USB_BAUD_1200         2
+#define USB_BAUD_2400         3
+#define USB_BAUD_9600         4
+#define USB_BAUD_19200        5
+#define USB_BAUD_57600        6
+#define USB_BAUD_115200       7
+#define USB_BAUD_230400       8
+#define USB_BAUD_460800       9
+#define USB_BAUD_921600       10
+#define USB_BAUD_AUTO         11
+
+/**** Data Format ****/
+
+/* Stop Bits */
+#define USB_STOPBITS_1        1
+#define USB_STOPBITS_1_5      (1<<1)
+#define USB_STOPBITS_2        (1<<2)
+
+/* Parity Bits */
+#define USB_PARITY_NONE       (1<<3)
+#define USB_PARITY_EVEN       (1<<4)
+#define USB_PARITY_ODD        (1<<5)
+
+/* Data Bits */
+#define USB_DATABITS_5        (1<<6)
+#define USB_DATABITS_6        (1<<7)
+#define USB_DATABITS_7        (1<<8)
+#define USB_DATABITS_8        (1<<9)
+
+
+/**** Flow Control ****/
+#define USB_FC_NONE           0
+#define USB_FC_HW             1
+#define USB_FC_SW             2
+
+/**** Data Buffering Mechanism ****/
+#define USB_BUF_BYTE          0
+#define USB_BUF_GKI           1
+
+/**** Signals ****/
+#define USB_SIG_RTSCTS        1
+#define USB_SIG_DSRDTR        (1<<1)
+#define USB_SIG_RI            (1<<2)
+#define USB_SIG_CD            (1<<3)
+#define USB_SIG_DTE_DEVICE    (1<<4)
+
+/**** Errors *****/
+#define USB_ERR_OVERRUN       1
+#define USB_ERR_PARITY        (1<<1)
+#define USB_ERR_FRAMING       (1<<2)
+#define USB_ERR_BREAK         (1<<3)
+
+/**** Serial Operations ****/
+#define USB_OP_FLUSH          0
+#define USB_OP_FLUSH_RX       1
+#define USB_OP_FLUSH_TX       2
+#define USB_OP_BREAK_OFF      3
+#define USB_OP_BREAK_ON       4
+#define USB_OP_BAUD_RD        5
+#define USB_OP_BAUD_WR        6
+#define USB_OP_FMT_RD         7
+#define USB_OP_FMT_WR         8
+#define USB_OP_SIG_RD         9
+#define USB_OP_SIG_WR         10
+#define USB_OP_FC_RD          11
+#define USB_OP_FC_WR          12
+
+typedef UINT8 tUSB_OP;
+
+
+/**** Serial feature types ****/
+#define USB_FEAT_PORT_1       0
+#define USB_FEAT_PORT_2       1
+#define USB_FEAT_PORT_3       2
+#define USB_FEAT_PORT_4       3
+#define USB_FEAT_BAUD_AUTO    4
+#define USB_FEAT_BAUD_300     5
+#define USB_FEAT_BAUD_600     6
+#define USB_FEAT_BAUD_1200    7
+#define USB_FEAT_BAUD_2400    8
+#define USB_FEAT_BAUD_9600    9
+#define USB_FEAT_BAUD_19200   10
+#define USB_FEAT_BAUD_57600   11
+#define USB_FEAT_BAUD_115200  12
+#define USB_FEAT_BAUD_230400  13
+#define USB_FEAT_BAUD_460800  14
+#define USB_FEAT_BAUD_921600  15
+#define USB_FEAT_STOPBITS_1   16
+#define USB_FEAT_STOPBITS_1_5 17
+#define USB_FEAT_STOPBITS_2   18
+#define USB_FEAT_PARITY_NONE  19
+#define USB_FEAT_PARITY_EVEN  20
+#define USB_FEAT_PARITY_ODD   21
+#define USB_FEAT_DATABITS_5   22
+#define USB_FEAT_DATABITS_6   23
+#define USB_FEAT_DATABITS_7   24
+#define USB_FEAT_DATABITS_8   25
+#define USB_FEAT_FC_NONE      26
+#define USB_FEAT_FC_HW        27
+#define USB_FEAT_FC_SW        28
+#define USB_FEAT_BUF_BYTE     29
+#define USB_FEAT_BUF_GKI      30
+#define USB_FEAT_SIG_RTS      31
+#define USB_FEAT_SIG_CTS      32
+#define USB_FEAT_SIG_DSR      33
+#define USB_FEAT_SIG_DTR      34
+#define USB_FEAT_SIG_RI       35
+#define USB_FEAT_SIG_CD       36
+#define USB_FEAT_OP_FLUSH     37
+#define USB_FEAT_OP_FLUSH_RX  38
+#define USB_FEAT_OP_FLUSH_TX  39
+#define USB_FEAT_OP_BREAK     40
+#define USB_FEAT_OP_BAUD_RD   41
+#define USB_FEAT_OP_BAUD_WR   42
+#define USB_FEAT_OP_FMT_RD    43
+#define USB_FEAT_OP_FMT_WR    44
+#define USB_FEAT_OP_SIG_RD    45
+#define USB_FEAT_OP_SIG_WR    46
+#define USB_FEAT_OP_FC_RD     47
+#define USB_FEAT_OP_FC_WR     48
+
+typedef UINT8 tUSB_FEATURE;
+
+
+/**** Event types ****/
+#define USB_RX_READY_EVT      0
+#define USB_TX_DONE_EVT       1
+#define USB_SIG_EVT           2
+#define USB_ERR_EVT           3
+
+typedef UINT8 tUSB_EVT;
+
+
+/* Structure used to configure serial port during open        */
+typedef struct
+{
+    UINT16 fmt;          /* Data format                       */
+    UINT8  baud;         /* Baud rate                         */
+    UINT8  fc;           /* Flow control                      */
+    UINT8  buf;          /* Data buffering mechanism          */
+    UINT8  pool;         /* GKI buffer pool for received data */
+    UINT16 size;         /* Size of GKI buffer pool           */
+    UINT16 offset;       /* Offset in GKI buffer pool         */
+} tUSB_OPEN_CFG;
+
+/* Union used to pass ioctl arguments */
+typedef union
+{
+    UINT16 fmt;
+    UINT8  baud;
+    UINT8  fc;
+    UINT8  sigs;
+} tUSB_IOCTL_DATA;
+
+
+/* Union to pass event data */
+typedef union
+{
+    UINT8 sigs;
+    UINT8 error;
+} tUSB_EVT_DATA;
+
+/* callback for events */
+typedef void (tUSB_CBACK)(tUSB_PORT, tUSB_EVT, tUSB_EVT_DATA *);
+
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void    USB_Init(void *);
+UDRV_API extern void    USB_Open(tUSB_PORT, tUSB_OPEN_CFG *, tUSB_CBACK *);
+UDRV_API extern void    USB_ReadBuf(tUSB_PORT, BT_HDR **);
+UDRV_API extern UINT16  USB_Read(tUSB_PORT, UINT8 *, UINT16);
+UDRV_API extern BOOLEAN USB_WriteBuf(tUSB_PORT, BT_HDR *);
+UDRV_API extern UINT16  USB_Write(tUSB_PORT, UINT8 *, UINT16);
+UDRV_API extern void    USB_Ioctl(tUSB_PORT, tUSB_OP, tUSB_IOCTL_DATA *);
+UDRV_API extern void    USB_Close(tUSB_PORT);
+UDRV_API extern BOOLEAN USB_Feature(tUSB_FEATURE);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USB_H */
diff --git a/src/udrv/include/utimer.h b/src/udrv/include/utimer.h
new file mode 100755
index 0000000..a663ad7
--- /dev/null
+++ b/src/udrv/include/utimer.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains timer definitions from WIDCOMM's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UTIMER_H
+#define UTIMER_H
+
+/*******************************************************************************
+** Timer APIs
+*******************************************************************************/
+
+/**** Timer IDs ****/
+
+#define UTIMER_ID_1               0
+#define UTIMER_ID_2               1
+#define UTIMER_ID_3               2
+#define UTIMER_ID_4               3
+
+#define UTIMER_NUM_TIMERS         4     /* Number of timers supported */
+
+typedef UINT8 tUTIMER_ID;
+
+/**** Timer types ****/
+
+#define UTIMER_TYPE_PERIODIC      0
+#define UTIMER_TYPE_ONESHOT       1
+
+typedef UINT8 tUTIMER_TYPE;
+
+
+/**** Timer time ****/
+
+typedef UINT32 tUTIMER_TIME;
+
+
+/**** Timer configuration ****/
+
+typedef struct
+{
+    tUTIMER_TIME period;
+    tUTIMER_TYPE type;
+} tUTIMER_CFG;
+
+
+/**** Timer feature types ****/
+#define UTIMER_FEAT_ID_1          0
+#define UTIMER_FEAT_ID_2          1
+#define UTIMER_FEAT_ID_3          2
+#define UTIMER_FEAT_ID_4          3
+#define UTIMER_FEAT_TYPE_PERIODIC 4
+#define UTIMER_FEAT_TYPE_ONESHOT  5
+
+typedef UINT8 tUTIMER_FEATURE;
+
+
+/**** Callback for timer expiration ****/
+typedef void (tUTIMER_CBACK)(tUTIMER_ID);
+
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void    UTIMER_Init(void *);
+UDRV_API extern void    UTIMER_Start(tUTIMER_ID, tUTIMER_CFG *, tUTIMER_CBACK *);
+UDRV_API extern void    UTIMER_Read(tUTIMER_ID, tUTIMER_TIME *);
+UDRV_API extern void    UTIMER_Stop(tUTIMER_ID);
+UDRV_API extern BOOLEAN UTIMER_Feature(tUTIMER_FEATURE);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UTIMER_H */
diff --git a/src/udrv/include/uusb.h b/src/udrv/include/uusb.h
new file mode 100755
index 0000000..590a8fa
--- /dev/null
+++ b/src/udrv/include/uusb.h
@@ -0,0 +1,290 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains usb definitions from Widcomm's Universal Embedded
+ *  Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef UUSB_H
+#define UUSB_H
+
+#include "bt_target.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*******************************************************************************
+** Codec APIs
+*******************************************************************************/
+
+
+/**** Status ****/
+#define UUSB_SUCCESS                                  0
+#define UUSB_DRV_INVALID_PARM                         1   // Invalid parameter(s) passed to Driver
+#define UUSB_DRV_INVALID_STATE                        2   // Driver is not in correct state to accept
+#define UUSB_DRV_UNSUPPORTED_SETUP_REQ                3   // Unsupported SETUP request (use with tUSER_EP0_SETUP_CB)
+#define UUSB_DRV_NO_BUFFER_AVAILABLE                  4   // User cannot provide a Buffer (use with CB functions)
+
+typedef UINT8 tUUSB_STATUS;
+
+
+#define  UUSB_EP1   0
+#define  UUSB_EP2   1
+#define  UUSB_EP3   2
+#define  UUSB_EP4   3
+#define  UUSB_EP5   4
+#define  UUSB_EP6   5
+#define  UUSB_EP7   6
+
+typedef UINT8 tUUSB_EP_ID;
+
+typedef enum {
+  UUSB_EP_TYPE_CONTROL = 0,
+  UUSB_EP_TYPE_ISOCHRONOUS,
+  UUSB_EP_TYPE_BULK,
+  UUSB_EP_TYPE_INTERRUPT
+} tUUSB_EP_TYPE;
+
+typedef enum {
+  UUSB_DIR_OUT = 0,
+  UUSB_DIR_IN
+} tUUSB_EP_DIRECTION;
+
+typedef struct tUUSB_SETUP_PKTTag
+{
+/* Definition of "USBbmRequestType" */
+#define UUSB_DATA_PHASE_DIR      0x80    /* Mask to get data phase transfer direction */
+#define UUSB_HOST_TO_DEVICE      0x00    /* Data transfer directions */
+#define UUSB_DEVICE_TO_HOST      0x80    /* Data transfer directions */
+/* Types of requests */
+#define UUSB_REQUEST_TYPE		0x60	/* Mask to get request type */
+#define UUSB_STANDARD_REQUEST	0x00	/* Standard request */
+#define	UUSB_CLASS_REQUEST		0x20	/* Class request */
+#define	UUSB_VENDOR_REQUEST		0x40	/* Vendor request */
+  UINT8 bmRequestType;
+  UINT8 bRequest;
+  UINT16 wValue;
+  UINT16 wIndex;
+  UINT16 wLength;
+} tUUSB_SETUP_PKT;
+
+typedef union
+{
+#define UUSB_HEAD_SIZE (8)
+	UINT8           HeadBytes[UUSB_HEAD_SIZE];
+    tUUSB_SETUP_PKT Setup;
+} tSETUP_OR_HEAD;
+
+typedef struct
+{
+  UINT8        BufSize;
+  UINT8        NumBytesInBuf;
+  tSETUP_OR_HEAD Buf;
+} tUUSB_RX_HEAD;
+
+typedef enum
+{
+  UUSB_EP_DISABLE,
+  UUSB_EP_ENABLE,
+  UUSB_EP_STALL
+} tUUSB_EP_STATE;
+
+typedef UINT8 tEndPoint;
+
+#if 0
+#define  UUSB_ATTACHED      0
+#define  UUSB_POWERED       1
+#define  UUSB_DEFAULT       2
+#define  UUSB_ADDRESS       3
+#define  UUSB_CONFIGURED    4
+#define  UUSB_SUSPENDED     5
+
+typedef UINT8 tUUSB_BUS_STATE;
+#else
+typedef enum
+{
+  UUSB_ATTACHED,
+  UUSB_POWERED,
+  UUSB_DEFAULT,
+  UUSB_ADDRESS,
+  UUSB_CONFIGURED,
+  UUSB_SUSPENDED
+} tUUSB_BUS_STATE;
+#endif
+
+typedef enum _tUUSB_STANDART_REQ
+{
+	UUSB_GET_STATUS = 0,
+	UUSB_CLEAR_FEATURE,
+	UUSB_RESERVED1,
+	UUSB_SET_FEATURE,
+	UUSB_RESERVED2,
+	UUSB_SET_ADDRESS,
+	UUSB_GET_DESCRIPTOR,
+	UUSB_SET_DESCRIPTOR,
+	UUSB_GET_CONFIGURATION,
+	UUSB_SET_CONFIGURATION,
+	UUSB_GET_INTERFACE,
+	UUSB_SET_INTERFACE,
+	UUSB_TOTAL_sREQUEST,				/* Total number of Standard request */
+	UUSB_SYNCH_FRAME = 12
+} tUUSB_STANDART_REQ;
+
+
+typedef void (*tUUSB_STATE_CB)          (tUUSB_BUS_STATE State);
+typedef void (*tUUSB_PROT_COMPLETE_CB ) (UINT8 *pBuf,UINT16 NumBytesInBuf);
+
+typedef tUUSB_STATUS (*tUUSB_PROT_SETUP_CB ) (UINT8 **ppBuf,UINT16 *pBufSize);
+
+typedef void (*tUUSB_RX_START_CB )      (tUUSB_EP_ID EndPoint,
+                                        UINT8 **ppBuf,
+                                        UINT16 *pBufSize);
+
+typedef void (*tUUSB_RX_COMPLETE_CB )   (tUUSB_EP_ID EndPoint,
+                                        UINT8 *pRxBuf,
+                                        UINT16 NumBytesInBuf);
+
+typedef void (*tUUSB_TX_COMPLETE_CB )   (tUUSB_EP_ID EndPoint,
+                                        UINT8 *pRxBuf);
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+/******************************************************************************
+**
+** Function         UCODEC_Init
+**
+** Description      Startup initialisation function. This function is called
+**                  before any orther function of UUSB it initialize UUSB
+**                  internal structure an the external hw.
+**
+**                  Input :
+**
+**                  Output Parameters :
+**
+** Returns          UUSB_SUCCESS if The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS    UUSB_Init    (tUUSB_PROT_SETUP_CB       userProtSetupCallBack,
+                                            tUUSB_PROT_COMPLETE_CB    userProtCompleteCallBack,
+                                            tUUSB_RX_START_CB         userRxStartCallBack,
+                                            tUUSB_STATE_CB            userStateCallBack,
+                                            tUUSB_TX_COMPLETE_CB      userTxCompleteCallBack,
+                                            tUUSB_RX_COMPLETE_CB      userRxCompleteCallBack);
+
+
+
+
+/******************************************************************************
+**
+** Function         UUSB_Start
+**
+** Description
+**
+**
+**
+**
+**
+** Returns          UUSB_SUCCESS if The action was performed with sucess.
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS    UUSB_Start  (void);
+
+/******************************************************************************
+**
+** Function         UUSB_Stop
+**
+** Description
+**
+**
+**
+**
+** Returns          UUSB_SUCCESS if The action was performed with sucess.
+**                  Error code else.
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS    UUSB_Stop      (void);
+
+/******************************************************************************
+**
+** Function         UUSB_SetEndPointCnf
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS    UUSB_SetEndPointCnf ( BOOLEAN         IsIN_EndPoint,
+                                                    tUUSB_EP_ID     EndPoint,
+                                                    UINT8           MaxPacketSize,
+                                                    tUUSB_EP_TYPE   EndPointType,
+                                                    tUUSB_RX_HEAD   *pRxHead,
+                                                    UINT16          RxTimeOut);
+
+
+/******************************************************************************
+**
+** Function         UUSB_SetEndPointState
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_SetEndPointState (tUUSB_EP_ID    EndPoint,
+                                                    tUUSB_EP_STATE EndPointState);
+
+/******************************************************************************
+**
+** Function         UUSB_WriteEndPoint
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_WriteEndPoint (tUUSB_EP_ID     EndPoint,
+                                                UINT16     Length,
+                                                UINT8*    pBuf);
+
+/******************************************************************************
+**
+** Function         UUSB_GenerateRemoteWakeUp
+**
+** Description
+**
+**
+** Returns
+**
+******************************************************************************/
+BT_API extern tUUSB_STATUS UUSB_GenerateRemoteWakeUp (void);
+
+#ifdef __cplusplus
+};
+#endif
+
+
+#endif /* UUSB_H */