NFC: Merge branch 'caf/caf/nxpnfc-project/br_android_ncihalx_o' into nfc.lnx.3.1

* caf/caf/nxpnfc-project/br_android_ncihalx_o: (66 commits)
  NFC_NCIHALx_AR003C.8.3.0_O_OpnSrc
  MW version updated to 8.3.0
  NFC_NCIHALx_AR0054.8.3.0_O_OpnSrc
  MW version updated to 8.3.0
  Switching NFCC clock source from XTAL to PLL is not working.
  Update README.md
  NFC_NCIHALx_AR180C.8.3.0_O_OpnSrc
  MW version updated to 8.3.0
  MW version updated to 8.2.B
  MW version updated to 8.2.A
  Added GKI error prints
  Fix for selftest failures on android O
  Fix for Model ID print issue
  Selftest Single binary improvements
  Add Lx Debug decoding information
  MW version updated to 8.2.9
  Fix for UICC detection issue after FW download
  MW version updated to 8.2.8
  Fix for selfTest application cr*sh due to HAL library path mismatch
  Observing NFC Init success with Model ID mismatch
  ...

Change-Id: Ie0682fda686cf41c97e9f925318672f0cbd3c5ec
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 7d7287a..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,61 +0,0 @@
-subdirs = ["src"]
-cc_library_shared {
-    name: "nfc_nci.pn54x",
-    proprietary: true,
-    relative_install_path: "hw",
-    srcs: [
-        "halimpl/pn54x/common/*.c",
-        "halimpl/pn54x/dnld/*.c",
-        "halimpl/pn54x/hal/*.c",
-        "halimpl/pn54x/log/*.c",
-        "halimpl/pn54x/self-test/*.c",
-        "halimpl/pn54x/tml/*.c",
-        "halimpl/pn54x/utils/*.c",
-        "halimpl/pn54x/utils/*.cpp",
-        "halimpl/pn54x/configs/*.cpp",
-        "halimpl/pn54x/nfc_nci.c"
-    ],
-    shared_libs: [
-        "libcutils",
-         "liblog",
-        "libhwbinder",
-        "libhardware",
-    ],
-    local_include_dirs: [
-        "halimpl/pn54x/inc",
-        "halimpl/pn54x/common",
-        "halimpl/pn54x/dnld",
-        "halimpl/pn54x/hal",
-        "halimpl/pn54x/log",
-        "halimpl/pn54x/self-test",
-        "halimpl/pn54x/tml",
-        "halimpl/pn54x/utils",
-        "halimpl/pn54x/configs",
-        "src/hal/include",
-        "src/hal/int",
-        "src/nfc/include",
-        "src/nfa/include",
-        "src/udrv/include",
-        "src/include",
-        "src/gki/ulinux/",
-        "src/gki/common/",
-    ],
-    include_dirs: [
-        "vendor/nxp/opensource/hardware/interfaces/nxpnfc/1.0/default/",
-    ],
-    cflags: [
-        "-DBUILDCFG=1",
-        "-Wno-deprecated-register",
-        "-Wno-unused-parameter",
-        "-Wno-missing-field-initializers",
-        "-DNFC_HAL_TARGET=TRUE",
-        "-DNFC_RW_ONLY=TRUE",
-        "-DNXP_EXTNS=TRUE",
-        "-DNFC_NXP_AID_MAX_SIZE_DYN=TRUE",
-        "-DNXP_NFCC_HCE_F=TRUE",
-        "-DNFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION=TRUE",
-        "-DNFC_NXP_HFO_SETTINGS=FALSE",
-        "-DANDROID",
-        "-DNXP_HW_SELF_TEST"
-    ],
-}
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..dc58037
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,140 @@
+ifeq ($(strip $(TARGET_USES_NQ_NFC)),true)
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+NFA := src/nfa
+NFC := src/nfc
+HAL := src/hal
+UDRV := src/udrv
+
+D_CFLAGS := -DANDROID -DBUILDCFG=1 \
+    -Wno-deprecated-register \
+    -Wno-unused-parameter \
+
+#Enable NXP Specific
+D_CFLAGS += -DNXP_EXTNS=TRUE
+D_CFLAGS += -DNFC_NXP_STAT_DUAL_UICC_EXT_SWITCH=FALSE
+D_CFLAGS += -DNFC_NXP_AID_MAX_SIZE_DYN=TRUE
+
+#Enable HCE-F specific
+D_CFLAGS += -DNXP_NFCC_HCE_F=TRUE
+
+#variables for NFC_NXP_CHIP_TYPE
+PN547C2 := 1
+PN548C2 := 2
+PN551   := 3
+PN553   := 4
+PN557   := 5
+
+ifeq ($(PN547C2),1)
+D_CFLAGS += -DPN547C2=1
+endif
+ifeq ($(PN548C2),2)
+D_CFLAGS += -DPN548C2=2
+endif
+ifeq ($(PN551),3)
+D_CFLAGS += -DPN551=3
+endif
+ifeq ($(PN553),4)
+D_CFLAGS += -DPN553=4
+endif
+ifeq ($(PN557),5)
+D_CFLAGS += -DPN557=5
+endif
+
+#### Select the JCOP OS Version ####
+JCOP_VER_3_1 := 1
+JCOP_VER_3_2 := 2
+JCOP_VER_3_3 := 3
+JCOP_VER_4_0 := 4
+
+LOCAL_CFLAGS += -DJCOP_VER_3_1=$(JCOP_VER_3_1)
+LOCAL_CFLAGS += -DJCOP_VER_3_2=$(JCOP_VER_3_2)
+LOCAL_CFLAGS += -DJCOP_VER_3_3=$(JCOP_VER_3_3)
+LOCAL_CFLAGS += -DJCOP_VER_4_0=$(JCOP_VER_4_0)
+
+NFC_NXP_ESE:= TRUE
+ifeq ($(NFC_NXP_ESE),TRUE)
+LOCAL_CFLAGS += -DNFC_NXP_ESE=TRUE
+LOCAL_CFLAGS += -DNFC_NXP_ESE_VER=$(JCOP_VER_4_0)
+else
+LOCAL_CFLAGS += -DNFC_NXP_ESE=FALSE
+endif
+
+ifeq ($(call is-board-platform-in-list,msm8909w msm8916 msm8994 msm8909 msm8996 msm8992 msm8952 msm8937 msm8953 msm8998),true)
+D_CFLAGS += -DNQ_NFC_DUAL_UICC=FALSE
+else
+D_CFLAGS += -DNQ_NFC_DUAL_UICC=TRUE
+endif
+
+#### Select the CHIP ####
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+NXP_CHIP_TYPE := $(PN553)
+else
+NXP_CHIP_TYPE := $(PN548C2)
+endif
+
+ifeq ($(NXP_CHIP_TYPE),$(PN547C2))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN547C2
+else ifeq ($(NXP_CHIP_TYPE),$(PN548C2))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2
+else ifeq ($(NXP_CHIP_TYPE),$(PN551))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN551
+else ifeq ($(NXP_CHIP_TYPE),$(PN553))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553
+else ifeq ($(NXP_CHIP_TYPE),$(PN557))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN557
+endif
+
+#Gemalto SE support
+D_CFLAGS += -DGEMALTO_SE_SUPPORT
+D_CFLAGS += -DNXP_UICC_ENABLE
+ifeq ($(NXP_CHIP_TYPE),$(PN553))
+D_CFLAGS += -DJCOP_WA_ENABLE=FALSE
+else
+D_CFLAGS += -DJCOP_WA_ENABLE=TRUE
+endif
+
+#Routing Entries optimization
+D_CFLAGS += -DNFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION=TRUE
+######################################
+# Build shared library system/lib/libnfc-nci.so for stack code.
+
+LOCAL_ARM_MODE := arm
+ifeq (true,$(TARGET_IS_64_BIT))
+LOCAL_MULTILIB := 64
+else
+LOCAL_MULTILIB := 32
+endif
+LOCAL_MODULE := libnqnfc-nci
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := nxp
+LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils liblog libdl libhardware
+LOCAL_CFLAGS += $(D_CFLAGS)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/include \
+    $(LOCAL_PATH)/src/gki/ulinux \
+    $(LOCAL_PATH)/src/gki/common \
+    $(LOCAL_PATH)/$(NFA)/include \
+    $(LOCAL_PATH)/$(NFA)/int \
+    $(LOCAL_PATH)/$(NFC)/include \
+    $(LOCAL_PATH)/$(NFC)/int \
+    $(LOCAL_PATH)/src/hal/include \
+    $(LOCAL_PATH)/src/hal/int \
+    $(LOCAL_PATH)/$(HALIMPL)/include \
+    system/libhwbinder/include
+
+# Treble configuration
+LOCAL_SHARED_LIBRARIES += libhidlbase libhidltransport libhwbinder libutils android.hardware.nfc@1.0 vendor.nxp.hardware.nfc@1.0
+LOCAL_SRC_FILES := \
+    $(call all-c-files-under, $(NFA)/ce $(NFA)/dm $(NFA)/ee) \
+    $(call all-c-files-under, $(NFA)/hci $(NFA)/int $(NFA)/p2p $(NFA)/rw $(NFA)/sys) \
+    $(call all-c-files-under, $(NFC)/int $(NFC)/llcp $(NFC)/nci $(NFC)/ndef $(NFC)/nfc $(NFC)/tags) \
+    $(call all-c-files-under, src/adaptation) \
+    $(call all-cpp-files-under, src/adaptation) \
+    $(call all-c-files-under, src/gki) \
+    src/nfca_version.c
+include $(BUILD_SHARED_LIBRARY)
+
+
+######################################
+include $(call all-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/CleanSpec.mk b/CleanSpec.mk
index e051104..cf3a247 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -43,7 +43,7 @@
 #$(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)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libnqnfc-nci_intermediates)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/README.md b/README.md
index 9978c5a..8491caa 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 ####Git Repository
 
 | DESCRIPTION        | CHECKOUT COMMAND          |
-|:-------------:|:-------------:| 
+|:-------------:|:-------------:|
 | NFC_NCIHAL_libnfc-nci     |  git clone https://github.com/NXPNFCProject/NFC_NCIHAL_libnfc-nci.git |
 
 ####Supported Versions on "master" Branch
diff --git a/README.md~ b/README.md~
new file mode 100644
index 0000000..ffa039d
--- /dev/null
+++ b/README.md~
@@ -0,0 +1,29 @@
+#NFC_NCIHAL_libnfc-nci
+
+####Git Repository
+
+| DESCRIPTION        | CHECKOUT COMMAND          |
+|:-------------:|:-------------:| 
+| NFC_NCIHAL_libnfc-nci     |  git clone https://github.com/NXPNFCProject/NFC_NCIHAL_libnfc-nci.git |
+
+####Supported Versions on "master" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-5.0.0_r1/android5.1.0_r1     |  3.5.0_L (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.3.5.0_L_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_m" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-6.0.0_r1                     |  4.2.0_M (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.4.2.0_M_OpnSrc |
+| android-6.0.0_r1                     |  4.3.0_M (PN547C2/PN548C2) |  NFC_NCIHALx_AR0F.4.3.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.5.0_M (PN551/PN548C2)   |  NFC_NCIHALx_AR3C.4.5.0_M_OpnSrc |
+| android-6.0.1_r17                    |  4.7.0_M (PN553)   |  NFC_NCIHALx_ARC0.4.7.0_M_OpnSrc |
+
+####Supported Versions on "br_android_ncihalx_n" Branch
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-7.0.0_r1                     |  7.0.3_N (PN548C2/PN551) |  NFC_NCIHALx_AR3C.7.0.3_N_OpnSrc |
+| android-7.0.0_r4                     |  7.0.4_N (PN553) |  NFC_NCIHALx_AR3C.7.0.4_N_OpnSrc |
diff --git a/halimpl/bcm2079x/adaptation/CondVar.cpp b/halimpl/bcm2079x/adaptation/CondVar.cpp
new file mode 100644
index 0000000..c2dacdc
--- /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>
+#include <string.h>
+
+
+/*******************************************************************************
+**
+** Function:        CondVar
+**
+** Description:     Initialize member variables.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::CondVar ()
+{
+    pthread_condattr_t attr;
+    pthread_condattr_init(&attr);
+    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+    memset (&mCondition, 0, sizeof(mCondition));
+    int const res = pthread_cond_init (&mCondition, &attr);
+    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;
+    }
+
+    int waitResult = pthread_cond_timedwait (&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..92e86b8
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ *  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>
+#include <cutils/properties.h>
+#include "buildcfg.h"
+#include "android_logmsg.h"
+extern void delete_hal_non_volatile_store (bool forceDelete);
+extern void verify_hal_non_volatile_store ();
+extern void resetConfig ();
+extern "C"
+{
+#include "userial.h"
+}
+
+extern void configureCrystalFrequency ();
+
+///////////////////////////////////////
+// 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);
+
+static bool isColdBoot = true;
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+extern const UINT8  nfca_version_string [];
+extern const UINT8  nfa_version_string [];
+
+tNFC_HAL_DM_PRE_SET_MEM nfc_hal_pre_set_mem_20795a1 [] =
+{
+    {0x0016403c,    0x00000008},
+    {0x0016403c,    0x00000000},
+    {0x0014008c,    0x00000001},
+    {0,         0}
+};
+
+extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem;
+
+///////////////////////////////////////
+
+
+int HaiInitializeLibrary (const bcm2079x_dev_t* device)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    ALOGE ("%s: ver=%s nfa=%s", __FUNCTION__, nfca_version_string, nfa_version_string);
+    int retval = EACCES;
+    unsigned long freq = 0;
+    unsigned long num = 0;
+    char temp[120];
+    int8_t prop_value;
+    UINT8 logLevel = 0;
+
+    logLevel = InitializeGlobalAppLogLevel ();
+
+    if ( GetNumValue ( NAME_GLOBAL_RESET, &num, sizeof ( num ) ) )
+    {
+        if (num == 1)
+        {
+            // Send commands to disable boc
+            p_nfc_hal_dm_pre_set_mem = nfc_hal_pre_set_mem_20795a1;
+        }
+    }
+
+    configureCrystalFrequency ();
+    verify_hal_non_volatile_store ();
+    if ( GetNumValue ( NAME_PRESERVE_STORAGE, (char*)&num, sizeof ( num ) ) &&
+            (num == 1) )
+        ALOGD ("%s: preserve HAL NV store", __FUNCTION__);
+    else
+    {
+        delete_hal_non_volatile_store (false);
+    }
+
+    if ( GetNumValue ( NAME_USE_RAW_NCI_TRACE, &num, sizeof ( num ) ) )
+    {
+        if (num == 1)
+        {
+            // display protocol traces in raw format
+            ProtoDispAdapterUseRawOutput (TRUE);
+        }
+    }
+
+    // Initialize protocol logging level
+    InitializeProtocolLogLevel ();
+
+    tUSERIAL_OPEN_CFG cfg;
+    struct tUART_CONFIG  uart;
+
+    if ( GetStrValue ( NAME_UART_PARITY, temp, sizeof ( temp ) ) )
+    {
+        if ( strcmp ( temp, "even" ) == 0 )
+            uart.m_iParity = USERIAL_PARITY_EVEN;
+        else if ( strcmp ( temp, "odd" ) == 0 )
+            uart.m_iParity = USERIAL_PARITY_ODD;
+        else if ( strcmp ( temp, "none" ) == 0 )
+            uart.m_iParity = USERIAL_PARITY_NONE;
+    }
+    else
+        uart.m_iParity = USERIAL_PARITY_NONE;
+
+    if ( GetStrValue ( NAME_UART_STOPBITS, temp, sizeof ( temp ) ) )
+    {
+        if ( strcmp ( temp, "1" ) == 0 )
+            uart.m_iStopbits = USERIAL_STOPBITS_1;
+        else if ( strcmp ( temp, "2" ) == 0 )
+            uart.m_iStopbits = USERIAL_STOPBITS_2;
+        else if ( strcmp ( temp, "1.5" ) == 0 )
+            uart.m_iStopbits = USERIAL_STOPBITS_1_5;
+    }
+    else if ( GetNumValue ( NAME_UART_STOPBITS, &num, sizeof ( num ) ) )
+    {
+        if ( num == 1 )
+            uart.m_iStopbits = USERIAL_STOPBITS_1;
+        else if ( num == 2 )
+            uart.m_iStopbits = USERIAL_STOPBITS_2;
+    }
+    else
+        uart.m_iStopbits = USERIAL_STOPBITS_1;
+
+    if ( GetNumValue ( NAME_UART_DATABITS, &num, sizeof ( num ) ) )
+    {
+        if ( 5 <= num && num <= 8 )
+            uart.m_iDatabits = ( 1 << ( num + 1 ) );
+    }
+    else
+        uart.m_iDatabits = USERIAL_DATABITS_8;
+
+    if ( GetNumValue ( NAME_UART_BAUD, &num, sizeof ( num ) ) )
+    {
+        if ( num == 300 ) uart.m_iBaudrate = USERIAL_BAUD_300;
+        else if ( num == 600 ) uart.m_iBaudrate = USERIAL_BAUD_600;
+        else if ( num == 1200 ) uart.m_iBaudrate = USERIAL_BAUD_1200;
+        else if ( num == 2400 ) uart.m_iBaudrate = USERIAL_BAUD_2400;
+        else if ( num == 9600 ) uart.m_iBaudrate = USERIAL_BAUD_9600;
+        else if ( num == 19200 ) uart.m_iBaudrate = USERIAL_BAUD_19200;
+        else if ( num == 57600 ) uart.m_iBaudrate = USERIAL_BAUD_57600;
+        else if ( num == 115200 ) uart.m_iBaudrate = USERIAL_BAUD_115200;
+        else if ( num == 230400 ) uart.m_iBaudrate = USERIAL_BAUD_230400;
+        else if ( num == 460800 ) uart.m_iBaudrate = USERIAL_BAUD_460800;
+        else if ( num == 921600 ) uart.m_iBaudrate = USERIAL_BAUD_921600;
+    }
+    else if ( GetStrValue ( NAME_UART_BAUD, temp, sizeof ( temp ) ) )
+    {
+        if ( strcmp ( temp, "auto" ) == 0 )
+            uart.m_iBaudrate = USERIAL_BAUD_AUTO;
+    }
+    else
+        uart.m_iBaudrate = USERIAL_BAUD_115200;
+
+    memset (&cfg, 0, sizeof(tUSERIAL_OPEN_CFG));
+    cfg.fmt = uart.m_iDatabits | uart.m_iParity | uart.m_iStopbits;
+    cfg.baud = uart.m_iBaudrate;
+
+    ALOGD ("%s: uart config=0x%04x, %d\n", __func__, cfg.fmt, cfg.baud);
+    USERIAL_Init(&cfg);
+
+    if ( GetNumValue ( NAME_NFCC_ENABLE_TIMEOUT, &num, sizeof ( num ) ) )
+    {
+        p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout = num;
+    }
+
+    if ( GetNumValue ( NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof ( num ) ) && num == 0 )
+    {
+        // Since NFA_MAX_EE_SUPPORTED is explicetly set to 0, no UICC support is needed.
+        p_nfc_hal_cfg->nfc_hal_hci_uicc_support = 0;
+    }
+
+    prop_value = property_get_bool("nfc.bcm2079x.isColdboot", 0);
+    if (prop_value) {
+        isColdBoot = true;
+        property_set("nfc.bcm2079x.isColdboot", "0");
+    }
+    // Set 'first boot' flag based on static variable that will get set to false
+    // after the stack has first initialized the EE.
+    p_nfc_hal_cfg->nfc_hal_first_boot = isColdBoot ? TRUE : FALSE;
+
+    HAL_NfcInitialize ();
+    HAL_NfcSetTraceLevel (logLevel); // Initialize HAL's logging level
+
+    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 ();
+    resetConfig ();
+    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 (0, 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;
+
+    // This function is a clear indication that the stack is initializing
+    // EE.  So we can reset the cold-boot flag here.
+    isColdBoot = false;
+    retval = HAL_NfcPreDiscover () ? 1 : 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;
+}
+
+
+int HaiGetMaxNfcee (const bcm2079x_dev_t* device, uint8_t* maxNfcee)
+{
+    ALOGD ("%s: enter", __FUNCTION__);
+    int retval = EACCES;
+
+    // This function is a clear indication that the stack is initializing
+    // EE.  So we can reset the cold-boot flag here.
+    isColdBoot = false;
+
+    if ( maxNfcee )
+    {
+        *maxNfcee = HAL_NfcGetMaxNfcee ();
+        ALOGD("%s: max_ee from HAL to use %d", __FUNCTION__, *maxNfcee);
+        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..f931493
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.cpp
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ *  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>
+#include <string.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..f921f99
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
@@ -0,0 +1,275 @@
+/******************************************************************************
+ *
+ *  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"
+#define LOG_TAG "NfcNciHal"
+#include "gki.h"
+extern "C"
+{
+    #include "nfc_hal_target.h"
+    #include "nfc_hal_nv_ci.h"
+}
+#include "config.h"
+#include "CrcChecksum.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* default_location = "/data/nfc";
+static const char* filename_prefix = "/halStorage.bin";
+static const std::string get_storage_location ();
+void delete_hal_non_volatile_store (bool forceDelete);
+void verify_hal_non_volatile_store ();
+
+
+/*******************************************************************************
+**
+** 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 = get_storage_location();
+    char filename[256];
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    snprintf (filename, sizeof(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)
+    {
+        unsigned short checksum = 0;
+        size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum));
+        size_t actualReadData = read (fileStream, p_buf, nbytes);
+        close (fileStream);
+        if (actualReadData > 0)
+        {
+            ALOGD ("%s: data size=%u", __FUNCTION__, actualReadData);
+            nfc_hal_nv_ci_read (actualReadData, NFC_HAL_NV_CO_OK, block);
+        }
+        else
+        {
+            ALOGE ("%s: fail to read", __FUNCTION__);
+            nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
+        }
+    }
+    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 = get_storage_location();
+    char filename[256];
+    int fileStream = 0;
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+    snprintf (filename, sizeof(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)
+    {
+        unsigned short checksum = crcChecksumCompute (p_buf, nbytes);
+        size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum));
+        size_t actualWrittenData = write (fileStream, p_buf, nbytes);
+        ALOGD ("%s: %d bytes written", __FUNCTION__, actualWrittenData);
+        if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
+        {
+            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);
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         get_storage_location
+**
+** Description      Get the absolute directory path of the HAL's storage location.
+**
+** Parameters       none
+**
+** Returns          Absolute path.
+**
+*******************************************************************************/
+const std::string get_storage_location ()
+{
+    char buffer [100];
+    memset (buffer, 0, sizeof(buffer));
+    if (!GetStrValue (NAME_NFA_STORAGE, buffer, sizeof(buffer)))
+        return default_location;
+    else
+        return std::string (buffer);
+}
+
+
+/*******************************************************************************
+**
+** Function         delete_hal_non_volatile_store
+**
+** Description      Delete all the content of the HAL's storage location.
+**
+** Parameters       forceDelete: unconditionally delete the storage.
+**
+** Returns          none
+**
+*******************************************************************************/
+void delete_hal_non_volatile_store (bool forceDelete)
+{
+    static bool firstTime = true;
+    std::string fn = get_storage_location();
+    char filename[256];
+    int stat = 0;
+
+    if ((firstTime == false) && (forceDelete == false))
+        return;
+    firstTime = false;
+
+    ALOGD ("%s", __FUNCTION__);
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
+    remove (filename);
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
+    remove (filename);
+}
+
+
+/*******************************************************************************
+**
+** Function         verify_hal_non_volatile_store
+**
+** Description      Verify the content of all non-volatile store.
+**
+** Parameters       none
+**
+** Returns          none
+**
+*******************************************************************************/
+void verify_hal_non_volatile_store ()
+{
+    ALOGD ("%s", __FUNCTION__);
+    std::string fn = get_storage_location();
+    char filename[256];
+    bool isValid = false;
+
+    fn.append (filename_prefix);
+    if (fn.length() > 200)
+    {
+        ALOGE ("%s: filename too long", __FUNCTION__);
+        return;
+    }
+
+    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
+    if (crcChecksumVerifyIntegrity (filename))
+    {
+        snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
+        if (crcChecksumVerifyIntegrity (filename))
+        {
+            snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
+            if (crcChecksumVerifyIntegrity (filename))
+            {
+                snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
+                if (crcChecksumVerifyIntegrity (filename))
+                {
+                    snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
+                    if (crcChecksumVerifyIntegrity (filename))
+                        isValid = true;
+                }
+            }
+        }
+    }
+
+    if (isValid == false)
+        delete_hal_non_volatile_store (true);
+}
diff --git a/halimpl/bcm2079x/adaptation/OverrideLog.cpp b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
new file mode 100644
index 0000000..ce40d8a
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ *  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 <string.h>
+#include "config.h"
+#include "android_logmsg.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};
+
+    num = 1;
+    if (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);
+
+    if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+    {
+        //display protocol traces in raw format
+        ProtoDispAdapterUseRawOutput (TRUE);
+    }
+    return appl_trace_level;
+}
+
+UINT32 InitializeProtocolLogLevel () {
+    UINT32 num = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
+        ScrProtocolTraceFlag = num;
+
+    int len = property_get ("nfc.enable_protocol_log", valueStr, "");
+    if (len > 0)
+    {
+        if (strncmp("0", valueStr, 1) == 0)
+        {
+            ScrProtocolTraceFlag = 0;
+        } else {
+            ScrProtocolTraceFlag = ~0;
+        }
+    }
+
+    return ScrProtocolTraceFlag;
+}
+
diff --git a/halimpl/bcm2079x/adaptation/StartupConfig.cpp b/halimpl/bcm2079x/adaptation/StartupConfig.cpp
new file mode 100644
index 0000000..f296763
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/StartupConfig.cpp
@@ -0,0 +1,155 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Construct a buffer that contains multiple Type-Length-Value contents
+ * that is used by the HAL in a CORE_SET_CONFIG NCI command.
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "StartupConfig.h"
+
+
+const UINT8 StartupConfig::mMaxLength = 255;
+
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Initialize all member variables.
+**
+** Returns:         None
+**
+*******************************************************************************/
+StartupConfig::StartupConfig ()
+{
+    //set first byte to 0, which is length of payload
+    mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
+}
+
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Reset all member variables.
+**
+** Returns:         None
+**
+*******************************************************************************/
+void StartupConfig::initialize ()
+{
+    mBuffer.clear ();
+    //set first byte to 0, which is length of payload
+    mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
+}
+
+
+/*******************************************************************************
+**
+** Function:        getInternalBuffer
+**
+** Description:     Get the pointer to buffer that contains multiple
+**                  Type-Length-Value contents.
+**
+** Returns:         Pointer to buffer.
+**
+*******************************************************************************/
+const UINT8* StartupConfig::getInternalBuffer ()
+{
+    return mBuffer.data ();
+}
+
+
+/*******************************************************************************
+**
+** Function:        append
+**
+** Description:     Append new config data to internal buffer.
+**                  newContent: buffer containing new content; newContent[0] is
+**                          payload length; newContent[1..end] is payload.
+**                  newContentLen: total length of newContent.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool StartupConfig::append (const UINT8* newContent, UINT8 newContentLen)
+{
+    static const char fn [] = "StartupConfig::append";
+    if ((newContentLen+mBuffer.size()) > mMaxLength)
+    {
+        ALOGE ("%s: exceed max length", fn);
+        return false;
+    }
+
+    ALOGD ("%s: try append %u bytes", fn, (uint8_string::size_type) (newContentLen));
+    //append new payload into private buffer
+    mBuffer.append (newContent+1, (uint8_string::size_type) (newContentLen-1));
+    //increase size counter of payload in private buffer
+    mBuffer[0] = mBuffer[0] + newContentLen-1;
+    ALOGD ("%s: new size %u bytes", fn, mBuffer[0]);
+    return true;
+};
+
+
+/*******************************************************************************
+**
+** Function:        disableSecureElement
+**
+** Description:     Adjust a TLV to disable secure element(s).  The TLV's type is 0xC2.
+**                  bitmask: 0xC0 = do not detect any secure element.
+**                           0x40 = do not detect secure element in slot 0.
+**                           0x80 = do not detect secure element in slot 1.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool StartupConfig::disableSecureElement (UINT8 bitmask)
+{
+    const UINT8 maxLen = mBuffer[0];
+    UINT8 index = 1, tlvType = 0, tlvLen = 0;
+    bool found0xC2 = false;
+
+    while (true)
+    {
+        if (index > maxLen)
+            break;
+        tlvType = mBuffer [index];
+        index++;
+        tlvLen = mBuffer [index];
+        index++;
+        if (tlvType == 0xC2) //this TLV controls secure elements
+        {
+            index++; //index of second byte in TLV's value
+            mBuffer [index] = mBuffer [index] | bitmask; //turn on certain bits
+            found0xC2 = true;
+        }
+        else
+            index += tlvLen;
+    }
+
+    if (found0xC2 == false)
+    {
+        UINT8 tlv [] = {0x04, 0xC2, 0x02, 0x61, 0x00};
+        tlv [4] = tlv [4] | bitmask;
+        found0xC2 = append (tlv, 5);
+    }
+    return found0xC2;
+}
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..86fc9b8
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
@@ -0,0 +1,360 @@
+/******************************************************************************
+ *
+ *  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 "android_logmsg.h"
+#include "nfc_target.h"
+#include "buildcfg.h"
+#include <cutils/log.h>
+
+
+extern UINT32 ScrProtocolTraceFlag;
+#define MAX_NCI_PACKET_SIZE 259
+#define BTE_LOG_BUF_SIZE 1024
+#define BTE_LOG_MAX_SIZE (BTE_LOG_BUF_SIZE - 12)
+#define MAX_LOGCAT_LINE 4096
+#define PRINT(s) __android_log_write (ANDROID_LOG_DEBUG, "BrcmNci", s)
+static char log_line [MAX_LOGCAT_LINE];
+static const char* sTable = "0123456789abcdef";
+static BOOLEAN sIsUseRaw = FALSE;
+static void ToHex (const UINT8* data, UINT16 len, char* hexString, UINT16 hexStringSize);
+static void dumpbin (const char* data, int size, UINT32 trace_layer, UINT32 trace_type);
+static inline void word2hex (const char* data, char** hex);
+static inline void byte2char (const char* data, char** str);
+static inline void byte2hex (const char* data, char** str);
+
+
+void BTDISP_LOCK_LOG()
+{
+}
+
+
+void BTDISP_UNLOCK_LOG()
+{
+}
+
+
+void BTDISP_INIT_LOCK()
+{
+}
+
+
+void BTDISP_UNINIT_LOCK()
+{
+}
+
+
+void ProtoDispAdapterUseRawOutput (BOOLEAN isUseRaw)
+{
+    sIsUseRaw = isUseRaw;
+}
+
+
+void ProtoDispAdapterDisplayNciPacket (UINT8 *nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv)
+{
+    //Protocol decoder is not available, so decode NCI packet into hex numbers.
+    if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
+        return;
+    char line_buf [(MAX_NCI_PACKET_SIZE*2)+1];
+    ToHex (nciPacket, nciPacketLen, line_buf, sizeof(line_buf));
+    __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
+}
+
+
+void ToHex (const UINT8* data, UINT16 len, char* hexString, UINT16 hexStringSize)
+{
+    int i=0, j=0;
+    for(i = 0, j = 0; i < len && j < hexStringSize-3; i++)
+    {
+        hexString [j++] = sTable [(*data >> 4) & 0xf];
+        hexString [j++] = sTable [*data & 0xf];
+        data++;
+    }
+    hexString [j] = '\0';
+}
+
+
+//Protodisp code calls ScrLog() to print decoded texts.
+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);
+}
+
+
+UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
+{
+    if(pTitle && *pTitle)
+        PRINT(pTitle);
+    dumpbin((char*) p, len, layer, type);
+    return p;
+}
+
+
+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;
+    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);
+    }
+}
+
+
+inline void word2hex (const char* data, char** hex)
+{
+    byte2hex(&data[1], hex);
+    byte2hex(&data[0], hex);
+}
+
+
+inline void byte2char (const char* data, char** str)
+{
+    **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
+    ++(*str);
+}
+
+
+inline void byte2hex (const char* data, char** str)
+{
+    **str = sTable[(*data >> 4) & 0xf];
+    ++*str;
+    **str = sTable[*data & 0xf];
+    ++*str;
+}
+
+
+    //Decode a few Bluetooth HCI packets into hex numbers.
+    void DispHciCmd (BT_HDR *p_buf)
+    {
+        UINT32 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;
+
+        ToHex (data, data_len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
+    }
+
+
+    //Decode a few Bluetooth HCI packets into hex numbers.
+    void DispHciEvt (BT_HDR *p_buf)
+    {
+        UINT32 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;
+
+        ToHex (data, data_len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
+    }
+
+
+    /*******************************************************************************
+    **
+    ** Function         DispLLCP
+    **
+    ** Description      Log LLCP packet as hex-ascii bytes.
+    **
+    ** Returns          None.
+    **
+    *******************************************************************************/
+    void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv)
+    {
+        UINT32 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;
+
+        ToHex (data, data_len, log_line, sizeof(log_line));
+        __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)
+    {
+        UINT32 nBytes = (len*2)+1;
+
+        if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+            return;
+
+        // Only trace HCP if we're tracing HCI as well
+        if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+            return;
+
+        if (nBytes > sizeof(log_line))
+            return;
+
+        ToHex (data, len, log_line, sizeof(log_line));
+        __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR": "BrcmHcpX", log_line);
+    }
+
+
+    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) {}
+
+
+/*******************************************************************************
+**
+** Function:        LogMsg
+**
+** Description:     Print messages from NFC stack.
+**
+** 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, LOGMSG_TAG_NAME, buffer);
+}
+
+
+void LogMsg_0 (UINT32 maskTraceSet, const char *p_str)
+{
+    LogMsg (maskTraceSet, p_str);
+}
+
+
+void LogMsg_1 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1)
+{
+    LogMsg (maskTraceSet, fmt_str, p1);
+}
+
+
+void LogMsg_2 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2);
+}
+
+
+void LogMsg_3 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3);
+}
+
+
+void LogMsg_4 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4);
+}
+
+void LogMsg_5 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4, p5);
+}
+
+
+void LogMsg_6 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6)
+{
+    LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4, p5, p6);
+}
diff --git a/halimpl/bcm2079x/adaptation/config.cpp b/halimpl/bcm2079x/adaptation/config.cpp
new file mode 100644
index 0000000..7889a52
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/config.cpp
@@ -0,0 +1,763 @@
+/******************************************************************************
+ *
+ *  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 <sys/stat.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+
+#define LOG_TAG "NfcNciHal"
+
+const char* transport_config_paths[] = {"/odm/etc/", "/vendor/etc/", "/etc/"};
+const int transport_config_path_size =
+    (sizeof(transport_config_paths) / sizeof(transport_config_paths[0]));
+
+#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:    findConfigFilePathFromTransportConfigPaths()
+**
+** Description: find a config file path with a given config name from transport
+**              config paths
+**
+** Returns:     none
+**
+*******************************************************************************/
+void findConfigFilePathFromTransportConfigPaths(const string& configName,
+                                                string& filePath) {
+  for (int i = 0; i < transport_config_path_size - 1; i++) {
+    filePath.assign(transport_config_paths[i]);
+    filePath += configName;
+    struct stat file_stat;
+    if (stat(filePath.c_str(), &file_stat) == 0 && S_ISREG(file_stat.st_mode)) {
+      return;
+    }
+  }
+  filePath.assign(transport_config_paths[transport_config_path_size - 1]);
+  filePath += configName;
+}
+
+/*******************************************************************************
+**
+** 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;
+        findConfigFilePathFromTransportConfigPaths(config_name, strPath);
+        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);
+        if (len > pParam->str_len())
+            len  = pParam->str_len();
+        memcpy(pValue, pParam->str_value(), 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 l)
+{
+    size_t len = l;
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    bool b = rConfig.getValue(name, pValue, len);
+    return b ? len : 0;
+}
+
+/*******************************************************************************
+**
+** 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;
+    string configName(extra_config_base);
+    configName += extra;
+    configName += extra_config_ext;
+
+    findConfigFilePathFromTransportConfigPaths(configName, strPath);
+    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..76947b9
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/patchram.cpp
@@ -0,0 +1,621 @@
+/******************************************************************************
+ *
+ *  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 <malloc.h>
+#include <string>
+#include <cutils/properties.h>
+#include "spdhelper.h"
+#include "StartupConfig.h"
+
+#define LOG_TAG "NfcNciHal"
+
+#define FW_PRE_PATCH                        "FW_PRE_PATCH"
+#define FW_PATCH                            "FW_PATCH"
+#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 CONFIG_MAX_LEN 256
+static UINT8 sConfig [CONFIG_MAX_LEN];
+static StartupConfig sStartupConfig;
+static StartupConfig sLptdConfig;
+static StartupConfig sPreDiscoveryConfig;
+static StartupConfig sXtalCustomParam;
+extern UINT8 *p_nfc_hal_dm_start_up_cfg; //defined in the HAL
+static UINT8 nfa_dm_start_up_vsc_cfg[CONFIG_MAX_LEN];
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; //defined in the HAL
+extern UINT8 *p_nfc_hal_dm_lptd_cfg; //defined in the HAL
+static UINT8 sDontSendLptd[] = { 0 };
+extern UINT8 *p_nfc_hal_pre_discover_cfg; //defined in the HAL
+extern UINT8 *p_nfc_hal_dm_xtal_params_cfg; //defined in HAL
+
+extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg;
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+static void mayDisableSecureElement (StartupConfig& config);
+
+/* Default patchfile (in NCD format) */
+#ifndef NFA_APP_DEFAULT_PATCHFILE_NAME
+#define NFA_APP_DEFAULT_PATCHFILE_NAME      "\0"
+#endif
+
+/* Default patchfile (in NCD format) */
+#ifndef NFA_APP_DEFAULT_I2C_PATCHFILE_NAME
+#define NFA_APP_DEFAULT_I2C_PATCHFILE_NAME  "\0"
+#endif
+
+tNFC_POST_RESET_CB nfc_post_reset_cb =
+{
+    /* Default Patch & Pre-Patch */
+    NFA_APP_DEFAULT_PATCHFILE_NAME,
+    NULL,
+    NFA_APP_DEFAULT_I2C_PATCHFILE_NAME,
+    NULL,
+
+    /* Default UART baud rate */
+    NFC_HAL_DEFAULT_BAUD,
+
+    /* Default tNFC_HAL_DEV_INIT_CFG (flags, num_xtal_cfg, {brcm_hw_id, xtal-freq, xtal-index} ) */
+    {
+        2, /* number of valid entries */
+        {
+            {0x43341000, 37400, NFC_HAL_XTAL_INDEX_37400},      // All revisions of 43341 use 37,400
+            {0x20795000, 26000, NFC_HAL_XTAL_INDEX_26000},
+            {0, 0, 0},
+            {0, 0, 0},
+            {0, 0, 0},
+        }
+    },
+
+    /* Default low power mode settings */
+    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  */
+
+    NFA_APP_MAX_NUM_REINIT,         /* max retry to get NVM type */
+    0,                              /* current retry count */
+    TRUE,                           /* debug mode for downloading patchram */
+    FALSE                           /* skip downloading patchram after reinit because of patch download failure */
+};
+
+
+/*******************************************************************************
+**
+** 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 > 0) ? sz : 0;
+}
+
+/*******************************************************************************
+**
+** 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);
+    //let stack download firmware during next initialization
+    nfc_post_reset_cb.spd_skip_on_power_cycle = FALSE;
+    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);
+    GetStrValue (NAME_SNOOZE_MODE_CFG, (char*)&gSnoozeModeCfg, sizeof(gSnoozeModeCfg));
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        ALOGE("%s: Patch download failed", __FUNCTION__);
+        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 */
+            ALOGD("%s: re-init; don't download firmware", __FUNCTION__);
+            //stop stack from downloading firmware during next initialization
+            nfc_post_reset_cb.spd_skip_on_power_cycle = TRUE;
+            USERIAL_PowerupDevice(0);
+            HAL_NfcReInit ();
+        }
+    }
+    /* 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 (UINT32 chipid)
+{
+    unsigned long num = 0;
+    int actualLen = 0;
+
+    sStartupConfig.initialize ();
+    sLptdConfig.initialize ();
+    sPreDiscoveryConfig.initialize();
+
+    actualLen = GetStrValue (NAME_NFA_DM_START_UP_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+        sStartupConfig.append (sConfig, actualLen);
+
+    // Set antenna tuning configuration if configured.
+    actualLen = GetStrValue(NAME_PREINIT_DSP_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+        sStartupConfig.append (sConfig, actualLen);
+
+    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] );
+    }
+
+    actualLen = GetStrValue(NAME_LPTD_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+    {
+        sLptdConfig.append (sConfig, actualLen);
+        p_nfc_hal_dm_lptd_cfg = const_cast<UINT8*> (sLptdConfig.getInternalBuffer ());
+    }
+    else
+    {
+        // Default to not sending any LPTD setting.
+        p_nfc_hal_dm_lptd_cfg = sDontSendLptd;
+    }
+
+    mayDisableSecureElement (sStartupConfig);
+    p_nfc_hal_dm_start_up_cfg = const_cast<UINT8*> (sStartupConfig.getInternalBuffer ());
+
+    actualLen = GetStrValue(NAME_NFA_DM_PRE_DISCOVERY_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen)
+    {
+        sPreDiscoveryConfig.append (sConfig, actualLen);
+        mayDisableSecureElement (sPreDiscoveryConfig);
+        p_nfc_hal_pre_discover_cfg = const_cast<UINT8*> (sPreDiscoveryConfig.getInternalBuffer ());
+    }
+
+    //configure how many secure elements are available for each type of chip
+    if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support > 0)
+    {
+        if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20791_GEN)
+        {
+            nfc_hal_cb.max_ee = BRCM_NFC_20791_GEN_MAX_EE;
+            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
+        }
+        else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_43341_GEN)
+        {
+            nfc_hal_cb.max_ee = BRCM_NFC_43341_GEN_MAX_EE;
+            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
+        }
+        else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20795_GEN)
+        {
+            nfc_hal_cb.max_ee = BRCM_NFC_20795_GEN_MAX_EE;
+            p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST;
+        }
+
+        //let .conf variable determine how many EE's to discover
+        if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num)))
+            nfc_hal_cb.max_ee = num;
+    }
+}
+
+/*******************************************************************************
+**
+** 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(chipid);                 // 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)
+                {
+                    size_t actualLen = fread(sI2cFixPrmBuf, 1, lenPrmBuffer, fd);
+                    if (actualLen == lenPrmBuffer)
+                    {
+                        ALOGD("%s Setting I2C fix to %s (size: %lu)", __FUNCTION__, sPrePatchFn, lenPrmBuffer);
+                        HAL_NfcPrmSetI2cPatch((UINT8*)sI2cFixPrmBuf, (UINT16)lenPrmBuffer, 0);
+                    }
+                    else
+                        ALOGE("%s fail reading i2c fix; actual len=%u; expected len=%lu", __FUNCTION__, actualLen, lenPrmBuffer);
+                }
+                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);
+                ALOGD("%s Downloading patchfile %s (size: %lu) format=%u", __FUNCTION__, sPatchFn, lenPrmBuffer, NFC_HAL_PRM_FORMAT_NCD);
+                if ((sPrmBuf = malloc(lenPrmBuffer)) != NULL)
+                {
+                    size_t actualLen = fread(sPrmBuf, 1, lenPrmBuffer, fd);
+                    if (actualLen == lenPrmBuffer)
+                    {
+                        if (!SpdHelper::isPatchBad((UINT8*)sPrmBuf, lenPrmBuffer))
+                        {
+                            /* Download patch using static memeory mode */
+                            HAL_NfcPrmDownloadStart(NFC_HAL_PRM_FORMAT_NCD, 0, (UINT8*)sPrmBuf, lenPrmBuffer, 0, prmCallback);
+                            bDownloadStarted = true;
+                        }
+                    }
+                    else
+                        ALOGE("%s fail reading patchram", __FUNCTION__);
+                }
+                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%lx, nvm_type=%d", __FUNCTION__, brcm_hw_id, nvm_type);
+    tHAL_NFC_STATUS stat = HAL_NFC_STATUS_FAILED;
+    UINT8 max_credits = 1, allow_no_nvm=0;
+
+    p_nfc_hal_cfg->nfc_hal_prm_nvm_required = TRUE; //don't download firmware if controller cannot detect EERPOM
+
+    if (nvm_type == NCI_SPD_NVM_TYPE_NONE)
+    {
+        GetNumValue(NAME_ALLOW_NO_NVM, &allow_no_nvm, sizeof(allow_no_nvm));
+        if (allow_no_nvm == 0)
+        {
+        ALOGD("%s: No NVM detected, FAIL the init stage to force a retry", __FUNCTION__);
+        USERIAL_PowerupDevice (0);
+        stat = HAL_NfcReInit ();
+            return;
+        }
+
+        p_nfc_hal_cfg->nfc_hal_prm_nvm_required = FALSE; //allow download firmware if controller cannot detect EERPOM
+    }
+
+        /* 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:        mayDisableSecureElement
+**
+** Description:     Optionally adjust a TLV to disable secure element.  This feature
+**                  is enabled by setting the system property
+**                  nfc.disable_secure_element to a bit mask represented by a hex
+**                  octet: C0 = do not detect any secure element.
+**                         40 = do not detect secure element in slot 0.
+**                         80 = do not detect secure element in slot 1.
+**
+**                  config: a sequence of TLV's.
+**
+*******************************************************************************/
+void mayDisableSecureElement (StartupConfig& config)
+{
+    unsigned int bitmask = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+    int len = property_get ("nfc.disable_secure_element", valueStr, "");
+    if (len > 0)
+    {
+        sscanf (valueStr, "%x", &bitmask); //read system property as a hex octet
+        ALOGD ("%s: disable 0x%02X", __FUNCTION__, (UINT8) bitmask);
+        config.disableSecureElement ((UINT8) (bitmask & 0xC0));
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function:    configureCrystalFrequency
+**
+** Description: Configure controller's crystal frequency by reading values from
+**              .conf file.  If .conf file does not define any value, then use
+**              default values defined in struct nfc_post_reset_cb.
+**
+** Returns:     none
+**
+*******************************************************************************/
+void configureCrystalFrequency ()
+{
+    unsigned long num = 0;
+    UINT32 hwId = 0;
+    UINT16 xtalFreq = 0;
+    UINT8 xtalIndex = 0;
+    int actualLen = 0;
+
+    if (GetNumValue (NAME_XTAL_HARDWARE_ID, &num, sizeof(num)))
+        hwId = num;
+
+    if (GetNumValue (NAME_XTAL_FREQUENCY, &num, sizeof(num)))
+        xtalFreq = (UINT16) num;
+
+    if (GetNumValue (NAME_XTAL_FREQ_INDEX, &num, sizeof(num)))
+        xtalIndex = (UINT8) num;
+
+    actualLen = GetStrValue (NAME_XTAL_PARAMS_CFG, (char*)sConfig, sizeof(sConfig));
+    if (actualLen && (xtalIndex == NFC_HAL_XTAL_INDEX_SPECIAL)) //whether to use custom crystal frequency
+    {
+        sXtalCustomParam.append (sConfig, actualLen);
+        p_nfc_hal_dm_xtal_params_cfg = const_cast<UINT8*> (sXtalCustomParam.getInternalBuffer ());
+    }
+
+    if ((hwId == 0) && (xtalFreq == 0) && (xtalIndex == 0))
+        return;
+
+    ALOGD ("%s: hwId=0x%lX; freq=%u; index=%u", __FUNCTION__, hwId, xtalFreq, xtalIndex);
+    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].brcm_hw_id = (hwId & BRCM_NFC_GEN_MASK);
+    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_freq  = xtalFreq;
+    nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_index = xtalIndex;
+    nfc_post_reset_cb.dev_init_config.num_xtal_cfg = 1;
+}
diff --git a/halimpl/bcm2079x/adaptation/spdhelper.cpp b/halimpl/bcm2079x/adaptation/spdhelper.cpp
new file mode 100644
index 0000000..3d87e0e
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/spdhelper.cpp
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#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;
+    mIsPatchBad = false;
+    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 100644
index 0000000..f41f296
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/userial_linux.c
@@ -0,0 +1,1795 @@
+/******************************************************************************
+ *
+ *  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
+#define NFC_WAKE_ASSERTED_ON_POR            UPIO_OFF
+
+#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];
+
+/* Modes used when powering off (independent
+   of what the stack/jni has configured */
+#define POM_NORMAL          (0)     /* Normal */
+#define POM_CE3SO           (1)     /* Go to CE3-SO */
+#define POM_NFC_OFF         (2)     /* Set NFC Off bit */
+
+static int gPowerOffMode = POM_NORMAL;
+
+static UINT8 ce3_so_cmd[10] = { 0x10,
+                                0x2F, /* CMD */
+                                0x08,
+                                0x06, /* size of cmd */
+                                0x02, /* CE3 power-level */
+                                0xF3, /* LpmUicc */
+                                0x01, /* LpmListenTech */
+                                0x01, /* Param */
+                                0x00, /* Forced */
+                                0x00  /* Debug */
+};
+
+static UINT8 set_nfc_off_cmd[5] = {
+                                0x10,
+                                0x2F, /* CMD */
+                                0x38,
+                                0x01, /* size of cmd */
+                                0x01  /* setNfcOff */
+};
+
+#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[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+static int   bSerialPortDevice = FALSE;
+static int _timeout = POLL_TIMEOUT;
+static BOOLEAN is_close_thread_is_waiting = FALSE;
+
+static int change_client_addr(int addr);
+
+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()
+{
+    int stat = 0;
+
+    stat = close(signal_fds[0]);
+    if (stat == -1)
+        ALOGE ("%s, fail close index 0; errno=%d", __FUNCTION__, errno);
+    signal_fds[0] = 0;
+
+    stat = close(signal_fds[1]);
+    if (stat == -1)
+        ALOGE ("%s, fail close index 1; errno=%d", __FUNCTION__, errno);
+    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__);
+
+    //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_Init(): wait for close-thread");
+            sleep (1);
+        }
+        else
+            break;
+    }
+
+    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);
+    pthread_mutex_unlock(&close_thread_mutex);
+}
+
+/*******************************************************************************
+ **
+ ** 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];
+            if (count > (len - offset)) //if (count > (remaining buffer size))
+                count = len - offset; //only read what the remaining buffer size can hold
+        }
+        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_to_tcio_baud: 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;
+    if ( GetNumValue ( NAME_POWER_OFF_MODE, &num, sizeof ( num ) ) )
+        gPowerOffMode = 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);
+
+    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( "%s sock = %d\n", __FUNCTION__, 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);
+                }
+            }
+        }
+        if ( bSerialPortDevice )
+        {
+            tcflush(linux_cb.sock, TCIOFLUSH);
+            tcgetattr(linux_cb.sock, &termios);
+
+            termios.c_cflag &= ~(CSIZE | PARENB);
+            termios.c_cflag = CLOCAL|CREAD|data_bits|stop_bits|parity;
+            if (!parity)
+                termios.c_cflag |= IGNPAR;
+            // termios.c_cflag &= ~CRTSCTS;
+            termios.c_oflag = 0;
+            termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
+            termios.c_iflag &= ~(BRKINT | ICRNL | INLCR | ISTRIP | IXON | IGNBRK | PARMRK | INPCK);
+            termios.c_lflag = 0;
+            termios.c_iflag = 0;
+            cfsetospeed(&termios, baud);
+            cfsetispeed(&termios, baud);
+
+            termios.c_cc[VTIME] = 0;
+            termios.c_cc[VMIN] = 1;
+            tcsetattr(linux_cb.sock, TCSANOW, &termios);
+
+            tcflush(linux_cb.sock, TCIOFLUSH);
+
+#if (USERIAL_USE_IO_BT_WAKE==TRUE)
+            userial_io_init_bt_wake( linux_cb.sock, &linux_cb.bt_wake_state );
+#endif
+            GKI_delay(gPowerOnDelay);
+        }
+        else
+        {
+            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;
+
+    ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write: (%d bytes)", len);
+    pthread_mutex_lock(&close_thread_mutex);
+
+    doWriteDelay();
+    t = clock();
+    while (len != 0 && linux_cb.sock != -1)
+    {
+        ret = write(linux_cb.sock, p_data + total, len);
+        if (ret < 0)
+        {
+            ALOGE("USERIAL_Write len = %d, ret = %d, errno = %d", len, ret, errno);
+            break;
+        }
+        else
+        {
+            ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write len = %d, ret = %d", len, ret);
+        }
+
+        total += ret;
+        len -= ret;
+    }
+    perf_update(&perf_write, clock() - t, total);
+
+    /* register a delay for next write */
+    setWriteDelay(total * nfc_write_delay / 1000);
+
+    pthread_mutex_unlock(&close_thread_mutex);
+
+    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_SetPowerOffDelays
+**
+** Description      Set power off delays used during USERIAL_Close().  The
+**                  values in the conf. file setting override these if set.
+**
+** Returns          None.
+**
+*******************************************************************************/
+UDRV_API void USERIAL_SetPowerOffDelays(int pre_poweroff_delay, int post_poweroff_delay)
+{
+    gPrePowerOffDelay = pre_poweroff_delay;
+    gPostPowerOffDelay = post_poweroff_delay;
+}
+
+/*******************************************************************************
+**
+** 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;
+    UINT8          res[10];
+    UINT32         delay = 100;
+
+    ALOGD ("%s: enter; gPowerOffMode=%d", __FUNCTION__, gPowerOffMode);
+
+    /* Do we need to put NFCC into certain mode before switching off?... */
+    if (gPowerOffMode != POM_NORMAL)
+    {
+        switch (gPowerOffMode)
+        {
+        case POM_CE3SO:
+            ALOGD ("%s: Sending Set_PwrLevel cmd to go to CE3-SO mode", __FUNCTION__);
+            USERIAL_Write(port, ce3_so_cmd, sizeof (ce3_so_cmd));
+            delay = 1000;
+            break;
+
+        case POM_NFC_OFF:
+            ALOGD ("%s: Sending Set_NfcOff cmd", __FUNCTION__);
+            USERIAL_Write(port, set_nfc_off_cmd, sizeof (set_nfc_off_cmd));
+            break;
+        }
+
+        USERIAL_Read(port, res, sizeof ( res ));
+        GKI_delay(delay);
+    }
+
+    // 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, NULL);
+        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)
+{
+    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 == -1)
+        ALOGE("%s: fail close linux_cb.sock; errno=%d", __FUNCTION__, errno);
+
+    if (linux_cb.sock_power_control > 0 && linux_cb.sock_power_control != linux_cb.sock)
+    result = close(linux_cb.sock_power_control);
+    if (result == -1)
+        ALOGE("%s: fail close linux_cb.sock_power_control; errno=%d", __FUNCTION__, errno);
+
+    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];
+    int delay = gPowerOnDelay;
+    ALOGD("%s: enter", __FUNCTION__);
+
+    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)
+        {
+            current_nfc_wake_state = NFC_WAKE_ASSERTED_ON_POR;
+            ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, NFC_WAKE_ASSERTED_ON_POR);
+            ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+            GKI_delay(10);
+            ret = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 1);
+        }
+
+        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_nego_res, sizeof ( spi_nego_res ));
+        }
+
+        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)
+        {
+            /* Delay needed after turning on chip */
+            GKI_delay(delay);
+            ALOGD( "Change client address to %x\n", bcmi2cnfc_client_addr);
+            ret = change_client_addr(bcmi2cnfc_client_addr);
+            if (!ret) {
+                resetSuccess = 1;
+                linux_cb.client_device_address = bcmi2cnfc_client_addr;
+                /* Delay long enough for address change */
+                /* MACO xxx this needs to be at least 200 ms for BCM2079x B3 */
+                delay = 200;
+            }
+        } else {
+            resetSuccess = 1;
+        }
+    }
+
+    if (!resetSuccess) {
+        ALOGE("BCM2079x: failed to initialize NFC controller");
+    }
+
+    GKI_delay(delay);
+    ALOGD("%s: exit", __FUNCTION__);
+}
+
+#define DEFAULT_CLIENT_ADDRESS 0x77
+#define ALIAS_CLIENT_ADDRESS   0x79
+static int change_client_addr(int addr)
+{
+    int ret;
+    int i;
+    char addr_data[] = {
+        0xFA, 0xF2, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A
+    };
+    int size = sizeof(addr_data) - 1;
+
+    addr_data[5] = addr & 0xFF;
+
+    /* set the checksum */
+    ret = 0;
+    for (i = 1; i < size; ++i)
+        ret += addr_data[i];
+    addr_data[size] = (ret & 0xFF);
+    ALOGD( "change_client_addr() change addr from 0x%x to 0x%x\n", DEFAULT_CLIENT_ADDRESS, addr);
+    /* ignore the return code from IOCTL */
+    /* always revert back to the default client address */
+    ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, DEFAULT_CLIENT_ADDRESS);
+    /* Send address change command (skipping first byte) */
+    ret = write(linux_cb.sock, &addr_data[1], size);
+
+    /* If it fails, it is likely a B3 we are talking to */
+    if (ret != size) {
+        ALOGD( "change_client_addr() change addr to 0x%x by setting BSP address to 0x%x\n", addr, ALIAS_CLIENT_ADDRESS);
+        /* legacy kernel */
+        /* MACO xxx commented out code below only works with new kernel driver,
+         * but Mako/Manta ship with old one */
+        ret = ioctl(linux_cb.sock, BCMNFC_CHANGE_ADDR, addr);
+        return ret;
+        /*
+        ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, ALIAS_CLIENT_ADDRESS);
+        size++;
+        ret = write(linux_cb.sock, addr_data, size);
+        */
+    }
+
+    if (ret == size) {
+        ALOGD( "change_client_addr() set client address 0x%x to client driver\n", addr);
+        ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, addr);
+    }
+    else {
+        ret = -EIO;
+    }
+    return ret;
+}
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..555bc4b
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_buffer.c
@@ -0,0 +1,1559 @@
+/******************************************************************************
+ *
+ *  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"
+#include <android/log.h>
+#include <cutils/log.h>
+#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;
+    #if GKI_BUFFER_DEBUG
+        ALOGD("\ngki_alloc_free_queue in, id:%d \n", id);
+    #endif
+
+    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
+            #if GKI_BUFFER_DEBUG
+                ALOGD("\ngki_alloc_free_queue calling  gki_init_free_queue, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            #endif
+            gki_init_free_queue(id, Q->size, Q->total, p_mem);
+            #if GKI_BUFFER_DEBUG
+                ALOGD("\ngki_alloc_free_queue ret OK, id:%d  size:%d, totol:%d\n", id, Q->size, Q->total);
+            #endif
+            return TRUE;
+        }
+        GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
+    }
+    #if GKI_BUFFER_DEBUG
+        ALOGD("\ngki_alloc_free_queue out failed, id:%d\n", id);
+    #endif
+    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");
+                GKI_enable();
+                return NULL;
+            }
+        #endif
+
+            if(Q->p_first == 0)
+            {
+                /* gki_alloc_free_queue() failed to alloc memory */
+                GKI_TRACE_ERROR_0("GKI_getbuf() fail alloc free queue");
+                GKI_enable();
+                return NULL;
+            }
+
+            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
+
+        if(Q->p_first == 0)
+        {
+            /* gki_alloc_free_queue() failed to alloc memory */
+            GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
+            return NULL;
+        }
+
+        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..e840a36
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_time.c
@@ -0,0 +1,1017 @@
+/******************************************************************************
+ *
+ *  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.OSRdyTbl[task_id] == TASK_DEAD)
+        {
+            // task is shutdown do not try to service timers
+            continue;
+        }
+
+        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..27ae561
--- /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          UINTPTR;
+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..df58e27
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1317 @@
+/******************************************************************************
+ *
+ *  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 <malloc.h>
+#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
+
+#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_condattr_t attr;
+    pthread_attr_t attr1;
+
+    pthread_condattr_init(&attr);
+    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+    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], &attr);
+    pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
+    pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], &attr);
+
+    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 = 0;
+
+    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(&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");
+    GKI_disable ();
+    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");
+    GKI_enable ();
+}
+
+/*******************************************************************************
+**
+** 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..a2faa94
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
@@ -0,0 +1,326 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 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 <string.h>
+#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)
+{
+    /* Initialize HAL control block */
+    nfc_hal_main_init ();
+
+   HAL_TRACE_API1 ("HAL_NfcInitialize (): NFC_HAL_TASK id=%i", NFC_HAL_TASK);
+
+
+#ifndef NFC_HAL_SHARED_GKI
+    /* Initialize GKI (not needed if using shared NFC/HAL GKI resources) */
+    GKI_init ();
+    GKI_enable ();
+#endif
+
+    /* 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);
+
+#ifndef NFC_HAL_SHARED_GKI
+    /* Start GKI scheduler (not needed if using shared NFC/HAL GKI resources) */
+    GKI_run (0);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcTerminate
+**
+** Description      Called to terminate NFC HAL
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcTerminate(void)
+{
+    HAL_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)
+{
+    HAL_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)
+{
+    HAL_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 (UINT16 data_len, UINT8 *p_core_init_rsp_params)
+{
+    NFC_HDR *p_msg;
+    UINT16  size;
+
+    HAL_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;
+
+    HAL_TRACE_API0 ("HAL_NfcWrite ()");
+
+    if (data_len > (NCI_MAX_CTRL_SIZE + NCI_MSG_HDR_SIZE))
+    {
+        HAL_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;
+
+    NFC_HDR *p_msg;
+
+    HAL_TRACE_API0 ("HAL_NfcPreDiscover ()");
+    if (nfc_hal_cb.pre_discover_done == FALSE)
+    {
+        nfc_hal_cb.pre_discover_done    = TRUE;
+        if (p_nfc_hal_pre_discover_cfg && *p_nfc_hal_pre_discover_cfg)
+        {
+            status                          = TRUE;
+            /* 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_PRE_DISCOVER;
+                GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+            }
+        }
+    }
+
+    HAL_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;
+    HAL_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)
+{
+    HAL_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);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcGetMaxNfcee
+**
+** Description      Retrieve the maximum number of NFCEEs supported by NFCC
+**
+** Returns          the maximum number of NFCEEs supported by NFCC
+**
+*******************************************************************************/
+UINT8 HAL_NfcGetMaxNfcee (void)
+{
+    HAL_TRACE_API1 ("HAL_NfcGetMaxNfcee: %d",nfc_hal_cb.max_ee);
+    return nfc_hal_cb.max_ee;
+}
+
+
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..aaae0a4
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
@@ -0,0 +1,30 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 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..9e200f8
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
@@ -0,0 +1,1289 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 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 <string.h>
+#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
+
+#define NCI_PROP_PARAM_SIZE_XTAL_INDEX      3       /* length of parameters in XTAL_INDEX CMD */
+#ifndef NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX
+#define NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX      20
+#endif
+
+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_VERSION_LEN  16  /* Length of patch version string in PATCH_INFO */
+
+/*****************************************************************************
+** 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;
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem;
+
+/*****************************************************************************
+** 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
+        {
+            HAL_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV");
+        }
+
+        GKI_freebuf (p_buff);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** 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;
+
+    HAL_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;
+        }
+    }
+
+    HAL_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)
+{
+    HAL_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))
+    {
+        nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP;
+
+        if (nfc_hal_dm_set_config (NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN,
+                                   p_nfc_hal_dm_pll_325_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;
+        }
+    }
+
+    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_get_xtal_index
+**
+** Description: Return Xtal index and frequency
+**
+** Returns:     tNFC_HAL_XTAL_INDEX
+**
+*******************************************************************************/
+tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index (UINT32 brcm_hw_id, UINT16 *p_xtal_freq)
+{
+    UINT8 xx;
+
+    HAL_TRACE_DEBUG1("nfc_hal_dm_get_xtal_index() brcm_hw_id:0x%x", brcm_hw_id);
+
+    for (xx = 0; xx < nfc_post_reset_cb.dev_init_config.num_xtal_cfg; xx++)
+    {
+        if ((brcm_hw_id & BRCM_NFC_GEN_MASK)
+            == nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].brcm_hw_id)
+        {
+            *p_xtal_freq = nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_freq;
+            return (nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_index);
+        }
+    }
+
+    /* if not found */
+    *p_xtal_freq = 0;
+    return (NFC_HAL_XTAL_INDEX_MAX);
+}
+
+/*******************************************************************************
+**
+** 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_MAX_SIZE_XTAL_INDEX];
+    UINT8 *p;
+    tNFC_HAL_XTAL_INDEX xtal_index;
+    UINT16              xtal_freq;
+    UINT8               cmd_len = NCI_PROP_PARAM_SIZE_XTAL_INDEX;
+    extern UINT8 *p_nfc_hal_dm_xtal_params_cfg;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_xtal_freq_index (): brcm_hw_id = 0x%x", nfc_hal_cb.dev_cb.brcm_hw_id);
+
+    xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
+    if ((xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL) && (p_nfc_hal_dm_xtal_params_cfg))
+    {
+        cmd_len += p_nfc_hal_dm_xtal_params_cfg[0]; /* [0] is the length of extra params */
+    }
+
+    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, cmd_len);
+    UINT8_TO_STREAM  (p, xtal_index);
+    UINT16_TO_STREAM (p, xtal_freq);
+    if (cmd_len > NCI_PROP_PARAM_SIZE_XTAL_INDEX)
+    {
+        memcpy (p, &p_nfc_hal_dm_xtal_params_cfg[1], p_nfc_hal_dm_xtal_params_cfg[0]);
+    }
+
+    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 + cmd_len, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_send_get_build_info_cmd
+**
+** Description      Send NCI_MSG_GET_BUILD_INFO CMD
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_get_build_info_cmd (void)
+{
+    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);
+}
+/*******************************************************************************
+**
+** Function:    nfc_hal_dm_adjust_hw_id
+**
+** Description: The hw_id of certain chips are shifted by 8 bits.
+**              Adjust the hw_id before processing.
+**
+** Returns:     Nothing
+**
+*******************************************************************************/
+static UINT32 nfc_hal_dm_adjust_hw_id (UINT32 hw_id)
+{
+    if ((hw_id & 0xF0000000) == 0)
+        hw_id <<= 4; /* shift hw_id by 4 bits to align w the format of most chips */
+    return hw_id;
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_check_xtal
+**
+** Description      check if need to send xtal command.
+**                  If not, proceed to next step get_patch_version.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_dm_check_xtal (void)
+{
+    UINT16  xtal_freq;
+    tNFC_HAL_XTAL_INDEX xtal_index;
+
+    /* if NFCC needs to set Xtal frequency before getting patch version */
+    xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
+    if ((xtal_index < NFC_HAL_XTAL_INDEX_MAX) || (xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL))
+    {
+        {
+            /* set Xtal index before getting patch version */
+            nfc_hal_dm_set_xtal_freq_index ();
+            return;
+        }
+    }
+
+    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);
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_pre_set_mem_cback
+**
+** Description      This is pre-set mem complete callback.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_dm_pre_set_mem_cback (tNFC_HAL_BTVSC_CPLT *pData)
+{
+    UINT8   status = pData->p_param_buf[0];
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_pre_set_mem_cback: %d", status);
+    /* if it is completed */
+    if (status == HCI_SUCCESS)
+    {
+        if (!nfc_hal_dm_check_pre_set_mem())
+        {
+            return;
+        }
+    }
+    nfc_hal_dm_check_xtal();
+}
+
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_check_pre_set_mem
+**
+** Description      Check if need to send the command.
+**
+** Returns          TRUE if done.
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_dm_check_pre_set_mem (void)
+{
+    UINT8   cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH];
+    UINT8   *p;
+    UINT32  addr = 0;
+
+    if (p_nfc_hal_dm_pre_set_mem)
+        addr     = p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].addr;
+    HAL_TRACE_DEBUG2 ("nfc_hal_dm_check_pre_set_mem: %d/0x%x", nfc_hal_cb.pre_set_mem_idx, addr);
+    if (addr == 0)
+    {
+        return TRUE;
+    }
+    p = cmd;
+
+    /* Add the command */
+    UINT16_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM);
+    UINT8_TO_STREAM  (p, HCI_BRCM_PRE_SET_MEM_LENGTH);
+
+    UINT8_TO_STREAM  (p, HCI_BRCM_PRE_SET_MEM_TYPE);
+    UINT32_TO_STREAM  (p, addr);
+    UINT8_TO_STREAM   (p, 0);
+    UINT32_TO_STREAM  (p, p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].data);
+    nfc_hal_cb.pre_set_mem_idx++;
+
+    nfc_hal_dm_send_bt_cmd (cmd,
+                            NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH,
+                            nfc_hal_dm_pre_set_mem_cback);
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** 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;
+    UINT8 u8;
+    tNFC_HAL_NCI_CBACK *p_cback = NULL;
+    UINT8   chipverlen;
+    UINT8   chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
+    UINT32  hw_id = 0;
+
+    HAL_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_NTF)
+            {
+                if (  (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE)
+                    ||(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET)  )
+                {
+                    /*
+                    ** Core reset ntf in the following cases;
+                    ** 1) after power up (raising REG_PU)
+                    ** 2) after setting xtal index
+                    ** Start pre-initializing NFCC
+                    */
+                    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer);
+                    nfc_hal_dm_pre_init_nfcc ();
+                }
+                else
+                {
+                    /* Core reset ntf after post-patch download, 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))
+            {
+                /* start timer in case that NFCC doesn't send RESET NTF after loading patch from NVM */
+                NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_POST_XTAL_SET);
+
+                nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+                                                ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+            }
+        }
+        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 (hw_id, p);
+            nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id (hw_id);
+            HAL_TRACE_DEBUG2 ("brcm_hw_id: 0x%x -> 0x%x", hw_id, nfc_hal_cb.dev_cb.brcm_hw_id);
+
+            STREAM_TO_UINT8 (chipverlen, p);
+            memset (chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN);
+
+            STREAM_TO_ARRAY (chipverstr, p, chipverlen);
+
+            nfc_hal_hci_handle_build_info (chipverlen, chipverstr);
+            nfc_hal_cb.pre_set_mem_idx = 0;
+            if (!nfc_hal_dm_check_pre_set_mem())
+            {
+                /* pre-set mem started */
+                return;
+            }
+            nfc_hal_dm_check_xtal();
+        }
+        else if (  (op_code == NFC_VS_GET_PATCH_VERSION_EVT)
+                 &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO)  )
+        {
+            /* Store NVM info to control block */
+
+            /* Skip over rsp len */
+            p++;
+
+            /* Get project id */
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.project_id, p);
+
+            /* RFU */
+            p++;
+
+            /* Get chip version string */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN)
+                u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN;
+            memcpy (nfc_hal_cb.nvm_cb.chip_ver, p, u8);
+            p += NCI_PATCH_INFO_VERSION_LEN;
+
+            /* Get major/minor version */
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_major, p);
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_minor, p);
+
+            /* Skip over max_size and patch_max_size */
+            p += 4;
+
+            /* Get current lpm patch size */
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.lpm_size, p);
+            STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.fpm_size, p);
+
+            /* clear all flags which may be set during previous initialization */
+            nfc_hal_cb.nvm_cb.flags = 0;
+
+            /* Set patch present flag */
+            if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size))
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT;
+
+            /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8)
+            {
+                /* LPM patch in NVM fails CRC check */
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD;
+            }
+
+
+            /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+            STREAM_TO_UINT8 (u8, p);
+            if (u8)
+            {
+                /* FPM patch in NVM fails CRC check */
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD;
+            }
+
+            /* Check if downloading patch to RAM only (no NVM) */
+            STREAM_TO_UINT8 (nfc_hal_cb.nvm_cb.nvm_type, p);
+            if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
+            {
+                nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM;
+            }
+
+            /* let platform update baudrate or download patch */
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE);
+            nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, nfc_hal_cb.nvm_cb.nvm_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 (op_code == NFC_VS_SEC_PATCH_AUTH_EVT)
+        {
+            HAL_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;
+
+    HAL_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)
+    {
+        HAL_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;
+    char buff[300];
+    char tmp[4];
+    buff[0] = 0;
+    int i;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+    for (i = 0; i < len; i++)
+    {
+        sprintf (tmp, "%02x ", p_data[i]);
+        strcat(buff, tmp);
+    }
+    HAL_TRACE_DEBUG2 ("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len, buff);
+
+    if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+    {
+        HAL_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)
+{
+    HAL_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;
+
+    HAL_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)
+{
+    HAL_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)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_dm_pre_init_nfcc ()");
+
+    /* if it was waiting for core reset notification after raising REG_PU */
+    if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE)
+    {
+        nfc_hal_dm_send_get_build_info_cmd ();
+    }
+    /* if it was waiting for core reset notification after setting Xtal */
+    else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET)
+    {
+        {
+            /* Core reset ntf after xtal setting indicating NFCC loaded patch from NVM */
+            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);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** 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)
+{
+    HAL_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.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);
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    nfc_hal_cb.hci_cb.hcp_conn_id = 0;
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+#endif
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.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)
+{
+    HAL_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;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback;
+#endif
+
+    nfc_hal_cb.pre_discover_done        = FALSE;
+
+    nfc_post_reset_cb.spd_nvm_detection_cur_count = 0;
+    nfc_post_reset_cb.spd_skip_on_power_cycle     = FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function         HAL_NfcDevInitDone
+**
+** Description      Notify that pre-initialization of NFCC is complete
+**
+** Returns          void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status)
+{
+    HAL_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 restart initialization after REG_PU
+**                  toggled because of failure to detect NVM type or download patchram.
+**
+** 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 (void)
+{
+    tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+
+    HAL_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)
+    {
+        {
+            /* Wait for NFCC to enable - Core reset notification */
+            NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
+
+            /* NFCC Enable timeout */
+            nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+                                            ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+        }
+
+        status = HAL_NFC_STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_dm_set_snooze_mode_cback
+**
+** Description      This is snooze 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;
+
+    HAL_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..7c8e1e8
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
@@ -0,0 +1,182 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2011-2014 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 */   31,
+    /* 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*/        0x0E,
+    /* B13*/        0xE8,
+    /* B14*/        0xF0,
+    /* B15*/        0x55,
+    /* B16*/        0x00,
+    /* B17*/        0x0F, /* CE3 SO delay in sec */
+    /* B18*/        0x00,
+    /* B19*/        0x00,
+    /* B20*/        0x00,
+    /* B21*/        0x00,
+    /* B22*/        0x00,
+    /* B23*/        0x00,
+    /* B24*/        0x00,
+    /* B25*/        0x00,
+    /* B26*/        0x00,
+    /* B27*/        0x00,
+    /* B28*/        NCI_PARAM_ID_ACT_ORDER, /* polling sequence */
+    /* B29*/        1,
+    /* B30*/        1,     /* (1 = active mode polling before passive, 0 = passive polling first) Default = 0.*/
+};
+
+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;
+
+/* the SetConfig at HAL_NfcPreDiscover. This is done once after HAL_NfcOpen */
+UINT8 nfc_hal_pre_discover_cfg[] = {
+    /* TLV len */   0x0A,
+    /* B0 */        NCI_PARAM_ID_SWPCFG,
+    /* B1 */        0x08,
+    /* B2 */        0x01,
+    /* B3 */        0x08,
+    /* B4 */        0x00,
+    /* B5 */        0x04,
+    /* B6 */        0x80,
+    /* B7 */        0xC3,
+    /* B8 */        0xC9,
+    /* B9 */        0x01
+};
+
+UINT8 *p_nfc_hal_pre_discover_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];
+
+/*
+** NFCC has a table which has 9 XTAL frequencies: 9.6, 13, 16.2,  19.2, 24, 26, 38.4, 52 and 37.4 in MHz.
+** For these 9 xtal frequencies, host doesn't need to configure PLL325.
+** For 43341, host doesn't need to configure it at all.
+*/
+UINT8 *p_nfc_hal_dm_pll_325_cfg = NULL;
+
+/*
+** Proprietary pre-set is required, if not NULL.
+*/
+tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem = NULL;
+
+tNFC_HAL_CFG nfc_hal_cfg =
+{
+    FALSE,                                  /* set nfc_hal_prm_nvm_required to TRUE, if the platform wants to abort PRM process without NVM */
+    (UINT16) NFC_HAL_NFCC_ENABLE_TIMEOUT,   /* max time to wait for RESET NTF after setting REG_PU to high
+                                            ** If NFCC doesn't have NVM or cannot load patch from NVM without Xtal setting
+                                            ** then set it to short to optimize bootup time because NFCC cannot send RESET NTF.
+                                            ** Otherwise, it depends on NVM type and size of patchram.
+                                            */
+    (UINT16) NFC_HAL_NFCC_ENABLE_TIMEOUT    /* max time to wait for RESET NTF after setting Xtal frequency
+                                            ** It depends on NVM type and size of patchram.
+                                            */
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    ,
+    TRUE,                                   /* set nfc_hal_first_boot to TRUE, if platform enables NFC for the first time after bootup */
+    (HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST)  /* Set bit(s) for supported UICC(s) */
+#endif
+};
+
+tNFC_HAL_CFG *p_nfc_hal_cfg= (tNFC_HAL_CFG *) &nfc_hal_cfg;
+
+const UINT8 nfc_hal_dm_xtal_params_cfg [] =
+{
+    8,             /* length */
+    0x00,           /* B0 Rfpll_cfg_pll_xtal_div_2                  */
+    0x00,           /* B1 Rfpll_cfg_pll_vcocal1_0_cal_ref_timeout   */
+    0x00,           /* B2 Rfpll_cfg_pll_vcocal2_cal_count           */
+    0x00,           /* B3 Rfpll_cfg_pll_vcocal3_cal_count           */
+    0x00,           /* B4 Rfpll_cfg_pll_dsm_b_msb_wild_base         */
+    0x00,           /* B5 Rfpll_cfg_pll_dsm_b_lsb_3_wild_base_3     */
+    0x00,           /* B6 Rfpll_cfg_pll_dsm_b_lsb_2_wild_base_2     */
+    0x00            /* B7 Rfpll_cfg_pll_dsm_b_lsb_1_wild_base_1     */
+};
+
+/* By default, the XTAL command does not need these extra params. */
+UINT8 *p_nfc_hal_dm_xtal_params_cfg = NULL;
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..6b573d5
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
@@ -0,0 +1,817 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 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_target.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+#include <string.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
+
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET    0x0C
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET    0x32
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET   0x7F
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET    0xB4
+
+#define NFC_HAL_HCI_PIPE_VALID_MASK                         0x80
+
+#define NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL             0xFF
+#define NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL              0xFE
+
+/* Version string for BCM20791B3 */
+const UINT8 NFC_HAL_DM_BCM20791B3_STR[]   = "20791B3";
+#define NFC_HAL_DM_BCM20791B3_STR_LEN     (sizeof (NFC_HAL_DM_BCM20791B3_STR)-1)
+
+/* Version string for BCM20791B4 */
+const UINT8 NFC_HAL_DM_BCM20791B4_STR[]   = "20791B4";
+#define NFC_HAL_DM_BCM20791B4_STR_LEN     (sizeof (NFC_HAL_DM_BCM20791B4_STR)-1)
+
+/* Version string for BCM43341B0 */
+const UINT8 NFC_HAL_DM_BCM43341B0_STR[]   = "43341B0";
+#define NFC_HAL_DM_BCM43341B0_STR_LEN     (sizeof (NFC_HAL_DM_BCM43341B0_STR)-1)
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+/****************************************************************************
+** Internal function prototypes
+****************************************************************************/
+static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
+static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void);
+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)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_evt_hdlr ()");
+
+    switch (p_evt_data->hdr.event)
+    {
+    case NFC_HAL_HCI_RSP_NV_READ_EVT:
+        if (  (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf && (p_evt_data->nv_read.block == HC_F3_NV_BLOCK || p_evt_data->nv_read.block == HC_F4_NV_BLOCK || p_evt_data->nv_read.block == HC_F5_NV_BLOCK))
+            ||(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf && p_evt_data->nv_read.block == HC_F2_NV_BLOCK)  )
+        {
+            nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
+        }
+        else
+        {
+            /* Invalid block or no buffer, Ignore */
+            HAL_TRACE_ERROR1 ("nfc_hal_hci_evt_hdlr: No buffer for handling read NV block: 0x%02x", p_evt_data->nv_read.block);
+        }
+        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;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_enable ()");
+
+    if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for NVM Type: 0x%02x", nfc_hal_cb.nvm_cb.nvm_type);
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+        return;
+    }
+
+    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_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
+        ||((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST) && ((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM)))
+        ||(p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST)  )
+    {
+        if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
+        {
+            HAL_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;
+            if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
+            {
+                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);
+            }
+            else
+            {
+                HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): Skip send F3 HCI NETWK CMD for UICC Mask: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support);
+                nfc_hal_hci_set_next_hci_netwk_config (HC_F3_NV_BLOCK);
+            }
+
+        }
+    }
+    else
+    {
+        HAL_TRACE_DEBUG2 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+        nfc_hal_hci_set_next_hci_netwk_config (HC_F2_NV_BLOCK);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_build_info
+**
+** Description      handle build info evt
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_build_info (UINT8 chipverlen, UINT8 *p_chipverstr)
+{
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_build_info ()");
+
+    if ((chipverlen == NFC_HAL_DM_BCM20791B3_STR_LEN) && (memcmp (NFC_HAL_DM_BCM20791B3_STR, p_chipverstr, NFC_HAL_DM_BCM20791B3_STR_LEN) == 0))
+    {
+        /* BCM2079B3 FW - eSE restarted for patch download */
+        nfc_hal_cb.hci_cb.hci_fw_workaround         = TRUE;
+        nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = TRUE;
+    }
+    else if (  ((chipverlen == NFC_HAL_DM_BCM20791B4_STR_LEN) && (memcmp (NFC_HAL_DM_BCM20791B4_STR, p_chipverstr, NFC_HAL_DM_BCM20791B4_STR_LEN) == 0))
+             ||((chipverlen == NFC_HAL_DM_BCM43341B0_STR_LEN) && (memcmp (NFC_HAL_DM_BCM43341B0_STR, p_chipverstr, NFC_HAL_DM_BCM43341B0_STR_LEN) == 0))  )
+    {
+        /* BCM43341B0/BCM2079B4 FW - eSE restarted for patch download */
+        nfc_hal_cb.hci_cb.hci_fw_workaround         = TRUE;
+        nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = FALSE;
+    }
+    else
+    {
+        /* BCM2079B5 FW - eSE not be restarted for patch download from UICC */
+        nfc_hal_cb.hci_cb.hci_fw_workaround         = FALSE;
+        nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = FALSE;
+    }
+}
+
+/*******************************************************************************
+**
+** 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 = 0;
+    UINT8  hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+    UINT8  block = 0;
+
+    HAL_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)
+    {
+        /* Correct the session id assigned by DH */
+        *(p+1) = nfc_hal_cb.hci_cb.dh_session_id[0];
+        nfc_hal_nv_co_write (p, data_len, HC_F2_NV_BLOCK);
+        return;
+    }
+
+    if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
+    {
+        block = HC_F3_NV_BLOCK;
+    }
+    else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
+    {
+        block = HC_F4_NV_BLOCK;
+    }
+    else if (target_handle == NFC_HAL_HCI_UICC2_TARGET_HANDLE)
+    {
+        block = HC_F5_NV_BLOCK;
+    }
+    else
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Invalid Target handle: 0x%02x", target_handle);
+        return;
+    }
+
+    if (  (!nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+        ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)  )
+    {
+        /* HCI Network notification received for UICC0/UICC1/UICC2, Update nv data */
+        nfc_hal_nv_co_write (p, data_len, block);
+    }
+    else
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET]);
+        hci_netwk_cmd[0] = target_handle;
+        memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+        nfc_hal_nv_co_write (hci_netwk_cmd, 1, block);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh
+**
+** Description      Fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (void)
+{
+    NFC_HDR  *p_msg;
+    UINT8 *p, *ps;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (): Fake ADM_NOTIFY_ALL_PIPE_CLEARED (0x%02x) from HAL", NFC_HAL_HCI_HOST_ID_UICC1);
+
+    /* Start of new message. Allocate a buffer for message */
+    if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        /* Initialize NFC_HDR */
+        p_msg->len    = NCI_DATA_HDR_SIZE + 0x03;
+        p_msg->event  = 0;
+        p_msg->offset = 0;
+        p_msg->layer_specific = 0;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        ps = p;
+        NCI_DATA_BLD_HDR (p, nfc_hal_cb.hci_cb.hcp_conn_id, 0x03);
+        /* HCP header with ADMIN pipe id and chaining bit set */
+        *p++ = ((1 << 0x07) | (NFC_HAL_HCI_ADMIN_PIPE & 0x7F));
+        /* HCP Message header with Command type instruction and ADM_NOTIFY_ALL_PIPE_CLEARED command */
+        *p++ = ((NFC_HAL_HCI_COMMAND_TYPE << 6) | (NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED & 0x3F));
+        /* HCP Data with UICC1 host id */
+        *p = NFC_HAL_HCI_HOST_ID_UICC1;
+
+#ifdef DISP_NCI
+        DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
+#endif
+        nfc_hal_send_nci_msg_to_nfc_task (p_msg);
+
+    }
+    else
+    {
+        HAL_TRACE_ERROR0 ("Unable to allocate buffer for faking ADM_NOTIFY_ALL_PIPE_CLEARED cmd from HAL to stack");
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hcp_pkt_to_hc
+**
+** Description      Handle HCP Packet from NFC task to Host Controller
+**
+** Returns          FALSE to send the packet to host controller
+**                  TRUE to drop the packet and fake credit ntf for hcp connection
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_hci_handle_hcp_pkt_to_hc (UINT8 *p_data)
+{
+    UINT8   chaining_bit;
+    UINT8   pipe;
+    UINT8   type;
+    UINT8   inst;
+    UINT8   index;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_to_hc ()");
+
+    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_ANY_GET_PARAMETER)
+            {
+                index = *(p_data++);
+                if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX)
+                {
+                    /* Set flag to modify session id[0] on response
+                     * from host controller to set session id cmd
+                     */
+                    nfc_hal_cb.hci_cb.update_session_id = TRUE;
+                }
+            }
+            else if (inst == NFC_HAL_HCI_ANY_SET_PARAMETER)
+            {
+                index = *(p_data++);
+                if (index == NFC_HAL_HCI_WHITELIST_INDEX)
+                {
+                    if (  (nfc_hal_cb.hci_cb.hci_fw_workaround)
+                        &&(nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)  )
+                    {
+                        /* Set flag to fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task after
+                         * response from host controller to set whitelist cmd
+                         */
+                        nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = TRUE;
+                    }
+                }
+                else if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX)
+                {
+                    nfc_hal_cb.hci_cb.dh_session_id[0] = *p_data;
+                    if (p_nfc_hal_cfg->nfc_hal_first_boot)
+                        *p_data = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
+                    else
+                        *p_data = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
+                }
+            }
+        }
+        else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
+        {
+            if (  (nfc_hal_cb.hci_cb.hci_fw_workaround)
+                &&(nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)
+                &&(nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)  )
+            {
+                /* Got response to the fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd sent by HAL to nfc task */
+                nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 =  FALSE;
+                /* return TRUE to drop this hcp without forwarding to host controller */
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_handle_hcp_pkt_from_hc
+**
+** Description      Handle HCP Packet from Host controller to Terminal Host
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hcp_pkt_from_hc (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;
+    UINT8   block = 0;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_from_hc ()");
+
+    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)
+        {
+            if (!nfc_hal_cb.hci_cb.hci_fw_workaround)
+                return;
+
+            inst  = (*p_data++ & 0x3F);
+
+            if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
+            {
+                STREAM_TO_UINT8 (source_host, p_data);
+
+                HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Received ADM_NOTIFY_ALL_PIPE_CLEARED command for UICC: 0x%02x", source_host);
+                if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
+                {
+                    block            = HC_F3_NV_BLOCK;
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+                }
+                else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
+                {
+                    block            = HC_F4_NV_BLOCK;
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+                }
+                else if (source_host == NFC_HAL_HCI_HOST_ID_UICC2)
+                {
+                    block            = HC_F5_NV_BLOCK;
+                    hci_netwk_cmd[0] = NFC_HAL_HCI_UICC2_TARGET_HANDLE;
+                }
+
+                if (source_host >= NFC_HAL_HCI_HOST_ID_UICC0)
+                {
+                    /* Reset Session ID */
+                    memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+                    nfc_hal_nv_co_write (hci_netwk_cmd, 1, block);
+                    HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Sent command to reset nv file for block: 0x%02x", block);
+                }
+            }
+        }
+        else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
+        {
+            if (nfc_hal_cb.hci_cb.update_session_id)
+            {
+                nfc_hal_cb.hci_cb.update_session_id = FALSE;
+                inst  = (*p_data++ & 0x3F);
+                if (inst == NFC_HAL_HCI_ANY_OK)
+                {
+                    /* Correct the session id assigned by DH */
+                    *p_data = nfc_hal_cb.hci_cb.dh_session_id[0];
+                }
+            }
+            else if (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)
+            {
+                /* NVM Type is UICC and got response from host controller
+                 * to Set whitelist command. Now fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to
+                 * NFC Task and then forward the whitelist cmd response
+                 */
+                nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh ();
+            }
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** 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)
+{
+    UINT8   *p;
+    UINT8   *p_hci_netwk_info = NULL;
+
+    HAL_TRACE_DEBUG3 ("nfc_hal_hci_handle_nv_read (): Block: [0x%02x], Status: [0x%02x], Size: [0x%04x]", block, status, size);
+
+    /* 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:
+    case HC_F5_NV_BLOCK:
+        if (  (status != HAL_NFC_STATUS_OK)
+            ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE)
+            ||(size < NFC_HAL_HCI_MIN_NETWK_INFO_SIZE)
+            ||((nfc_hal_cb.hci_cb.hci_fw_workaround) && (block == HC_F4_NV_BLOCK) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))  )
+        {
+            HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
+            memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+            if (block == HC_F3_NV_BLOCK)
+                nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+            else if (block == HC_F4_NV_BLOCK)
+                nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+            else
+                nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC2_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_F2_NV_BLOCK:
+        nfc_hal_cb.hci_cb.dh_session_id[0] = nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1];
+        if (p_nfc_hal_cfg->nfc_hal_first_boot)
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
+        else
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
+
+        if (  (status != HAL_NFC_STATUS_OK)
+            ||(size > NFC_HAL_HCI_DH_NETWK_INFO_SIZE)
+            ||(size < NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE)  )
+        {
+            HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
+            nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[0] = NFC_HAL_HCI_DH_TARGET_HANDLE;
+            nfc_hal_cb.hci_cb.dh_session_id[0] = 0xFF;
+            memset (&nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[2], 0xFF, (NFC_HAL_HCI_SESSION_ID_LEN - 1));
+            memset ((nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_SESSION_ID_LEN + 1), 0, (NFC_HAL_HCI_DH_NETWK_INFO_SIZE - NFC_HAL_HCI_SESSION_ID_LEN - 1));
+            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
+        {
+            if ((nfc_hal_cb.hci_cb.hci_fw_workaround) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))
+            {
+                /* if NVM Type is UICC, then UICC1 will find session id mismatch when activated for patch download,
+                 * and will remove pipes connected to DH even before DH is enabled, So DH will update NFCC
+                 * control block by removing all dynamic pipes connected to UICC1 */
+
+                nfc_hal_hci_remove_dyn_pipe_to_uicc1 ();
+                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);
+        }
+        break;
+
+    default:
+        return;
+    }
+
+    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;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_hci_remove_dyn_pipe_to_uicc1
+**
+** Description      Prepare hci network command read from nv file removing
+**                  all pipes connected to UICC1
+**
+** Returns          None
+**
+*******************************************************************************/
+void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void)
+{
+    UINT8 *p, *np;
+    UINT8 num_dyn_pipes = 0, new_num_dyn_pipes = 0;
+    UINT8 xx;
+    UINT8 source_host, dest_host, pipe_id;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_remove_dyn_pipe_to_uicc1 ()");
+
+    p  = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
+    np = p;
+    num_dyn_pipes = *(p - 1);
+
+    for (xx = 0; xx < num_dyn_pipes; xx++,p += NFC_HAL_HCI_PIPE_INFO_SIZE)
+    {
+        source_host = *(UINT8 *) (p);
+        dest_host   = *(UINT8 *) (p + 1);
+        pipe_id     = *(UINT8 *) (p + 4);
+
+        if ((source_host != NFC_HAL_HCI_HOST_ID_UICC1) && (dest_host != NFC_HAL_HCI_HOST_ID_UICC1))
+        {
+            memcpy (np, p, NFC_HAL_HCI_PIPE_INFO_SIZE);
+            np += NFC_HAL_HCI_PIPE_INFO_SIZE;
+            new_num_dyn_pipes++;
+        }
+    }
+
+    memset ((UINT8 *) (np), 0, NFC_HAL_HCI_PIPE_INFO_SIZE * (20 - new_num_dyn_pipes));
+
+    /* Update number of pipes after removing pipes connected to UICC1 */
+    p = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
+    *(p - 1) = new_num_dyn_pipes;
+}
+
+/*******************************************************************************
+**
+** 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;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_hci_init_complete (): Status: [0x%02x]", status);
+
+    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, status);
+}
+
+/*******************************************************************************
+**
+** 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;
+
+    HAL_TRACE_DEBUG1 ("nfc_hal_hci_set_next_hci_netwk_config (): Block: [0x%02x]", block);
+
+    switch (block)
+    {
+    case HC_F3_NV_BLOCK:
+        if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST)
+            &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+            &&((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM))  )
+        {
+            /* 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;
+        }
+        HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F4 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+
+    case HC_F4_NV_BLOCK:
+        if (  (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST)
+            &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)  )
+        {
+            /* Send command to read nvram data for 0xF5 */
+            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_F5_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;
+        }
+        HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F5 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+
+    case HC_F5_NV_BLOCK:
+        if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
+        {
+            HAL_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_F2_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_F2_NV_BLOCK:
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+        break;
+
+    default:
+        HAL_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;
+
+    HAL_TRACE_DEBUG3 ("nfc_hal_hci_vsc_cback (): Event: [0x%02x], Data length: [0x%04x], Status: [0x%02x]", event, data_len, status);
+
+    if (event  != NFC_VS_HCI_NETWK_RSP)
+        return;
+
+    if (status != HAL_NFC_STATUS_OK)
+    {
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+        return;
+    }
+
+    switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
+    {
+    case HC_F3_NV_BLOCK:
+    case HC_F4_NV_BLOCK:
+    case HC_F5_NV_BLOCK:
+    case HC_F2_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;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
+
+    if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
+    {
+        HAL_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
+        nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+    }
+}
+
+#endif
+
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..49236f9
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 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 "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+/*******************************************************************************
+**
+** Function         nfc_hal_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         nfc_hal_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);
+    }
+}
+
+#endif
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..d7fc5d5
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
@@ -0,0 +1,752 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 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 "nfc_hal_post_reset.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
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+/****************************************************************************
+** 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);
+static void nfc_hal_main_timeout_cback (void *p_tle);
+
+#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       */
+    "POST_XTAL_SET",    /* Waiting for reset ntf after xtal set  */
+    "W4_NFCC_ENABLE",   /* Waiting for reset ntf atter REG_PU up */
+    "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   */
+    "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;
+    nfc_hal_cb.timer.p_cback           = nfc_hal_main_timeout_cback;
+}
+
+/*******************************************************************************
+**
+** 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);
+
+    {
+        /* Wait for NFCC to enable - Core reset notification */
+        NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
+
+        /* NFCC Enable timeout */
+        nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+                                        ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hal_pre_discover_done_cback
+**
+** Description      Pre-discovery CFG is sent.
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_hal_pre_discover_done_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+    NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+    nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+    nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function         nfa_hal_send_pre_discover_cfg
+**
+** Description      sending Pre-discovery CFG
+**
+** Returns          nothing
+**
+*******************************************************************************/
+void nfa_hal_send_pre_discover_cfg (void)
+{
+    if (nfc_hal_dm_set_config (p_nfc_hal_pre_discover_cfg [0],
+                               &p_nfc_hal_pre_discover_cfg[1],
+                                nfa_hal_pre_discover_done_cback) != HAL_NFC_STATUS_OK)
+    {
+        nfa_hal_pre_discover_done_cback(0, 0, NULL);
+    }
+}
+
+/*******************************************************************************
+**
+** 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)
+    {
+        HAL_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)
+    {
+        HAL_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d", p_data->sigs);
+    }
+    else
+    {
+        HAL_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)
+{
+    HAL_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;
+
+    HAL_TRACE_DEBUG0 ("nfc_hal_main_timeout_cback ()");
+
+    switch (p_tlent->event)
+    {
+    case NFC_HAL_TTYPE_POWER_CYCLE:
+        nfc_hal_main_open_transport ();
+        break;
+
+    case NFC_HAL_TTYPE_NFCC_ENABLE:
+        /* NFCC should have enabled now, notify transport openned */
+        nfc_hal_dm_pre_init_nfcc ();
+        break;
+
+    default:
+        HAL_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_send_nci_msg_to_nfc_task
+**
+** Description      This function is called to send nci message to nfc task
+**
+** Returns          void
+**
+*******************************************************************************/
+void nfc_hal_send_nci_msg_to_nfc_task (NFC_HDR * p_msg)
+{
+#ifdef NFC_HAL_SHARED_GKI
+    /* Using shared NFC/HAL GKI resources - send message buffer directly to NFC_TASK for processing */
+    p_msg->event = BT_EVT_TO_NFC_NCI;
+    GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+#else
+    /* Send NCI message to the stack */
+    nfc_hal_cb.p_data_cback (p_msg->len, (UINT8 *) ((p_msg + 1)
+                                 + p_msg->offset));
+    GKI_freebuf(p_msg);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function         nfc_hal_send_credit_ntf_for_cid
+**
+** Description      This function is called to send credit ntf
+**                  for the specified connection id to nfc task
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_send_credit_ntf_for_cid (UINT8 cid)
+{
+    NFC_HDR  *p_msg;
+    UINT8    *p, *ps;
+
+    /* Start of new message. Allocate a buffer for message */
+    if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+    {
+        /* Initialize NFC_HDR */
+        p_msg->len    = NCI_DATA_HDR_SIZE + 0x03;
+        p_msg->event  = 0;
+        p_msg->offset = 0;
+        p_msg->layer_specific = 0;
+
+        p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+        ps = p;
+        NCI_MSG_BLD_HDR0(p, NCI_MT_NTF, NCI_GID_CORE);
+        NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_CONN_CREDITS);
+        UINT8_TO_STREAM (p, 0x03);
+
+        /* Number of credit entries */
+        *p++ = 0x01;
+        /* Connection id of the credit ntf */
+        *p++ = cid;
+        /* Number of credits */
+        *p = 0x01;
+#ifdef DISP_NCI
+        DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
+#endif
+        nfc_hal_send_nci_msg_to_nfc_task (p_msg);
+    }
+    else
+    {
+        HAL_TRACE_ERROR0 ("Unable to allocate buffer for Sending credit ntf to stack");
+    }
+}
+
+/*******************************************************************************
+**
+** 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)
+{
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    UINT8   cid, pbf;
+    UINT16  data_len;
+#endif
+    UINT8   *ps, *pp;
+    UINT16  len = p_msg->len;
+#ifdef DISP_NCI
+    UINT8   delta;
+#endif
+
+    HAL_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;
+        pp = ps + 1;
+#ifdef DISP_NCI
+        delta = p_msg->len - len;
+        DISP_NCI (ps + delta, (UINT16) (p_msg->len - delta), FALSE);
+#endif
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+        if (nfc_hal_cb.hci_cb.hcp_conn_id)
+        {
+            NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
+            if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
+            {
+                if (nfc_hal_hci_handle_hcp_pkt_to_hc (pp))
+                {
+                    HAL_TRACE_DEBUG0 ("nfc_hal_main_send_message() - Drop rsp to Fake cmd, Fake credit ntf");
+                    GKI_freebuf (p_msg);
+                    nfc_hal_send_credit_ntf_for_cid (cid);
+                    return;
+                }
+            }
+
+        }
+#endif
+
+        /* check low power mode state */
+        if (nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT))
+        {
+            USERIAL_Write (USERIAL_NFC_PORT, ps, p_msg->len);
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("nfc_hal_main_send_message(): drop data in low power mode");
+        }
+        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;
+
+    HAL_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)
+        {
+            HAL_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)
+        {
+            HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
+            nfc_hal_main_handle_terminate ();
+
+            /* Close uart */
+            USERIAL_Close (USERIAL_NFC_PORT);
+
+            if (nfc_hal_cb.p_stack_cback)
+            {
+                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)
+        {
+            HAL_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_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_PRE_DISCOVER:
+                    NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE);
+                    nfa_hal_send_pre_discover_cfg ();
+                    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_send_nci_msg_to_nfc_task (nfc_hal_cb.ncit_cb.p_rcv_msg);
+                        }
+                        else
+                        {
+                            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 ();
+        }
+    }
+
+    HAL_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..f4eb9af
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
@@ -0,0 +1,887 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2010-2014 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 */
+            HAL_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;
+                HAL_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 */
+            HAL_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
+        {
+            HAL_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
+        {
+            HAL_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 ((p_cb->p_rcv_msg) &&
+                ((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;
+
+                HAL_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 (NFC_HAL_TRACE_PROTOCOL == TRUE)
+    if (msg_received && p_cb->p_rcv_msg)
+    {
+        /* Display protocol trace message */
+        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;
+        HAL_TRACE_DEBUG1 ("nfc_hal_nci_proc_rx_bt_msg (): GOT an BT msgs init_sta:%d", nfc_hal_cb.dev_cb.initializing_state);
+        HAL_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_BUILD_INFO) ||
+            (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
+        {
+            HAL_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;
+    UINT8 mt, pbf, gid, op_code;
+    UINT8 payload_len;
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    UINT8  cid;
+    UINT16 data_len;
+#endif
+
+    HAL_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 (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+        if (mt == NCI_MT_DATA)
+        {
+            if (nfc_hal_cb.hci_cb.hcp_conn_id)
+            {
+                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_from_hc (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
+#endif
+        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)
+                        {
+                            HAL_TRACE_DEBUG2 ("RfDataCredits %d->%d", *p, nfc_hal_cb.max_rf_credits);
+                            *p = nfc_hal_cb.max_rf_credits;
+                        }
+                    }
+                }
+            }
+        }
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+        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;
+                    }
+                }
+            }
+        }
+#endif
+    }
+
+    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;
+    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
+    {
+        HAL_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);
+    }
+}
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** 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;
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+}
+
+#endif
+
+/*******************************************************************************
+**
+** 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;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+    if (  (nfc_hal_cb.hci_cb.hcp_conn_id == 0)
+        &&(nfc_hal_cb.nvm_cb.nvm_type != NCI_SPD_NVM_TYPE_NONE)  )
+        nci_brcm_check_cmd_create_hcp_connection ((NFC_HDR*) p_buf);
+#endif
+
+    /* 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)
+    {
+        HAL_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;
+        HAL_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);
+    }
+
+    HAL_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;
+
+    HAL_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)
+{
+    HAL_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..d1b739c
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
@@ -0,0 +1,1195 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2012-2014 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_BCM20791B3        0x10    /* B3 Patch (no RESET_NTF after patch download) */
+#define NFC_HAL_PRM_FLAGS_RM_RF             0x20    /* Erase Personality data */
+
+/* Secure patch download definitions */
+#define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN  7       /* PRJID + MAJORVER + MINORVER + COUNT */
+
+/* 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)*/
+
+#if (NFC_HAL_PRM_DEBUG == TRUE)
+#define NFC_HAL_PRM_STATE(str)  HAL_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);
+typedef struct
+{
+    UINT16              offset;
+    UINT8               len;
+} tNFC_HAL_PRM_RM_RF;
+
+const tNFC_HAL_PRM_RM_RF nfc_hal_prm_rm_rf_20795a1 [] =
+{
+    {0x0000,    0xFB},
+    {0x019C,    0x08},
+    {0x05E8,    0xFB},
+    {0,         0}
+};
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void);
+
+/*****************************************************************************
+** Extern variable from nfc_hal_dm_cfg.c
+*****************************************************************************/
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+
+/*******************************************************************************
+**
+** 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)
+    {
+        HAL_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);
+        if (memcmp (nfc_hal_cb.nvm_cb.chip_ver, p_src, chipverlen) != 0)
+        {
+            HAL_TRACE_ERROR0 ("Unexpected chip ver.");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+            return;
+        }
+        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_BCM20791B3;
+        }
+        else
+        {
+            /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */
+            nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_BCM20791B3;
+        }
+    }
+
+    /* 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 */
+            HAL_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 */
+    HAL_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;
+
+    HAL_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)
+        {
+            HAL_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 */
+        HAL_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_continue
+**
+** Description      Check patchfile version with current downloaded version
+**
+** Returns          void
+**
+*******************************************************************************/
+static void nfc_hal_prm_spd_check_version_continue (void)
+{
+    HAL_TRACE_DEBUG1 ("nfc_hal_prm_spd_check_version_continue 0x%02x", nfc_hal_cb.prm.flags);
+    if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_RM_RF)
+    {
+        HAL_TRACE_DEBUG0("erase relevant blocks in NVM");
+        nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_RM_RF;
+        if (!nfc_hal_prm_nvm_rw_cmd())
+        {
+            /* nvm rw started successfully */
+            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)
+    {
+        HAL_TRACE_DEBUG0 ("I2C patch 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 ();
+    }
+}
+
+/*******************************************************************************
+**
+** 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 nvm_patch_present_mask = 0;
+    UINT32 patchfile_patch_present_mask;
+    UINT16 patchfile_project_id = 0;
+    UINT16 patchfile_ver_major = 0;
+    UINT16 patchfile_ver_minor = 0;
+    UINT16 patchfile_patchsize;
+
+    UINT8  return_code = NFC_HAL_PRM_COMPLETE_EVT;
+
+    /* Initialize patchfile offset pointers */
+    p = p_start = NULL;
+    patchfile_patchsize = 0;
+
+    /* the good patches in NVM */
+    if (nfc_hal_cb.nvm_cb.lpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_LPM_BAD)))
+        nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
+
+    if (nfc_hal_cb.nvm_cb.fpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD)))
+        nvm_patch_present_mask  |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
+
+    /* 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)
+        {
+            HAL_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                        */
+
+
+        HAL_TRACE_DEBUG4 ("NVM Patch info: flags=0x%04x,   Ver=%i.%i, PatchMask=0x%08x",
+            nfc_hal_cb.nvm_cb.flags, nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor, nvm_patch_present_mask );
+        HAL_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
+        *********************************************************************/
+        /* Download the patchfile if no patches in NVM */
+        if ((nfc_hal_cb.nvm_cb.project_id == 0) || !(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_PATCH_PRESENT))
+        {
+            /* No patch in NVM, need to download all */
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+            if (nfc_hal_cb.dev_cb.brcm_hw_id == BRCM_20795A1_ID)
+            {
+                nfc_hal_cb.prm.flags   |= NFC_HAL_PRM_FLAGS_RM_RF;
+                nfc_hal_cb.prm.p_param  = (void *)nfc_hal_prm_rm_rf_20795a1;
+                nfc_hal_cb.prm.param_idx = 0;
+            }
+
+            HAL_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.nvm_cb.project_id != patchfile_project_id)
+        {
+            /* Project IDs mismatch */
+            HAL_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
+                              nfc_hal_cb.nvm_cb.project_id, patchfile_project_id);
+
+            return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+        }
+        /* Skip download if version of patchfile is equal to version in NVM */
+        /*                  and patches of the power modes are the same as the good patches in NVM */
+        else if (  (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major)
+            &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor)
+                 &&((nvm_patch_present_mask | patchfile_patch_present_mask) == nvm_patch_present_mask)  ) /* if the NVM patch include all the patched in file */
+        {
+            HAL_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is the same than the patchfile ",
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+
+            return_code = NFC_HAL_PRM_COMPLETE_EVT;
+        }
+        /* Remaining cases: Download all patches in the patchfile */
+        else
+        {
+            nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+            HAL_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                              patchfile_ver_major, patchfile_ver_minor,
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+        }
+
+    }
+    else
+    {
+        /* Invalid patch file header */
+        HAL_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)
+    {
+        HAL_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+                            patchfile_ver_major, patchfile_ver_minor,
+                            nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.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+                               */
+        /*          or patchfile is not for B3 (always download for B4 onward)  */
+        if (  (nfc_hal_cb.prm_i2c.p_patch)
+            &&(  (nfc_hal_cb.nvm_cb.project_id == 0)
+               ||(nfc_hal_cb.nvm_cb.fpm_size == 0)
+               ||(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_FPM_BAD)
+               ||(patchfile_ver_major >= 76)
+               ||(!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) ))
+        {
+            HAL_TRACE_DEBUG0 ("I2C patch fix required.");
+            nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+        }
+#endif  /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+        nfc_hal_prm_spd_check_version_continue ();
+    }
+    else
+    {
+        static BOOLEAN firstTime = TRUE;
+        if (firstTime)
+        {
+            HAL_TRACE_ERROR2 ("NVM patch version is %d.%d",
+                              nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.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_nvm_rw_cmd
+**
+** Description      Non Volatile Read Write Command; for now only write zeros
+**
+** Returns          TRUE if done.
+**
+*******************************************************************************/
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void)
+{
+    tNFC_HAL_PRM_RM_RF  *p_param = (tNFC_HAL_PRM_RM_RF *)(nfc_hal_cb.prm.p_param);
+    UINT8   *p_buff, *p, *p_end;
+    UINT8   len = 0;
+    UINT16  cmd_len;
+
+    if (p_param)
+        len     = p_param[nfc_hal_cb.prm.param_idx].len;
+    HAL_TRACE_DEBUG2 ("nfc_hal_prm_nvm_rw_cmd: %d/%d", nfc_hal_cb.prm.param_idx, len);
+    if (len == 0)
+    {
+        return TRUE;
+    }
+    cmd_len = len + 7;
+
+    if ((p_buff = (UINT8 *) GKI_getbuf(cmd_len)) == NULL)
+    {
+        HAL_TRACE_ERROR0 ("NVM No buffer");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        return TRUE;
+    }
+
+    p = p_buff;
+
+    UINT8_TO_STREAM  (p, (NCI_MTS_CMD|NCI_GID_PROP));
+    UINT8_TO_STREAM  (p, NCI_MSG_EEPROM_RW);
+    UINT8_TO_STREAM  (p, (len+4));
+    UINT8_TO_STREAM  (p, 1); /* 1=write 0=read */
+    UINT16_TO_STREAM  (p, p_param[nfc_hal_cb.prm.param_idx].offset);
+    UINT8_TO_STREAM  (p, len);
+    memset (p, 0, len); /* Fill remaining bytes with zeros*/
+
+    nfc_hal_cb.prm.param_idx++;
+    nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, nfc_hal_prm_nci_command_complete_cback);
+    GKI_freebuf (p_buff);
+    return FALSE;
+}
+
+/*******************************************************************************
+**
+** 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 SECURE_PATCH_DOWNLOAD Rsp */
+    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)
+            HAL_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status));
+#else
+            HAL_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 complete (SECURE_PATCH_DOWNLOAD NTF), including time to commit to NVM (for BCM43341B0) */
+            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_COMMIT_DELAY * 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)
+    {
+        HAL_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)
+            {
+                HAL_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)
+            {
+                HAL_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_BCM20791B3))
+            {
+                /* 20791B4 or newer - wait for RESET_NTF; including time to commit to NVM (for BCM20791B4+) */
+                post_signature_delay = NFC_HAL_PRM_COMMIT_DELAY;
+                HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay);
+
+            }
+            else if (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM)
+            {
+                /* No NVM. Wait for NFCC to restart */
+                post_signature_delay = NFC_HAL_PRM_END_DELAY;
+                HAL_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;
+                HAL_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
+        {
+            HAL_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+    }
+    /* Handle NCI_MSG_GET_PATCH_VERSION RSP */
+    else if (event == NFC_VS_GET_PATCH_VERSION_EVT)
+    {
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+    }
+    else if (event == NFC_VS_EEPROM_RW_EVT)
+    {
+        STREAM_TO_UINT8 (status, p);
+        if (status == NCI_STATUS_OK)
+        {
+            if (nfc_hal_prm_nvm_rw_cmd ())
+            {
+                nfc_hal_prm_spd_check_version_continue ();
+            }
+        }
+        else
+        {
+            HAL_TRACE_ERROR0 ("NVM failed");
+            nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+        }
+    }
+    else
+    {
+        /* Invalid response from NFCC during patch download */
+        HAL_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)
+{
+    UINT8 get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+    {
+        NCI_MTS_CMD|NCI_GID_PROP,
+        NCI_MSG_GET_PATCH_VERSION,
+        0x00
+    };
+
+    /* 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 */
+        HAL_TRACE_DEBUG0 ("Patch downloaded and authenticated. Get new patch version.");
+        /* add get patch info again to verify the effective FW version */
+        nfc_hal_dm_send_nci_cmd (get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback);
+        nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_W4_GET_VERSION;
+    }
+}
+
+/*******************************************************************************
+**
+** 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)
+    {
+        HAL_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 if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+    {
+        HAL_TRACE_DEBUG0 ("Received RESET NTF after pre-I2C patch download. Proceeding with patch download...");
+
+        /* Stop waiting for RESET NTF */
+        nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else
+    {
+        HAL_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_SPD_AUTH_DONE)
+    {
+        if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
+        {
+            /* Timeout waiting for RESET NTF after signature sent */
+            HAL_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)
+    {
+        HAL_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch");
+        nfc_hal_prm_spd_handle_next_patch_start ();
+    }
+    else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_W4_GET_VERSION)
+    {
+        HAL_TRACE_DEBUG0 ("get patch version timeout???");
+        nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+    }
+    else
+    {
+        HAL_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)
+{
+    HAL_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;
+
+        /* If patch download is required, but no NVM is available, then abort */
+        if ((p_nfc_hal_cfg->nfc_hal_prm_nvm_required) && (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM))
+        {
+            HAL_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 FALSE;
+        }
+
+        /* Compare patch version in NVM with version in patchfile */
+        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 patchfile is in a buffer, get patch version from buffer */
+            nfc_hal_prm_spd_check_version ();
+        }
+        else
+        {
+            /* If patchfile is not in a buffer, then request patchfile header from adaptation layer. */
+            (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT);
+        }
+    }
+    else
+    {
+        HAL_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)
+{
+    HAL_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
+    {
+        HAL_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))
+    HAL_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)
+    {
+        HAL_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
+    {
+        HAL_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/include/HalAdaptation.h b/halimpl/bcm2079x/include/HalAdaptation.h
new file mode 100644
index 0000000..9599c07
--- /dev/null
+++ b/halimpl/bcm2079x/include/HalAdaptation.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ *  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);
+extern int HaiGetMaxNfcee (const bcm2079x_dev_t* device, uint8_t* maxNfcee);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/OverrideLog.h b/halimpl/bcm2079x/include/OverrideLog.h
new file mode 100644
index 0000000..a441cbd
--- /dev/null
+++ b/halimpl/bcm2079x/include/OverrideLog.h
@@ -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 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;
+extern UINT32 ScrProtocolTraceFlag;
+
+
+/*******************************************************************************
+**
+** 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 ();
+UINT32 InitializeProtocolLogLevel ();
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/StartupConfig.h b/halimpl/bcm2079x/include/StartupConfig.h
new file mode 100644
index 0000000..e56a83c
--- /dev/null
+++ b/halimpl/bcm2079x/include/StartupConfig.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Construct a buffer that contains multiple Type-Length-Value contents
+ * that is used by the HAL in a CORE_SET_CONFIG NCI command.
+ ******************************************************************************/
+
+#pragma once
+#include "bt_types.h"
+#include <string>
+
+
+class StartupConfig
+{
+public:
+    typedef std::basic_string<UINT8> uint8_string;
+    StartupConfig ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        initialize
+    **
+    ** Description:     Reset all member variables.
+    **
+    ** Returns:         None
+    **
+    *******************************************************************************/
+    void initialize ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        getInternalBuffer
+    **
+    ** Description:     Get the pointer to buffer that contains multiple
+    **                  Type-Length-Value contents.
+    **
+    ** Returns:         Pointer to buffer.
+    **
+    *******************************************************************************/
+    const UINT8* getInternalBuffer ();
+
+
+    /*******************************************************************************
+    **
+    ** Function:        append
+    **
+    ** Description:     Append new config data to internal buffer.
+    **                  newContent: buffer containing new content; newContent[0] is
+    **                          payload length; newContent[1..end] is payload.
+    **                  newContentLen: total length of newContent.
+    **
+    ** Returns:         True if ok.
+    **
+    *******************************************************************************/
+    bool append (const UINT8* newContent, UINT8 newContentLen);
+
+
+    /*******************************************************************************
+    **
+    ** Function:        disableSecureElement
+    **
+    ** Description:     Adjust a TLV to disable secure element(s).  The TLV's type is 0xC2.
+    **                  bitmask: 0xC0 = do not detect any secure element.
+    **                           0x40 = do not detect secure element in slot 0.
+    **                           0x80 = do not detect secure element in slot 1.
+    **
+    ** Returns:         True if ok.
+    **
+    *******************************************************************************/
+    bool disableSecureElement (UINT8 bitmask);
+
+private:
+    static const UINT8 mMaxLength;
+    uint8_string mBuffer;
+};
diff --git a/halimpl/bcm2079x/include/android_logmsg.h b/halimpl/bcm2079x/include/android_logmsg.h
new file mode 100644
index 0000000..9922893
--- /dev/null
+++ b/halimpl/bcm2079x/include/android_logmsg.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ * Decode NFC packets and print them to ADB log.
+ * If protocol decoder is not present, then decode packets into hex numbers.
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "data_types.h"
+
+
+#define DISP_NCI    ProtoDispAdapterDisplayNciPacket
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv);
+void ProtoDispAdapterUseRawOutput (BOOLEAN isUseRaw);
+void ScrLog (UINT32 trace_set_mask, const char* fmt_str, ...);
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+void LogMsg_0 (UINT32 trace_set_mask, const char *p_str);
+void LogMsg_1 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1);
+void LogMsg_2 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2);
+void LogMsg_3 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3);
+void LogMsg_4 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4);
+void LogMsg_5 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5);
+void LogMsg_6 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6);
+UINT8* scru_dump_hex (UINT8* p, char* pTitle, UINT32 len, UINT32 layer, UINT32 type);
+void BTDISP_LOCK_LOG();
+void BTDISP_UNLOCK_LOG();
+void BTDISP_INIT_LOCK();
+void BTDISP_UNINIT_LOCK();
+void DispHciCmd (BT_HDR* p_buf);
+void DispHciEvt (BT_HDR* p_buf);
+void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv);
+void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv);
+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);
+
+
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/halimpl/bcm2079x/include/bcm2079x.h b/halimpl/bcm2079x/include/bcm2079x.h
new file mode 100644
index 0000000..beb5786
--- /dev/null
+++ b/halimpl/bcm2079x/include/bcm2079x.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ *  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)
+#define BCMNFC_SET_CLIENT_ADDR		_IO(BCMNFC_MAGIC, 0x07)
+
+struct bcm2079x_platform_data {
+	unsigned int irq_gpio;
+	unsigned int en_gpio;
+	int wake_gpio;
+};
+
+#endif
diff --git a/halimpl/bcm2079x/include/buildcfg.h b/halimpl/bcm2079x/include/buildcfg.h
new file mode 100644
index 0000000..32cf681
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ *  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"
+
+
+#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);
+void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv);
+#define DISP_NCI    ProtoDispAdapterDisplayNciPacket
+#define LOGMSG_TAG_NAME "NfcNciHal"
+
+
+#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..a8136b7
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg_hal.h
@@ -0,0 +1,31 @@
+/******************************************************************************
+ *
+ *  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 GKI_BUF0_MAX                16
+#define GKI_BUF1_MAX                16
+
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY (500)
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/spdhelper.h b/halimpl/bcm2079x/include/spdhelper.h
new file mode 100644
index 0000000..e496c98
--- /dev/null
+++ b/halimpl/bcm2079x/include/spdhelper.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+#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..7ca7369
--- /dev/null
+++ b/halimpl/bcm2079x/include/userial.h
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ *  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_SetPowerOffDelays(int,int);
+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/nfc_nci.c b/halimpl/bcm2079x/nfc_nci.c
new file mode 100644
index 0000000..b293c2b
--- /dev/null
+++ b/halimpl/bcm2079x/nfc_nci.c
@@ -0,0 +1,189 @@
+/******************************************************************************
+ *
+ *  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 <malloc.h>
+#include <string.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;
+}
+
+
+static int hal_get_max_nfcee (const struct nfc_nci_device *p_dev, uint8_t* maxNfcee)
+{
+    int retval = 0;
+    bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+    retval = HaiGetMaxNfcee (dev, maxNfcee);
+    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;
+        //dev->nci_device.get_max_ee = hal_get_max_nfcee;
+
+
+        // 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_BCM2079X_HARDWARE_MODULE_ID,
+        .name = "BCM2079x NFC NCI HW HAL",
+        .author = "Broadcom Corporation",
+        .methods = &nfc_module_methods,
+    },
+};
diff --git a/halimpl/pn54x/Android.mk.orig b/halimpl/pn54x/Android.mk
similarity index 60%
rename from halimpl/pn54x/Android.mk.orig
rename to halimpl/pn54x/Android.mk
index e47bde8..f9ce2c1 100644
--- a/halimpl/pn54x/Android.mk.orig
+++ b/halimpl/pn54x/Android.mk
@@ -26,6 +26,7 @@
 PN548C2 := 2
 PN551   := 3
 PN553   := 4
+PN557   := 5
 
 NQ110 := $PN547C2
 NQ120 := $PN547C2
@@ -48,9 +49,16 @@
 ifeq ($(PN553),4)
 D_CFLAGS += -DPN553=4
 endif
+ifeq ($(PN557),5)
+D_CFLAGS += -DPN557=5
+endif
 
 #### Select the CHIP ####
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
 NXP_CHIP_TYPE := $(PN553)
+else
+NXP_CHIP_TYPE := $(PN548C2)
+endif
 
 ifeq ($(NXP_CHIP_TYPE),$(PN547C2))
 D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN547C2
@@ -60,6 +68,8 @@
 D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN551
 else ifeq ($(NXP_CHIP_TYPE),$(PN553))
 D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553
+else ifeq ($(NXP_CHIP_TYPE),$(PN557))
+D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN557
 endif
 
 LOCAL_PATH := $(call my-dir)
@@ -67,11 +77,13 @@
 ifeq ($(NXP_CHIP_TYPE),$(PN547C2))
 LOCAL_MODULE := nfc_nci_pn547.grouper
 else ifeq ($(NXP_CHIP_TYPE),$(PN548C2))
-LOCAL_MODULE := nfc_nci.pn54x.default
+LOCAL_MODULE := nfc_nci.nqx.default
 else ifeq ($(NXP_CHIP_TYPE),$(PN551))
-LOCAL_MODULE := nfc_nci.pn54x.default
+LOCAL_MODULE := nfc_nci.nqx.default
 else ifeq ($(NXP_CHIP_TYPE),$(PN553))
-LOCAL_MODULE := nfc_nci.pn54x.default
+LOCAL_MODULE := nfc_nci.nqx.default
+else ifeq ($(NXP_CHIP_TYPE),$(PN557))
+LOCAL_MODULE := nfc_nci.nqx.default
 endif
 ifeq (true,$(TARGET_IS_64_BIT))
 LOCAL_MULTILIB := 64
@@ -79,8 +91,20 @@
 LOCAL_MULTILIB := 32
 endif
 LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := $(call all-subdir-c-files)  $(call all-subdir-cpp-files)
+LOCAL_SRC_FILES := \
+	$(call all-c-files-under, common) \
+	$(call all-c-files-under, dnld) \
+	$(call all-c-files-under, hal) \
+	$(call all-c-files-under, log) \
+	$(call all-c-files-under, self-test) \
+	$(call all-c-files-under, tml) \
+	$(call all-c-files-under, utils) \
+	$(call all-cpp-files-under, utils) \
+	nfc_nci.c
 LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware_legacy libdl
+LOCAL_MODULE_TAGS := optional
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := nxp
 
 LOCAL_CFLAGS := $(D_CFLAGS)
 LOCAL_C_INCLUDES += \
@@ -112,4 +136,36 @@
 #LOCAL_CFLAGS += -DFELICA_CLT_ENABLE
 #-DNXP_PN547C1_DOWNLOAD
 include $(BUILD_SHARED_LIBRARY)
-    
+
+include $(CLEAR_VARS)
+LOCAL_MODULE       := libnfc-brcm.conf
+LOCAL_MODULE_TAGS  := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)
+LOCAL_SRC_FILES    := $(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE       := libnfc-nxp.conf
+LOCAL_MODULE_TAGS  := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+LOCAL_SRC_FILES    := libnfc-nxp-PN80T_example.conf
+else
+LOCAL_SRC_FILES    := libnfc-nxp-PN66T_example.conf
+endif
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE       := libnfc-nxp_default.conf
+LOCAL_MODULE_TAGS  := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)
+
+ifeq ($(strip $(NQ3XX_PRESENT)),true)
+LOCAL_SRC_FILES    := libnfc-nxp-PN80T_example.conf
+else
+LOCAL_SRC_FILES    := libnfc-nxp-PN66T_example.conf
+endif
+include $(BUILD_PREBUILT)
diff --git a/halimpl/pn54x/common/phNfcCommon.h b/halimpl/pn54x/common/phNfcCommon.h
index 418a181..f03896d 100644
--- a/halimpl/pn54x/common/phNfcCommon.h
+++ b/halimpl/pn54x/common/phNfcCommon.h
@@ -15,8 +15,7 @@
  */
 
 /*
- *  OSAL header files related to memory, debug, random, semaphore and mutex
- * functions.
+ *  OSAL header files related to memory, debug, random, semaphore and mutex functions.
  */
 
 #ifndef PHNFCCOMMON_H
diff --git a/halimpl/pn54x/configs/NxpNfcCapability.cpp b/halimpl/pn54x/configs/NxpNfcCapability.cpp
index 869a55c..a4d0e14 100644
--- a/halimpl/pn54x/configs/NxpNfcCapability.cpp
+++ b/halimpl/pn54x/configs/NxpNfcCapability.cpp
@@ -1,5 +1,8 @@
 /******************************************************************************
  *
+ *  Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
  *  Copyright (C) 2015 NXP Semiconductors
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c
index 1dcc2c5..09882d2 100644
--- a/halimpl/pn54x/dnld/phDnldNfc.c
+++ b/halimpl/pn54x/dnld/phDnldNfc.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -751,8 +754,8 @@
   /*Read Firmware file name from config file*/
   if (GetNxpStrValue(NAME_NXP_FW_NAME, (char*)fwFileName, sizeof(fwFileName)) ==
       true) {
-    strcpy(fwpathName, FW_DLL_ROOT_DIR);
-    strncat(fwpathName, fwFileName, strlen(fwFileName));
+    strlcpy(fwpathName, FW_DLL_ROOT_DIR, sizeof(fwpathName));
+    strlcat(fwpathName, fwFileName, sizeof(fwpathName));
     pathName = fwpathName;
   }
 
@@ -969,15 +972,15 @@
   void* pImageInfoLen = NULL;
   if (pathName == NULL) {
       if(nfcFL.chipType == pn548C2) {
-          pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+          pathName = "/vendor/firmware/libpn548ad_fw.so";
       } else if(nfcFL.chipType == pn551) {
-          pathName = "/system/vendor/firmware/libpn551_fw.so";
+          pathName = "/vendor/firmware/libpn551_fw.so";
       } else if(nfcFL.chipType == pn553) {
-          pathName = "/system/vendor/firmware/libpn553_fw.so";
+          pathName = "/vendor/firmware/libpn553_fw.so";
       } else if(nfcFL.chipType == pn557) {
-          pathName = "/system/vendor/firmware/libpn557_fw.so";
+          pathName = "/vendor/firmware/libpn557_fw.so";
       } else {
-          pathName = "/system/vendor/firmware/libpn547_fw.so";
+          pathName = "/vendor/firmware/libpn547_fw.so";
       }
   }
 
@@ -1043,15 +1046,15 @@
   /* check for path name */
   if (pathName == NULL) {
       if(nfcFL.chipType == pn548C2) {
-          pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+          pathName = "/vendor/firmware/libpn548ad_fw.so";
       } else if(nfcFL.chipType == pn551) {
-          pathName = "/system/vendor/firmware/libpn551_fw.so";
+          pathName = "/vendor/firmware/libpn551_fw.so";
       } else if(nfcFL.chipType == pn553) {
-          pathName = "/system/vendor/firmware/libpn553_fw.so";
+          pathName = "/vendor/firmware/libpn553_fw.so";
       }else if(nfcFL.chipType == pn557) {
-          pathName = "/system/vendor/firmware/libpn557_fw.so";
+          pathName = "/vendor/firmware/libpn557_fw.so";
       } else {
-          pathName = "/system/vendor/firmware/libpn547_fw.so";
+          pathName = "/vendor/firmware/libpn547_fw.so";
       }
   }
   /* check if the handle is not NULL then free the library */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Internal.c b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
index 516489e..d6d0bad 100644
--- a/halimpl/pn54x/dnld/phDnldNfc_Internal.c
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
index bfdbde9..100b72b 100644
--- a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -534,7 +537,6 @@
     if ((0 != pRespBuff->wLen) && (NULL != pRespBuff->pBuff)) {
       bHwVer = (pRespBuff->pBuff[0]);
       bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */
-
       if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) ||
               (PHDNLDNFC_HWVER_MRA2_2 == bHwVer) ||
                ((nfcFL.chipType == pn551) &&
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
index 7185388..f8d0103 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.c
+++ b/halimpl/pn54x/hal/phNxpNciHal.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -507,8 +510,8 @@
                              max_len * sizeof(uint8_t))) {
     NXPLOG_NCIHAL_E(
         "Invalid nfc device node name keeping the default device node "
-        "/dev/pn54x");
-    strcpy(nfc_dev_node, "/dev/pn54x");
+        "/dev/nq-nci");
+    strlcpy(nfc_dev_node, "/dev/nq-nci", max_len);
   }
 
   tTmlConfig.pDevName = (int8_t*)nfc_dev_node;
@@ -669,8 +672,8 @@
                              max_len)) {
     NXPLOG_NCIHAL_E(
         "Invalid nfc device node name keeping the default device node "
-        "/dev/pn54x");
-    strcpy((char*)nfc_dev_node, "/dev/pn54x");
+        "/dev/nq-nci");
+    strlcpy((char*)nfc_dev_node, "/dev/nq-nci", max_len);
   }
   /* Configure hardware link */
   nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
@@ -1168,7 +1171,7 @@
 void phNxpNciHal_check_delete_nfaStorage_DHArea() {
   struct stat st;
   int ret = 0;
-  const char config_eseinfo_path[] = "/data/vendor/nfc/nfaStorage.bin1";
+  const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
   if (stat(config_eseinfo_path, &st) == -1) {
     ALOGD("%s: file not found %s", __func__, config_eseinfo_path);
   } else {
@@ -1731,7 +1734,7 @@
             NXPLOG_NCIHAL_E("request_EEPROM error occured %d", status);
             NXP_NCI_HAL_CORE_INIT_RECOVER(retry_core_init_cnt, retry_core_init);
         }
-        if(nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) {
+        if ((nfcFL.chipType == pn551) || (nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
             /*Read SWP1A data*/
             memset(&swp_intf_info, 0, sizeof(swp_intf_info));
             swp_intf_info.request_mode = GET_EEPROM_DATA;
@@ -2181,7 +2184,7 @@
   struct stat st;
   int ret = 0;
   NFCSTATUS status = NFCSTATUS_FAILED;
-  const char config_eseinfo_path[] = "/data/vendor/nfc/nfaStorage.bin1";
+  const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
   static uint8_t session_identity[8] = {0x00};
   uint8_t default_session[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
   uint8_t swp2_intf_status = 0x00;
@@ -2228,7 +2231,7 @@
 
   if (status == NFCSTATUS_FAILED) {
     /*Disable SWP1 and 1A interfaces*/
-      if(nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH) {
+      if ((nfcFL.chipType == pn551) || (nfcFL.chipType == pn553) || (nfcFL.chipType == pn557)) {
           status = phNxpNciHal_send_ext_cmd(sizeof(disable_dual_swp_intf),
                   disable_dual_swp_intf);
       }
@@ -3078,11 +3081,13 @@
       status = phNxpLog_EnableDisableLogLevel(pInpOutData->inp.data.halType);
       break;
     case HAL_NFC_IOCTL_SET_NFC_SERVICE_PID:
-      gpphTmlNfc_Context->nfc_service_pid = pInpOutData->inp.data.nfcServicePid;
-      status = phTmlNfc_IoCtl(phTmlNfc_e_SetNfcServicePid);
-      if (NFCSTATUS_FAILED != status) {
-        if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
-        ret = 0;
+      if(gpphTmlNfc_Context) {
+          gpphTmlNfc_Context->nfc_service_pid = pInpOutData->inp.data.nfcServicePid;
+          status = phTmlNfc_IoCtl(phTmlNfc_e_SetNfcServicePid);
+          if (NFCSTATUS_FAILED != status) {
+              if (NULL != p_data) pInpOutData->out.data.status = (uint16_t)status;
+              ret = 0;
+          }
       }
       break;
     case HAL_NFC_IOCTL_GET_FEATURE_LIST:
@@ -3705,7 +3710,7 @@
   struct stat st;
   int ret = 0;
   NFCSTATUS status = NFCSTATUS_FAILED;
-  const char config_eseinfo_path[] = "/data/vendor/nfc/nfaStorage.bin1";
+  const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
   uint8_t *reset_ese_session_identity_set;
   uint8_t ese_session_dyn_uicc_nv[] = {
             0x20, 0x02, 0x17, 0x02,0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF,
@@ -3930,6 +3935,60 @@
   return status;
 }
 
+tNFC_chipType configChipType(uint8_t* msg, uint16_t msg_len) {
+    tNFC_chipType chipType;
+    const uint16_t offsetHwVersion = 24;
+    const uint16_t offsetFwVersion = 25;
+
+    if((msg != NULL) && (msg_len != 0)) {
+        if((msg[0] == 0x60 && msg[1] == 00) ||
+                ((offsetFwVersion < msg_len) && (msg[offsetFwVersion] == 0x12))) {
+            chipType = pn81T;
+        }
+        else if(offsetHwVersion < msg_len) {
+            ALOGD ("%s HwVersion : 0x%02x", __func__,msg[offsetHwVersion]);
+            switch(msg[offsetHwVersion]){
+
+            case 0x40 : //PN553 A0
+            case 0x41 : //PN553 B0
+                chipType = pn553;
+                break;
+
+            case 0x50 : //PN553 A0 + P73
+            case 0x51 : //PN553 B0 + P73
+                chipType = pn80T;
+                break;
+
+            case 0x98 :
+                chipType = pn551;
+                break;
+
+            case 0xA8 :
+                chipType = pn67T;
+                break;
+
+            case 0x28 :
+            case 0x48 :
+                chipType = pn548C2;
+                break;
+
+            case 0x18 :
+            case 0x58 :
+                chipType = pn66T;
+                break;
+
+            default :
+                chipType = pn80T;
+            }
+        }
+        else {
+            ALOGD ("%s Wrong msg_len. Setting Default ChiptType pn80T",__func__);
+            chipType = pn80T;
+        }
+    }
+    return chipType;
+}
+
 /*******************************************************************************
 **
 ** Function         phNxpNciHal_configFeatureList
diff --git a/halimpl/pn54x/hal/phNxpNciHal.h b/halimpl/pn54x/hal/phNxpNciHal.h
index fe2f0a5..8870dcc 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.h
+++ b/halimpl/pn54x/hal/phNxpNciHal.h
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,13 +22,11 @@
 #include <hardware/nfc.h>
 #include <phNxpNciHal_utils.h>
 #include "NxpNfcCapability.h"
-#include "nfc_hal_api.h"
 
 /********************* Definitions and structures *****************************/
 #define MAX_RETRY_COUNT 5
 #define NCI_MAX_DATA_LEN 300
 #define NCI_POLL_DURATION 500
-#define HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT 0x07
 #define NXP_STAG_TIMEOUT_BUF_LEN 0x04 /*FIXME:TODO:remove*/
 #define NXP_WIREDMODE_RESUME_TIMEOUT_LEN 0x04
 #define NFCC_DECIDES 00
@@ -33,6 +34,34 @@
 #define LINK_ALWAYS_ON 02
 #undef P2P_PRIO_LOGIC_HAL_IMP
 
+enum {
+    HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT = 0x07,
+    HAL_NFC_POST_MIN_INIT_CPLT_EVT  = 0x08
+};
+
+enum {
+    HAL_NFC_IOCTL_P61_IDLE_MODE = 0,
+    HAL_NFC_IOCTL_P61_WIRED_MODE,
+    HAL_NFC_IOCTL_P61_PWR_MODE,
+    HAL_NFC_IOCTL_P61_DISABLE_MODE,
+    HAL_NFC_IOCTL_P61_ENABLE_MODE,
+    HAL_NFC_IOCTL_SET_BOOT_MODE,
+    HAL_NFC_IOCTL_GET_CONFIG_INFO,
+    HAL_NFC_IOCTL_CHECK_FLASH_REQ,
+    HAL_NFC_IOCTL_FW_DWNLD,
+    HAL_NFC_IOCTL_FW_MW_VER_CHECK,
+    HAL_NFC_IOCTL_DISABLE_HAL_LOG,
+    HAL_NFC_IOCTL_NCI_TRANSCEIVE,
+    HAL_NFC_IOCTL_P61_GET_ACCESS,
+    HAL_NFC_IOCTL_P61_REL_ACCESS,
+    HAL_NFC_IOCTL_ESE_CHIP_RST,
+    HAL_NFC_IOCTL_REL_SVDD_WAIT,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE,
+    HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,
+    HAL_NFC_IOCTL_GET_FEATURE_LIST
+};
+
 #define NCI_VERSION_2_0 0x20
 #define NCI_VERSION_1_1 0x11
 #define NCI_VERSION_1_0 0x10
diff --git a/halimpl/pn54x/hal/phNxpNciHal_ext.c b/halimpl/pn54x/hal/phNxpNciHal_ext.c
index 6e0c4f1..3f35693 100644
--- a/halimpl/pn54x/hal/phNxpNciHal_ext.c
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -65,7 +68,6 @@
 extern uint32_t timeoutTimerId;
 extern uint32_t gSvddSyncOff_Delay; /*default delay*/
 tNfc_featureList nfcFL;
-
 extern NFCSTATUS read_retry();
 /************** HAL extension functions ***************************************/
 static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void* pContext);
diff --git a/halimpl/pn54x/inc/Nxp_Features.h b/halimpl/pn54x/inc/Nxp_Features.h
new file mode 100644
index 0000000..84ab3dc
--- /dev/null
+++ b/halimpl/pn54x/inc/Nxp_Features.h
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2012-2016 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NXP features declarations
+ */
+#include <unistd.h>
+#include <string.h>
+#ifndef NXP_FEATURES_H
+#define NXP_FEATURES_H
+
+#define STRMAX_1 40
+#define STRMAX_2 100
+#define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+#define FW_DLL_EXTENSION ".so"
+
+#define FW_MOBILE_MAJOR_NUMBER_PN553 0x01
+#define FW_MOBILE_MAJOR_NUMBER_PN551 0x05
+#define FW_MOBILE_MAJOR_NUMBER_PN48AD 0x01
+
+#define NFA_EE_MAX_EE_SUPPORTED 4
+
+#define JCOP_VER_3_1    1
+#define JCOP_VER_3_2    2
+#define JCOP_VER_3_3    3
+#define JCOP_VER_4_0    4
+
+typedef enum {
+    pn547C2 = 0x01,
+    pn65T,
+    pn548C2,
+    pn66T,
+    pn551,
+    pn67T,
+    pn553,
+    pn80T,
+    pn557,
+    pn81T
+}tNFC_chipType;
+
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    /*Flags common to all chip types*/
+    uint8_t _NXP_NFCC_EMPTY_DATA_PACKET                     : 1;
+    uint8_t _GEMALTO_SE_SUPPORT                             : 1;
+    uint8_t _NFCC_I2C_READ_WRITE_IMPROVEMENT                : 1;
+    uint8_t _NFCC_MIFARE_TIANJIN                            : 1;
+    uint8_t _NFCC_MW_RCVRY_BLK_FW_DNLD                      : 1;
+    uint8_t _NFCC_DYNAMIC_DUAL_UICC                         : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH              : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH           : 1;
+    uint8_t _NFCC_FW_WA                                     : 1;
+    uint8_t _NFCC_FORCE_NCI1_0_INIT                         : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT                         : 1;
+    uint8_t _NFCC_SPI_FW_DOWNLOAD_SYNC                      : 1;
+    uint8_t _HW_ANTENNA_LOOP4_SELF_TEST                     : 1;
+    uint8_t _NFCEE_REMOVED_NTF_RECOVERY                     : 1;
+    uint8_t _NFCC_FORCE_FW_DOWNLOAD                         : 1;
+    uint8_t _UICC_CREATE_CONNECTIVITY_PIPE                  : 1;
+    uint8_t _NFCC_AID_MATCHING_PLATFORM_CONFIG              : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT_PROP                    : 1;
+    uint8_t _NXP_NFC_UICC_ETSI12                            : 1;
+    uint8_t _NFA_EE_MAX_EE_SUPPORTED                        : 3;
+}tNfc_nfccFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _ESE_EXCLUSIVE_WIRED_MODE                    : 2;
+    uint8_t _ESE_WIRED_MODE_RESUME                       : 2;
+    uint8_t _ESE_WIRED_MODE_TIMEOUT                      : 2;
+    uint8_t _ESE_PN67T_RESET                             : 2;
+    uint8_t _ESE_APDU_GATE_RESET                         : 2;
+    uint8_t _ESE_WIRED_MODE_DISABLE_DISCOVERY            : 1;
+    uint8_t _LEGACY_APDU_GATE                            : 1;
+    uint8_t _TRIPLE_MODE_PROTECTION                      : 1;
+    uint8_t _ESE_FELICA_CLT                              : 1;
+    uint8_t _WIRED_MODE_STANDBY_PROP                     : 1;
+    uint8_t _WIRED_MODE_STANDBY                          : 1;
+    uint8_t _ESE_DUAL_MODE_PRIO_SCHEME                   : 2;
+    uint8_t _ESE_FORCE_ENABLE                            : 1;
+    uint8_t _ESE_RESET_METHOD                            : 1;
+    uint8_t _EXCLUDE_NV_MEM_DEPENDENCY                   : 1;
+    uint8_t _ESE_ETSI_READER_ENABLE                      : 1;
+    uint8_t _ESE_SVDD_SYNC                               : 1;
+    uint8_t _NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION  : 1;
+    uint8_t _ESE_JCOP_DWNLD_PROTECTION                   : 1;
+    uint8_t _UICC_HANDLE_CLEAR_ALL_PIPES                 : 1;
+    uint8_t _GP_CONTINOUS_PROCESSING                     : 1;
+    uint8_t _ESE_DWP_SPI_SYNC_ENABLE                     : 1;
+    uint8_t _ESE_ETSI12_PROP_INIT                        : 1;
+    uint8_t _ESE_WIRED_MODE_PRIO                         : 1;
+    uint8_t _ESE_UICC_EXCLUSIVE_WIRED_MODE               : 1;
+    uint8_t _ESE_POWER_MODE                              : 1;
+    uint8_t _ESE_P73_ISO_RST                             : 1;
+    uint8_t _BLOCK_PROPRIETARY_APDU_GATE                 : 1;
+    uint8_t _JCOP_WA_ENABLE                              : 1;
+    uint8_t _NXP_LDR_SVC_VER_2                           : 1;
+    uint8_t _NXP_ESE_VER                                 : 3;
+}tNfc_eseFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _NFCC_RESET_RSP_LEN;
+}tNfc_platformFeatureList;
+
+typedef struct {
+    uint8_t _NCI_INTERFACE_UICC_DIRECT;
+    uint8_t _NCI_INTERFACE_ESE_DIRECT;
+    uint8_t _NCI_PWR_LINK_PARAM_CMD_SIZE;
+    uint8_t _NCI_EE_PWR_LINK_ALWAYS_ON;
+    uint8_t _NFA_EE_MAX_AID_ENTRIES;
+    uint8_t _NFC_NXP_AID_MAX_SIZE_DYN : 1;
+    uint8_t _FW_LIB_PATH[STRMAX_2];
+    uint8_t _PLATFORM_LIB_PATH[STRMAX_2];
+    uint8_t _PKU_LIB_PATH[STRMAX_2];
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_LEN;
+    uint8_t  _FW_MOBILE_MAJOR_NUMBER;
+}tNfc_nfcMwFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t nfcNxpEse : 1;
+    tNFC_chipType chipType;
+    tNfc_nfccFeatureList nfccFL;
+    tNfc_eseFeatureList eseFL;
+    tNfc_platformFeatureList platformFL;
+    tNfc_nfcMwFeatureList nfcMwFL;
+}tNfc_featureList;
+
+extern tNfc_featureList nfcFL;
+
+#define CONFIGURE_FEATURELIST(chipType) {                                   \
+        nfcFL.chipType = chipType;                                          \
+        nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN = true;                     \
+        if(chipType == pn81T) {                                             \
+            nfcFL.chipType = pn557;                                         \
+        }                                                                   \
+        else if(chipType == pn80T) {                                        \
+            nfcFL.chipType = pn553;                                         \
+        }                                                                   \
+        else if(chipType == pn67T) {                                        \
+            nfcFL.chipType = pn551;                                         \
+        }                                                                   \
+        else if(chipType == pn66T) {                                        \
+            nfcFL.chipType = pn548C2;                                       \
+        }                                                                   \
+        else if(chipType == pn65T) {                                        \
+            nfcFL.chipType = pn547C2;                                       \
+        }                                                                   \
+        if ((chipType == pn65T) || (chipType == pn66T) ||                   \
+                (chipType == pn67T) || (chipType == pn80T) ||               \
+                (chipType == pn81T)) {                                      \
+            nfcFL.nfcNxpEse = true;                                         \
+            CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType)                   \
+        } \
+        else {                                                              \
+            nfcFL.nfcNxpEse = false;                                        \
+            CONFIGURE_FEATURELIST_NFCC(chipType)                            \
+        }                                                                   \
+        \
+        \
+}
+
+#define CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType) {                     \
+        nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET = true;                    \
+        nfcFL.nfccFL._GEMALTO_SE_SUPPORT = true;                            \
+        \
+        \
+        nfcFL.eseFL._ESE_EXCLUSIVE_WIRED_MODE = 1;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_RESUME = 2;                             \
+        nfcFL.eseFL._ESE_PN67T_RESET = 1;                                   \
+        nfcFL.eseFL._ESE_APDU_GATE_RESET = 2;                               \
+        nfcFL.eseFL._NXP_ESE_VER = JCOP_VER_4_0;                            \
+        nfcFL.eseFL._NXP_LDR_SVC_VER_2 = true;                              \
+        \
+        \
+        if (chipType == pn81T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn557)                               \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                   \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+        }                                                                   \
+        if (chipType == pn80T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn553)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;              \
+            nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                \
+        }                                                                   \
+        else if (chipType == pn67T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn551)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn66T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn548C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn65T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn547C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = true;           \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+        }                                                                   \
+}
+
+
+#define CONFIGURE_FEATURELIST_NFCC(chipType) {                              \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT = 3;                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = false;              \
+        nfcFL.eseFL._LEGACY_APDU_GATE = false;                              \
+        nfcFL.eseFL._TRIPLE_MODE_PROTECTION = false;                        \
+        nfcFL.eseFL._ESE_FELICA_CLT = false;                                \
+        nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = false;                       \
+        nfcFL.eseFL._WIRED_MODE_STANDBY = false;                            \
+        nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT;                                \
+        nfcFL.eseFL._ESE_FORCE_ENABLE = false;                              \
+        nfcFL.eseFL._ESE_RESET_METHOD = false;                              \
+        nfcFL.eseFL._ESE_ETSI_READER_ENABLE = false;                        \
+        nfcFL.eseFL._ESE_SVDD_SYNC = false;                                 \
+        nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = false;    \
+        nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = false;                     \
+        nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = false;                   \
+        nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                       \
+        nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = false;                       \
+        nfcFL.eseFL._ESE_ETSI12_PROP_INIT = false;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_PRIO = false;                           \
+        nfcFL.eseFL._ESE_UICC_EXCLUSIVE_WIRED_MODE = false;                 \
+        nfcFL.eseFL._ESE_POWER_MODE = false;                                \
+        nfcFL.eseFL._ESE_P73_ISO_RST = false;                               \
+        nfcFL.eseFL._BLOCK_PROPRIETARY_APDU_GATE = false;                   \
+        nfcFL.eseFL._JCOP_WA_ENABLE = true;                                 \
+        nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = false;                     \
+        nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                          \
+        nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                    \
+        \
+        \
+        nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0;                           \
+        \
+        \
+        nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x00;                    \
+        nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x00;                     \
+        nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;                  \
+        nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                    \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x023CU;          \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C80U;             \
+        nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                             \
+        FW_MOBILE_MAJOR_NUMBER_PN48AD;                                      \
+        \
+        \
+        if (chipType == pn557)                                              \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                      \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn553)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = true;                    \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = true;                    \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = false;        \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._JCOP_WA_ENABLE = false;                            \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn553tc_fw", "libpn553tc_fw_platform",            \
+                    "libpn553tc_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN553;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn551)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x11U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn551_fw", "libpn551_fw_platform",                \
+                    "libpn551_fw_pku")                                      \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN551;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn548C2)                                       \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn548ad_fw", "libpn548ad_fw_platform",            \
+                    "libpn548ad_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            \
+            \
+        }                                                                   \
+        else if(chipType == pn547C2)                                        \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = false;          \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x81;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x82;                 \
+            \
+            \
+            SRTCPY_FW("libpn547_fw", "libpn547_fw_platform",                \
+                    "libpn547_fw_pku")                                      \
+            \
+            \
+        }                                                                   \
+}
+#ifdef __cplusplus
+#define SRTCPY_FW(str1,str2,str3)
+#else
+#define SRTCPY_FW(str1, str2,str3)                                                      \
+        snprintf(nfcFL.nfcMwFL._FW_LIB_PATH, STRMAX_2, "%s%s%s",                        \
+                FW_DLL_ROOT_DIR, str1, FW_DLL_EXTENSION);                               \
+                snprintf(nfcFL.nfcMwFL._PLATFORM_LIB_PATH, STRMAX_2, "%s%s%s",          \
+                        FW_DLL_ROOT_DIR, str2, FW_DLL_EXTENSION);                       \
+                        snprintf(nfcFL.nfcMwFL._PKU_LIB_PATH, STRMAX_2, "%s%s%s",       \
+                                FW_DLL_ROOT_DIR, str3, FW_DLL_EXTENSION);
+#endif
+#endif
diff --git a/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
index 5a18233..e73c5bc 100644
--- a/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
+++ b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,6 +23,114 @@
 #include <hardware/hardware.h>
 #include <hardware/nfc.h>
 
+#define NFC_NCI_NXP_PN54X_HARDWARE_MODULE_ID "nfc_nci.nqx"
+
+typedef struct
+{
+    struct nfc_nci_device nci_device;
+
+    /* Local definitions */
+    int (*ioctl)(const struct nfc_nci_device *p_dev, long arg, void *p_data);
+    int(*check_fw_dwnld_flag)(const struct nfc_nci_device *p_dev, uint8_t* param1);
+} pn547_dev_t;
+
+#define MAX_IOCTL_TRANSCEIVE_CMD_LEN  256
+#define MAX_IOCTL_TRANSCEIVE_RESP_LEN 256
+#define MAX_ATR_INFO_LEN              128
+
+/*
+ * Data structures provided below are used of Hal Ioctl calls
+ */
+/*
+ * nfc_nci_ExtnCmd_t shall contain data for commands used for transceive command in ioctl
+ */
+typedef struct
+{
+    uint16_t cmd_len;
+    uint8_t  p_cmd[MAX_IOCTL_TRANSCEIVE_CMD_LEN];
+} nfc_nci_ExtnCmd_t;
+
+/*
+ * nfc_nci_ExtnRsp_t shall contain response for command sent in transceive command
+ */
+typedef struct
+{
+    uint16_t rsp_len;
+    uint8_t  p_rsp[MAX_IOCTL_TRANSCEIVE_RESP_LEN];
+} nfc_nci_ExtnRsp_t;
+/*
+ * InputData_t :ioctl has multiple subcommands
+ * Each command has corresponding input data which needs to be populated in this
+ */
+typedef union {
+    uint16_t          bootMode;
+    uint8_t           halType;
+    nfc_nci_ExtnCmd_t nciCmd;
+    uint32_t          timeoutMilliSec;
+    long              nfcServicePid;
+}InputData_t;
+/*
+ * nfc_nci_ExtnInputData_t :Apart from InputData_t, there are context data
+ * which is required during callback from stub to proxy.
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, context data
+ * is exposed to libnfc (Not encapsulated).
+ */
+typedef struct {
+    /*
+     * context to be used/updated only by users of proxy & stub of Nfc.hal
+     * i.e NfcAdaptation & Nfc hidl
+     */
+    void*       context;
+    InputData_t data;
+}nfc_nci_ExtnInputData_t;
+
+/*
+ * outputData_t :ioctl has multiple commands/responses
+ * This contains the output types for each ioctl.
+ */
+typedef union{
+    uint32_t            status;
+    nfc_nci_ExtnRsp_t   nciRsp;
+    uint8_t             nxpNciAtrInfo[MAX_ATR_INFO_LEN];
+    uint32_t            p61CurrentState;
+    uint16_t            fwUpdateInf;
+    uint16_t            fwDwnldStatus;
+    uint16_t            fwMwVerStatus;
+    uint8_t             chipType;
+}outputData_t;
+
+/*
+ * nfc_nci_ExtnOutputData_t :Apart from outputData_t, there are other information
+ * which is required during callback from stub to proxy.
+ * For ex (context, result of the operation , type of ioctl which was completed).
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, these data
+ * is exposed(Not encapsulated).
+ */
+typedef struct {
+    /*
+     * ioctlType, result & context to be used/updated only by users of
+     * proxy & stub of Nfc.hal.
+     * i.e, NfcAdaptation & Nfc hidl
+     * These fields shall not be used by libnfc or halimplementation
+     */
+    uint64_t     ioctlType;
+    uint32_t     result;
+    void*        context;
+    outputData_t data;
+}nfc_nci_ExtnOutputData_t;
+
+/*
+ * nfc_nci_IoctlInOutData_t :data structure for input & output
+ * to be sent for ioctl command. input is populated by client/proxy side
+ * output is provided from server/stub to client/proxy
+ */
+typedef struct {
+    nfc_nci_ExtnInputData_t  inp;
+    nfc_nci_ExtnOutputData_t out;
+}nfc_nci_IoctlInOutData_t;
+
 /* NXP HAL functions */
 
 int phNxpNciHal_open(nfc_stack_callback_t* p_cback,
diff --git a/halimpl/pn54x/libnfc-brcm.conf b/halimpl/pn54x/libnfc-brcm.conf
index c32dbfc..32e5a3d 100644
--- a/halimpl/pn54x/libnfc-brcm.conf
+++ b/halimpl/pn54x/libnfc-brcm.conf
@@ -14,7 +14,7 @@
 
 ###############################################################################
 # File used for NFA storage
-NFA_STORAGE="/data/vendor/nfc"
+NFA_STORAGE="/data/nfc"
 
 ###############################################################################
 # Snooze Mode Settings
@@ -353,8 +353,25 @@
 PRESERVE_STORAGE=0x01
 
 ###############################################################################
+# Override the stack default for NFA_EE_MAX_EE_SUPPORTED set in nfc_target.h.
+# The value is set to 4 by default as it assumes we will additionally discover
+# 0xF2, 0xF3, and 0xF4. If a platform will exclude any SE, this value can be
+# reduced so that the stack will not wait any longer than necessary.
+
+# Maximum EE supported number
+# NXP PN547C2 0x02
+# NXP PN65T 0x03
+# NXP PN548C2 0x02
+# NXP PN66T 0x03
+# NXP PN551 0x02
+# NXP PN67T 0x03
+# NXP PN553 0x02
+# NXP PN80T 0x04
+NFA_MAX_EE_SUPPORTED=0x04
+
+###############################################################################
 # NCI Hal Module name
-NCI_HAL_MODULE="nfc_nci.pn54x"
+NCI_HAL_MODULE="nfc_nci.nqx"
 
 ##############################################################################
 # Deactivate notification wait time out in seconds used in ETSI Reader mode
@@ -390,7 +407,4 @@
 # Bail out mode
 #  If set to 1, NFCC is using bail out mode for either Type A or Type B poll.
 NFA_POLL_BAIL_OUT_MODE=0x01
-############################################################################## #
-#White list of Hosts
-#This values will be the Hosts(NFCEEs) in the HCI Network.
-    DEVICE_HOST_WHITE_LIST={80 : 81 : C0}
\ No newline at end of file
+#################################################################################
diff --git a/halimpl/pn54x/libnfc-brcm_NCI2_0.conf b/halimpl/pn54x/libnfc-brcm_NCI2_0.conf
index c4f6b73..0eca62c 100644
--- a/halimpl/pn54x/libnfc-brcm_NCI2_0.conf
+++ b/halimpl/pn54x/libnfc-brcm_NCI2_0.conf
@@ -14,7 +14,7 @@
 
 ###############################################################################
 #File used for NFA storage
-NFA_STORAGE="/data/vendor/nfc"
+NFA_STORAGE="/data/nfc"
 
 ###############################################################################
 #Snooze Mode Settings
diff --git a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
index c372dc0..a3d727c 100644
--- a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn544"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -76,7 +76,7 @@
 ## Set configuration optimization decision setting
 ## Enable    = 0x01
 ## Disable   = 0x00
-NXP_SET_CONFIG_ALWAYS=0x00
+NXP_SET_CONFIG_ALWAYS=0x01
 
 ###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
diff --git a/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf b/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf
new file mode 100644
index 0000000..49cb58a
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf
@@ -0,0 +1,265 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x)
+
+###############################################################################
+# Application options
+# Logging Levels
+# NXPLOG_DEFAULT_LOGLEVEL    0x01
+# ANDROID_LOG_DEBUG          0x03
+# ANDROID_LOG_WARN           0x02
+# ANDROID_LOG_ERROR          0x01
+# ANDROID_LOG_SILENT         0x00
+#
+NXPLOG_EXTNS_LOGLEVEL=0x03
+NXPLOG_NCIHAL_LOGLEVEL=0x03
+NXPLOG_NCIX_LOGLEVEL=0x03
+NXPLOG_NCIR_LOGLEVEL=0x03
+NXPLOG_FWDNLD_LOGLEVEL=0x03
+NXPLOG_TML_LOGLEVEL=0x03
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File location for Firmware
+#FW_STORAGE="/vendor/firmware/libpn548_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL       1
+#define CLK_SRC_PLL        2
+
+NXP_SYS_CLK_SRC_SEL=0x02
+
+###############################################################################
+# System clock frequency selection configuration
+#define CLK_FREQ_13MHZ         1
+#define CLK_FREQ_19_2MHZ       2
+#define CLK_FREQ_24MHZ         3
+#define CLK_FREQ_26MHZ         4
+#define CLK_FREQ_38_4MHZ       5
+#define CLK_FREQ_52MHZ         6
+
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x1A
+
+NXP_SYS_CLOCK_TO_CFG=0x01
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# NFCC Configuration Control
+# Allow NFCC to manage RF Config       0x01
+# Don't allow NFCC to manage RF Config 0x00
+NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01}
+
+###############################################################################
+# Standby enable settings
+#NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+# NXP TVDD configurations settings
+# Allow NFCC to configure External TVDD, There are currently three
+#configurations (1, 2 and 3) are supported, out of them only one can be
+#supported.
+
+NXP_EXT_TVDD_CFG=0x01
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A}
+
+###############################################################################
+#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC,
+#DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 15, 05,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D
+    }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set 01 ,to disable set to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01
+        }
+
+###############################################################################
+# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00
+NXP_I2C_FRAGMENTATION_ENABLED=0x00
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2B, 0D,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        60, 01, 0E,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+#                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
+#                                     A0, 53, 06, FF, FF, FF, FF, FF, FF,
+#                                     A0, 54, 06, 00, 00, 00, 00, 00, 00}
+
+###############################################################################
+# Default SE Options
+# No secure element 0x00
+# eSE               0x01
+# UICC              0x02
+
+NXP_DEFAULT_SE=0x07
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+
+NXP_NFC_CHIP=0x03
+
+###############################################################################
+# CE when Screen state is locked
+# Disable           0x00
+# Enable            0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+#Timeout in secs to get NFCEE Discover notification
+NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE  0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE  0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE  0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+
+###############################################################################
+#CHINA_TIANJIN_RF_SETTING
+#Enable  0x01
+#Disable 0x00
+NXP_CHINA_TIANJIN_RF_ENABLED=0x01
+
+###############################################################################
+#SWP_SWITCH_TIMEOUT_SETTING
+# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60].
+# Timeout in milliseconds, for example
+# No Timeout  0x00
+# 10 millisecond timeout 0x0A
+NXP_SWP_SWITCH_TIMEOUT=0x0A
diff --git a/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
index 58ec5d5..5a5fd07 100644
--- a/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN548C2_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn54x"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -93,10 +93,70 @@
 NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
 
 ###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
 ## Set configuration optimization decision setting
 ## Enable    = 0x01
 ## Disable   = 0x00
-NXP_SET_CONFIG_ALWAYS=0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 19, 06,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, 96, 01, 01
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
 
 ###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
@@ -108,6 +168,25 @@
 NXP_I2C_FRAGMENTATION_ENABLED=0x00
 
 ###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
 # Mifare Classic Key settings
 #NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
 #                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
diff --git a/halimpl/pn54x/libnfc-nxp-PN551_example.conf b/halimpl/pn54x/libnfc-nxp-PN551_example.conf
index 51655b6..990824f 100644
--- a/halimpl/pn54x/libnfc-nxp-PN551_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN551_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn54x"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -93,12 +93,72 @@
 NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 40, 0A}
 
 ###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
 ## Set configuration optimization decision setting
 ## Enable    = 0x01
 ## Disable   = 0x00
 NXP_SET_CONFIG_ALWAYS=0x00
 
 ###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 19, 06,
+    A0, EC, 01, 01,
+    A0, ED, 01, 00,
+    A0, 5E, 01, 01,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, 96, 01, 01
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
 NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 }
 
@@ -107,6 +167,25 @@
 NXP_I2C_FRAGMENTATION_ENABLED=0x00
 
 ###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
 # Mifare Classic Key settings
 #NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
 #                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
diff --git a/halimpl/pn54x/libnfc-nxp-PN553_example.conf b/halimpl/pn54x/libnfc-nxp-PN553_example.conf
index 160aad1..75466f4 100644
--- a/halimpl/pn54x/libnfc-nxp-PN553_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN553_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn553"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -87,12 +87,101 @@
 NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C}
 
 ###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DPC deactivated
+NXP_RF_CONF_BLK_1={
+20, 02, 5C, 01, A0, 0B, 58, 10, 90, 90, 78, 0F, 4E, 32, 00, 3D, 9F, 00, 00, 3D,
+9F, 00, 00, 50, 9F, 00, 00, 59, 9F, 00, 00, 5A, 9F, 00, 00, 64, 9F, 00, 00, 65,
+9F, 00, 00, 6E, 9F, 00, 00, 72, 9F, 00, 00, 79, 9F, 00, 00, 7B, 9F, 00, 00, 84,
+9F, 00, 00, 86, 9F, 00, 00, 8F, 9F, 00, 00, 91, 9F, 00, 00, 9A, 9F, 00, 00, A1,
+9F, 00, 00, A7, 1F, 00, 00, B0, 1F, 00, 00, B9, 1F, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DLMA Deactivated
+NXP_RF_CONF_BLK_2={
+20, 02, D6, 01, A0, 34, D2, 23, 04, 18, 07, 40, 00, 20, 40, 00, BE, 23, 60, 00,
+2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08, 00, DE, 54, 08, 02,
+00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02,
+00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08, 01, 00, 00, C8, 02,
+00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8, 00, 00, 00, 68, 00,
+00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00, 00, 00, 00, 00, 07, 00, 20, 40,
+00, BE, 23, 60, 00, 2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08,
+00, DE, 54, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08,
+02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08,
+01, 00, 00, C8, 02, 00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8,
+00, 00, 00, 68, 00, 00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
 # Set configuration optimization decision setting
 # Enable    = 0x01
 # Disable   = 0x00
 NXP_SET_CONFIG_ALWAYS=0x00
 
 ###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# eSE (SVDD) PWR REQ settings A0F2
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 - A037
+NXP_CORE_CONF_EXTN={20, 02, 25, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set
 # to 00 last bit
 NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 }
@@ -103,6 +192,25 @@
 NXP_I2C_FRAGMENTATION_ENABLED=0x00
 
 ###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
 # Mifare Classic Key settings
 #NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
 #                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
diff --git a/halimpl/pn54x/libnfc-nxp-PN557_example.conf b/halimpl/pn54x/libnfc-nxp-PN557_example.conf
index 17494b5..b8d925b 100644
--- a/halimpl/pn54x/libnfc-nxp-PN557_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN557_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn553"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -462,4 +462,4 @@
 # Timeout value in milliseconds to send response for Felica command received
 NXP_HCEF_CMD_RSP_TIMEOUT_VALUE=5000
 
-###############################################################################
\ No newline at end of file
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN65T_example.conf b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
index de8e654..e50eac8 100644
--- a/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn544"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -111,7 +111,7 @@
 ## Set configuration optimization decision setting
 ## Enable    = 0x01
 ## Disable   = 0x00
-NXP_SET_CONFIG_ALWAYS=0x00
+NXP_SET_CONFIG_ALWAYS=0x01
 
 ###############################################################################
 # Core configuration extensions
diff --git a/halimpl/pn54x/libnfc-nxp-PN66T_example.conf b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
index c77c60c..469646f 100644
--- a/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn54x"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -93,10 +93,75 @@
 NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
 
 ###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
 # Set configuration optimization decision setting
 # Enable    = 0x01
 # Disable   = 0x00
-NXP_SET_CONFIG_ALWAYS=0x00
+NXP_SET_CONFIG_ALWAYS=0x01
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# A0 9F 02 <svdd ON guard time (msec)> <svdd off guard time(msec)>
+NXP_CORE_CONF_EXTN={20, 02, 26, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 03,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, F2, 01, 01,
+    A0, 96, 01, 01,
+    A0, 9F, 02, 08, 08
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
 
 ###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set
@@ -109,6 +174,25 @@
 NXP_I2C_FRAGMENTATION_ENABLED=0x00
 
 ###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
 # Mifare Classic Key settings
 #NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
 #                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
diff --git a/halimpl/pn54x/libnfc-nxp-PN67T_example.conf b/halimpl/pn54x/libnfc-nxp-PN67T_example.conf
index 87930ba..b8ce7dd 100644
--- a/halimpl/pn54x/libnfc-nxp-PN67T_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN67T_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn54x"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -93,12 +93,77 @@
 NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
 
 ###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
 # Set configuration optimization decision setting
 # Enable    = 0x01
 # Disable   = 0x00
 NXP_SET_CONFIG_ALWAYS=0x00
 
 ###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# A0 9F 02 <svdd ON guard time (msec)> <svdd off guard time(msec)>
+NXP_CORE_CONF_EXTN={20, 02, 26, 09,
+    A0, EC, 01, 01,
+    A0, ED, 01, 03,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, DD, 01, 2D,
+    A0, F2, 01, 01,
+    A0, 96, 01, 01,
+    A0, 9F, 02, 08, 08
+    }
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set
 # to 00 last bit
 NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01 }
@@ -109,6 +174,25 @@
 NXP_I2C_FRAGMENTATION_ENABLED=0x00
 
 ###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
 # Mifare Classic Key settings
 #NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
 #                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
diff --git a/halimpl/pn54x/libnfc-nxp-PN80T_example.conf b/halimpl/pn54x/libnfc-nxp-PN80T_example.conf
index 3248bb1..1934ca2 100644
--- a/halimpl/pn54x/libnfc-nxp-PN80T_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN80T_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn553"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
@@ -87,12 +87,104 @@
 NXP_EXT_TVDD_CFG_2={20, 02, 0F, 01, A0, 0E, 0B, 11, 01, C2, B2, 00, B2, 1E, 1F, 00, D0, 0C}
 
 ###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DPC deactivated
+NXP_RF_CONF_BLK_1={
+20, 02, 5C, 01, A0, 0B, 58, 10, 90, 90, 78, 0F, 4E, 32, 00, 3D, 9F, 00, 00, 3D,
+9F, 00, 00, 50, 9F, 00, 00, 59, 9F, 00, 00, 5A, 9F, 00, 00, 64, 9F, 00, 00, 65,
+9F, 00, 00, 6E, 9F, 00, 00, 72, 9F, 00, 00, 79, 9F, 00, 00, 7B, 9F, 00, 00, 84,
+9F, 00, 00, 86, 9F, 00, 00, 8F, 9F, 00, 00, 91, 9F, 00, 00, 9A, 9F, 00, 00, A1,
+9F, 00, 00, A7, 1F, 00, 00, B0, 1F, 00, 00, B9, 1F, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# DLMA Deactivated
+NXP_RF_CONF_BLK_2={
+20, 02, D6, 01, A0, 34, D2, 23, 04, 18, 07, 40, 00, 20, 40, 00, BE, 23, 60, 00,
+2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08, 00, DE, 54, 08, 02,
+00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02,
+00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08, 01, 00, 00, C8, 02,
+00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8, 00, 00, 00, 68, 00,
+00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00, 00, 00, 00, 00, 07, 00, 20, 40,
+00, BE, 23, 60, 00, 2B, 13, 40, 00, B8, 21, 60, 00, 38, 35, 00, 00, 18, 46, 08,
+00, DE, 54, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 08,
+02, 00, 00, 08, 02, 00, 00, 08, 02, 00, 00, 48, 01, 00, 00, 08, 03, 00, 00, 08,
+01, 00, 00, C8, 02, 00, 00, C8, 00, 00, 00, 88, 02, 00, 00, 48, 02, 00, 00, B8,
+00, 00, 00, 68, 00, 00, 00, 18, 00, 00, 00, 08, 02, 00, 00, 00, 00
+}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
 # Set configuration optimization decision setting
 # Enable    = 0x01
 # Disable   = 0x00
 NXP_SET_CONFIG_ALWAYS=0x00
 
 ###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+# eSE (SVDD) PWR REQ settings A0F2
+# Window size A0D8
+# DWP Speed   A0D5
+# How eSE connected to PN553 A012
+# UICC2 bit rate A0D1
+# SWP1A interface A0D4
+# DWP intf behavior config, SVDD Load activated by default if set to 0x31 A037
+NXP_CORE_CONF_EXTN={20, 02, 29, 0A,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 40, 01, 01,
+    A0, D1, 01, 02,
+    A0, D4, 01, 01,
+    A0, 37, 01, 35,
+    A0, D8, 01, 02,
+    A0, D5, 01, 0A
+   }
+#       A0, F2, 01, 01,
+#       A0, 40, 01, 01,
+#       A0, 41, 01, 02,
+#       A0, 43, 01, 04,
+#       A0, 02, 01, 01,
+#       A0, 03, 01, 11,
+#       A0, 07, 01, 03,
+#       A0, 08, 01, 01
+#       }
+
+###############################################################################
 # Core configuration rf field filter settings to enable set to 01 to disable set
 # to 00 last bit
 NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 00 }
@@ -103,6 +195,25 @@
 NXP_I2C_FRAGMENTATION_ENABLED=0x00
 
 ###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2E, 0E,
+        28, 01, 00,
+        21, 01, 00,
+        30, 01, 08,
+        31, 01, 03,
+        32, 01, 60,
+        38, 01, 01,
+        33, 04, 01, 02, 03, 04,
+        54, 01, 06,
+        50, 01, 02,
+        5B, 01, 00,
+        80, 01, 01,
+        81, 01, 01,
+        82, 01, 0E,
+        18, 01, 01
+        }
+
+###############################################################################
 # Mifare Classic Key settings
 #NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
 #                                     A0, 52, 06, D3, F7, D3, F7, D3, F7,
diff --git a/halimpl/pn54x/libnfc-nxp-PN81T_example.conf b/halimpl/pn54x/libnfc-nxp-PN81T_example.conf
index a11bfcb..d0f3aef 100644
--- a/halimpl/pn54x/libnfc-nxp-PN81T_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN81T_example.conf
@@ -17,7 +17,7 @@
 
 ###############################################################################
 # Nfc Device Node name
-NXP_NFC_DEV_NODE="/dev/pn553"
+NXP_NFC_DEV_NODE="/dev/nq-nci"
 
 ###############################################################################
 # Extension for Mifare reader enable
diff --git a/halimpl/pn54x/nfc_nci.c b/halimpl/pn54x/nfc_nci.c
index 29193fc..3bda6f8 100644
--- a/halimpl/pn54x/nfc_nci.c
+++ b/halimpl/pn54x/nfc_nci.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,7 +26,6 @@
 #include <phNxpNciHal_Adaptation.h>
 #include <string.h>
 #include <stdlib.h>
-#include "hal_nxpnfc.h"
 /*****************************************************************************
  * NXP NCI HAL Function implementations.
  *****************************************************************************/
@@ -37,15 +39,16 @@
 ** Returns          0 if successful
 **
 *******************************************************************************/
-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;
+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;
 
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
-  retval = phNxpNciHal_open(p_hal_cback, p_hal_data_callback);
+    pn547_dev_t *dev = (pn547_dev_t*) p_dev;
+    retval = phNxpNciHal_open(p_hal_cback, p_hal_data_callback);
 
-  return retval;
+    return retval;
 }
 
 /*******************************************************************************
@@ -57,13 +60,14 @@
 ** Returns          Number of bytes successfully written to NFCC.
 **
 *******************************************************************************/
-static int hal_write(const struct nfc_nci_device* p_dev, uint16_t data_len,
-                     const uint8_t* p_data) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_write(const struct nfc_nci_device *p_dev, uint16_t data_len,
+        const uint8_t *p_data)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_write(data_len, p_data);
-  return retval;
+    retval = phNxpNciHal_write(data_len, p_data);
+    return retval;
 }
 
 /*******************************************************************************
@@ -75,13 +79,13 @@
 ** Returns          status code of ioctl.
 **
 *******************************************************************************/
-static int hal_ioctl(const struct nfc_nci_device* p_dev, long arg,
-                     void* p_data) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_ioctl(const struct nfc_nci_device *p_dev, long arg, void *p_data)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_ioctl(arg, p_data);
-  return retval;
+    retval = phNxpNciHal_ioctl(arg, p_data);
+    return retval;
 }
 
 /*******************************************************************************
@@ -94,13 +98,14 @@
 ** Returns          0 if successful
 **
 *******************************************************************************/
-static int hal_core_initialized(const struct nfc_nci_device* p_dev,
-                                uint8_t* p_core_init_rsp_params) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_core_initialized(const struct nfc_nci_device *p_dev,
+        uint8_t* p_core_init_rsp_params)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_core_initialized(p_core_init_rsp_params);
-  return retval;
+    retval = phNxpNciHal_core_initialized(p_core_init_rsp_params);
+    return retval;
 }
 
 /*******************************************************************************
@@ -112,12 +117,13 @@
 ** Returns          0 if successful
 **
 *******************************************************************************/
-static int hal_pre_discover(const struct nfc_nci_device* p_dev) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_pre_discover(const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_pre_discover();
-  return retval;
+    retval = phNxpNciHal_pre_discover();
+    return retval;
 }
 
 /*******************************************************************************
@@ -129,12 +135,13 @@
 ** Returns          0 if successful
 **
 *******************************************************************************/
-static int hal_close(const struct nfc_nci_device* p_dev) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_close(const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_close();
-  return retval;
+    retval = phNxpNciHal_close();
+    return retval;
 }
 
 /*******************************************************************************
@@ -146,12 +153,13 @@
 ** Returns          0 if successful
 **
 *******************************************************************************/
-static int hal_control_granted(const struct nfc_nci_device* p_dev) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_control_granted(const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_control_granted();
-  return retval;
+    retval = phNxpNciHal_control_granted();
+    return retval;
 }
 
 /*******************************************************************************
@@ -163,12 +171,13 @@
 ** Returns          0 if successful
 **
 *******************************************************************************/
-static int hal_power_cycle(const struct nfc_nci_device* p_dev) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_power_cycle(const struct nfc_nci_device *p_dev)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_power_cycle();
-  return retval;
+    retval = phNxpNciHal_power_cycle();
+    return retval;
 }
 
 /*******************************************************************************
@@ -180,12 +189,12 @@
 ** Returns          true if successful otherwise false.
 **
 *******************************************************************************/
-static int hal_get_fw_dwnld_flag(const struct nfc_nci_device* p_dev,
-                                 uint8_t* fwDnldRequest) {
-  int retval = 0;
-  nxpnfc_nci_device_t* dev = (nxpnfc_nci_device_t*)p_dev;
+static int hal_get_fw_dwnld_flag(const struct nfc_nci_device *p_dev, uint8_t* fwDnldRequest)
+{
+    int retval = 0;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
 
-  retval = phNxpNciHal_getFWDownloadFlag(fwDnldRequest);
+    retval = phNxpNciHal_getFWDownloadFlag(fwDnldRequest);
 
   return retval;
 }
@@ -219,34 +228,38 @@
 **
 *******************************************************************************/
 static int nfc_open(const hw_module_t* module, const char* name,
-                    hw_device_t** device) {
-  ALOGD("%s: enter; name=%s", __func__, name);
-  int retval = 0; /* 0 is ok; -1 is error */
-  nxpnfc_nci_device_t* dev = NULL;
-  if (strcmp(name, NFC_NCI_CONTROLLER) == 0) {
-    dev = calloc(1, sizeof(nxpnfc_nci_device_t));
-    if (dev == NULL) {
-      retval = -EINVAL;
-    } else {
-      /* 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;
+        hw_device_t** device)
+{
+    ALOGD("%s: enter; name=%s", __FUNCTION__, name);
+    int retval = 0; /* 0 is ok; -1 is error */
+    pn547_dev_t *dev = NULL;
+    if (strcmp(name, NFC_NCI_CONTROLLER) == 0)
+    {
+        dev = calloc(1, sizeof(pn547_dev_t));
+        if(dev == NULL)
+        {
+            retval = -EINVAL;
+        }
+        else
+        {
+            /* 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;
-      dev->ioctl = hal_ioctl;
-      dev->check_fw_dwnld_flag = hal_get_fw_dwnld_flag;
-      *device = (hw_device_t*)dev;
-    }
+            /* NCI HAL method pointers */
+            dev->nci_device.open = hal_open;
+            dev->nci_device.write = hal_write;
+            dev->ioctl = hal_ioctl;
+            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;
+            dev->check_fw_dwnld_flag = hal_get_fw_dwnld_flag;
+            *device = (hw_device_t*) dev;
+        }
   } else {
     retval = -EINVAL;
   }
diff --git a/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c b/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
index b82624c..c45bb23 100644
--- a/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
+++ b/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -1070,8 +1073,8 @@
                              max_len)) {
     NXPLOG_NCIHAL_E(
         "Invalid nfc device node name keeping the default device node "
-        "/dev/pn54x");
-    strcpy((char*)nfc_dev_node, "/dev/pn54x");
+        "/dev/nq-nci");
+    strlcpy((char*)nfc_dev_node, "/dev/nq-nci", max_len);
   }
 
   gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
diff --git a/halimpl/pn54x/tml/phOsalNfc_Timer.c b/halimpl/pn54x/tml/phOsalNfc_Timer.c
index 7e9f837..dc9c82d 100644
--- a/halimpl/pn54x/tml/phOsalNfc_Timer.c
+++ b/halimpl/pn54x/tml/phOsalNfc_Timer.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/halimpl/pn54x/tml/phTmlNfc.c b/halimpl/pn54x/tml/phTmlNfc.c
index fecfac2..9f4f8aa 100644
--- a/halimpl/pn54x/tml/phTmlNfc.c
+++ b/halimpl/pn54x/tml/phTmlNfc.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
  * Copyright (C) 2015 NXP Semiconductors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/halimpl/pn54x/tml/phTmlNfc_i2c.h b/halimpl/pn54x/tml/phTmlNfc_i2c.h
index 01dcd43..8903bc6 100644
--- a/halimpl/pn54x/tml/phTmlNfc_i2c.h
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.h
@@ -41,7 +41,7 @@
  * PN544_SET_PWR(1): power on
  * PN544_SET_PWR(2): reset and power on with firmware download enabled
  */
-#define PN544_SET_PWR _IOW(PN544_MAGIC, 0x01, long)
+#define PN544_SET_PWR    _IOW(PN544_MAGIC, 0x01, unsigned int)
 
 NFCSTATUS phTmlNfc_i2c_get_p61_power_state(void* pDevHandle);
 NFCSTATUS phTmlNfc_i2c_set_p61_power_state(void* pDevHandle, long arg);
@@ -57,19 +57,19 @@
  * level 1 = Enable power
  * level 0 = Disable power
  */
-#define P61_SET_SPI_PWR _IOW(PN544_MAGIC, 0x02, long)
+#define P61_SET_SPI_PWR    _IOW(PN544_MAGIC, 0x02, unsigned int)
 
 /* SPI or DWP can call this ioctl to get the current
  * power state of P61
  *
 */
-#define P61_GET_PWR_STATUS _IOR(PN544_MAGIC, 0x03, long)
+#define P61_GET_PWR_STATUS    _IOR(PN544_MAGIC, 0x03, unsigned int)
 
 /* DWP side this ioctl will be called
  * level 1 = Wired access is enabled/ongoing
  * level 0 = Wired access is disalbed/stopped
 */
-#define P61_SET_WIRED_ACCESS _IOW(PN544_MAGIC, 0x04, long)
+#define P61_SET_WIRED_ACCESS _IOW(PN544_MAGIC, 0x04, unsigned int)
 
 /*
   NFC Init will call the ioctl to register the PID with the i2c driver
diff --git a/halimpl/pn54x/utils/phNxpConfig.cpp b/halimpl/pn54x/utils/phNxpConfig.cpp
index 2908bca..acfe888 100644
--- a/halimpl/pn54x/utils/phNxpConfig.cpp
+++ b/halimpl/pn54x/utils/phNxpConfig.cpp
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2011-2012 Broadcom Corporation
  *
@@ -36,14 +38,28 @@
  *
  ******************************************************************************/
 
+ /**
+  * @file phNxpConfig.cpp
+  * @date 24 Aug 2016
+  * @brief File containing code for dynamic selection of config files based on target.
+  *
+  * The target device has to be configured with some primary setting while booting.So a
+  * config file will be picked while the target is booted. Here based on the target device
+  * a configuration file will be selected dynamically and the device will be configured.
+  */
+
 #include <phNxpConfig.h>
 #include <stdio.h>
 #include <string>
 #include <vector>
 #include <list>
 #include <sys/stat.h>
+#include <stdlib.h>
 
 #include <phNxpLog.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <errno.h>
 
 #if GENERIC_TARGET
 const char alternative_config_path[] = "/data/vendor/nfc/";
@@ -79,11 +95,57 @@
 const char nxp_rf_config_path[] =
         "/system/vendor/libnfc-nxp_RF.conf";
 
-using namespace ::std;
+/**
+ *  @brief target platform ID values.
+ */
+
+typedef enum
+{
+  CONFIG_GENERIC                         = 0x00,
+  MTP_TYPE_DEFAULT                       = 0x01, /**< default MTP config. DC DC ON */
+  QRD_TYPE_DEFAULT                       = 0x02, /**< default QRD config DC DC OFF */
+  MTP_TYPE_1                             = 0x03, /**< mtp config type1 : newer chip */
+  MTP_TYPE_2                             = 0x04, /**< mtp config type2 TBD */
+  QRD_TYPE_1                             = 0x05, /**< qrd config type1 DC DC ON*/
+  QRD_TYPE_2                             = 0x06, /**< qrd config type2  Newer chip */
+  MTP_TYPE_NQ3XX                         = 0x07, /**< mtp config : for NQ3XX chip */
+  QRD_TYPE_NQ3XX                         = 0x08, /**< qrd config : for NQ3XX chip */
+  MTP_TYPE_NQ4XX                         = 0x09, /**< mtp config : for NQ4XX chip */
+  QRD_TYPE_NQ4XX                         = 0x10, /**< qrd config : for NQ4XX chip */
+  DEFAULT_CONFIG                         = QRD_TYPE_DEFAULT, /**< default is qrd default config */
+  CONFIG_INVALID                         = 0xFF
+} CONFIGIDVALUE;
+
+/**
+ *  @brief Defines the soc_id values for different targets.
+ */
+
+typedef enum
+{
+  TARGET_GENERIC                       = 0x00,/**< new targets */
+  TARGET_MSM8952                       = 264, /**< 8952 target */
+  TARGET_MSM8976                       = 278, /**< 8976 target */
+  TARGET_MSM8937                       = 294, /**< 8937 target */
+  TARGET_MSM8953                       = 293, /**< 8953 target */
+  TARGET_MSM8996                       = 246, /**< 8996 target*/
+  TARGET_MSM8909                       = 245, /**< 8909w target */
+  TARGET_MSM8998                       = 292, /**< 8998 target */
+  TARGET_MSM8997                       = 306, /**< 8997 target */
+  TARGET_MSM8917                       = 303, /**< 8917 target */
+  TARGET_MSM8940                       = 313, /**< 8940 target */
+  TARGET_SDM660                        = 317, /**< SDM660 target */
+  TARGET_SDM630                        = 318, /**< SDM630 target */
+  TARGET_SDM845                        = 321, /**< SDM845 target */
+  TARGET_DEFAULT                       = TARGET_GENERIC, /**< new targets */
+  TARGET_INVALID                       = 0xFF
+} TARGETTYPE;
+
+using namespace::std;
 
 namespace nxp {
 
 void readOptionalConfig(const char* optional);
+void findConfigFilePathFromTransportConfigPaths(const string& configName, string& filePath);
 
 class CNfcParam : public string {
  public:
@@ -120,6 +182,8 @@
  private:
   CNfcConfig();
   bool readConfig(const char* name, bool bResetContent);
+  int     file_exist (const char* filename);
+  int     getconfiguration_id (char * config_file);
   void moveFromList();
   void moveToList();
   void add(const CNfcParam* pParam);
@@ -127,18 +191,275 @@
   bool isAllowed(const char* name);
   list<const CNfcParam*> m_list;
   bool mValidFile;
+  bool    mDynamConfig;
   unsigned long m_timeStamp;
   unsigned long m_timeStampRF;
   unsigned long m_timeStampTransit;
   string mCurrentFile;
 
   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; }
 };
 
+/**
+ * @brief This function reads the hardware information from the given path.
+ *
+ * This function receives the path and then reads the hardware information
+ * from the file present in the given path. It reads the details like whether
+ * it is QRD or MTP. It reads the data from that file and stores in buffer.
+ * It also receives a count which tells the number of characters to be read
+ * Finally the length of the buffer is returned.
+ *
+ * @param path The path where the file containing hardware details to be read.
+ * @param buff The hardware details that is read from that path will be stored here.
+ * @param count It represents the number of characters to be read from that file.
+ * @return It returns the length of the buffer.
+ */
+
+static int read_line_from_file(const char *path, char *buf, size_t count)
+{
+    char *fgets_ret = NULL;
+    FILE *fd = NULL;
+    int rv = 0;
+
+    // opens the file to read the HW_PLATFORM detail of the target
+    fd = fopen(path, "r");
+    if (fd == NULL)
+        return -1;
+
+    // stores the data that is read from the given path into buf
+    fgets_ret = fgets(buf, (int)count, fd);
+    if (NULL != fgets_ret)
+        rv = (int)strlen(buf);
+    else
+        rv = ferror(fd);
+
+    fclose(fd);
+
+    return rv;
+}
+
+/**
+ * @brief This function gets the source information from the file.
+ *
+ * This function receives a buffer variable to store the read information
+ * and also receives two different path. The hardware information may be
+ * present in any one of the received path. So this function checks in
+ * both the paths. This function internally uses read_line_from_file
+ * function to read the check and read the hardware details in each path.
+ *
+ * @param buf hardware details that is read will be stored.
+ * @param soc_node_path1 The first path where the file may be present.
+ * @param soc_node_path2 The second path where the file may be present.
+ * @return Returns the length of buffer.
+ */
+
+static int get_soc_info(char *buf, const char *soc_node_path1,
+            const char *soc_node_path2)
+{
+    int ret = 0;
+
+    // checks whether the hw platform detail is present in this path
+    ret = read_line_from_file(soc_node_path1, buf, MAX_SOC_INFO_NAME_LEN);
+    if (ret < 0) {
+        // if the hw platform detail is not present in the former path it checks here
+        ret = read_line_from_file(soc_node_path2, buf, MAX_SOC_INFO_NAME_LEN);
+        if (ret < 0) {
+            ALOGE("getting socinfo(%s, %d) failed.\n", soc_node_path1, ret);
+            return ret;
+        }
+    }
+    if (ret && buf[ret - 1] == '\n')
+        buf[ret - 1] = '\0';
+
+    return ret;
+}
+
+/**
+ * @brief finds the cofiguration id value for the particular target.
+ *
+ * This function reads the target board platform detail and hardware
+ * platform detail from the target device and generate a generic
+ * config file name.If that config file is present then it will be
+ * used for configuring that target. If not then based on the target
+ * information a config file will be assigned.
+ *
+ * @param config_file The generic config file name will be stored.
+ * @return it returns the config id for the target.
+ */
+
+int CNfcConfig::getconfiguration_id (char * config_file)
+{
+    int config_id = QRD_TYPE_DEFAULT;
+    char target_type[MAX_SOC_INFO_NAME_LEN] = {'\0'};
+    char soc_info[MAX_SOC_INFO_NAME_LEN] = {'\0'};
+    char nq_chipid[PROPERTY_VALUE_MAX] = {0};
+    char nq_fw_ver[PROPERTY_VALUE_MAX] = {0};
+    bool nq2xx_present = false;
+    string strPath;
+    int rc = 0;
+    int idx = 0;
+
+    rc = get_soc_info(soc_info, SYSFS_SOCID_PATH1, SYSFS_SOCID_PATH2);
+    if (rc < 0) {
+        ALOGE("get_soc_info(SOC_ID) fail!\n");
+        return DEFAULT_CONFIG;
+    }
+    idx = atoi(soc_info);
+
+    rc = get_soc_info(target_type, SYSFS_HW_PLATFORM_PATH1, SYSFS_HW_PLATFORM_PATH2);
+    if (rc < 0) {
+        ALOGE("get_soc_info(HW_PLATFORM) fail!\n");
+        return DEFAULT_CONFIG;
+    }
+
+    rc = __system_property_get("sys.nfc.nq.chipid", nq_chipid);
+    if (rc <= 0)
+        ALOGE("get sys.nfc.nq.chipid fail, chipid_found = %d\n", rc);
+    else
+        ALOGD("sys.nfc.nq.chipid = %s\n", nq_chipid);
+
+    rc = __system_property_get("sys.nfc.nq.fwver", nq_fw_ver);
+    if (rc <= 0)
+        ALOGE("get sys.nfc.nq.fwver fail, fwver found = %d\n", rc);
+    else
+        ALOGD("sys.nfc.nq.fwver = %s\n", nq_fw_ver);
+
+    nq2xx_present = (!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX))
+                 || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX));
+
+    // Converting the HW_PLATFORM detail that is read from target to lowercase
+    for (int i=0;target_type[i];i++)
+        target_type[i] = tolower(target_type[i]);
+
+    // generating a generic config file name based on the target details
+    snprintf(config_file, MAX_DATA_CONFIG_PATH_LEN, "libnfc-%s_%s.conf",
+            soc_info, target_type);
+
+    findConfigFilePathFromTransportConfigPaths(config_file, strPath);
+    if (file_exist(strPath.c_str()))
+        idx = 0;
+
+    if (DEBUG)
+        ALOGI("id:%d, config_file_name:%s\n", idx, config_file);
+
+    // if target is QRD platform then config id is assigned here
+    if (0 == strncmp(target_type, QRD_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN)) {
+        switch (idx)
+        {
+        case TARGET_GENERIC:
+            config_id = CONFIG_GENERIC;
+            break;
+        case TARGET_MSM8952:
+            config_id = QRD_TYPE_DEFAULT;
+            strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN);
+            break;
+        case TARGET_MSM8953:
+        case TARGET_MSM8937:
+        case TARGET_MSM8917:
+        case TARGET_MSM8940:
+        case TARGET_MSM8909:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = QRD_TYPE_DEFAULT;
+                strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = QRD_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_MSM8976:
+        case TARGET_MSM8996:
+            strlcpy(config_file, config_name_qrd1, MAX_DATA_CONFIG_PATH_LEN);
+            config_id = QRD_TYPE_1;
+            break;
+        case TARGET_SDM845:
+            if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) {
+                config_id = QRD_TYPE_NQ4XX;
+                strlcpy(config_file, config_name_qrd_NQ4XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            else {
+                config_id = QRD_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_SDM660:
+        case TARGET_SDM630:
+        case TARGET_MSM8998:
+        case TARGET_MSM8997:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = QRD_TYPE_2;
+                strlcpy(config_file, config_name_qrd2, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = QRD_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_qrd_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        default:
+            config_id = QRD_TYPE_DEFAULT;
+            strlcpy(config_file, config_name_qrd, MAX_DATA_CONFIG_PATH_LEN);
+            break;
+        }
+    }
+    // if target is MTP platform then config id is assigned here
+    else if (0 == strncmp(target_type, MTP_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN)) {
+        switch (idx)
+        {
+        case TARGET_GENERIC:
+            config_id = CONFIG_GENERIC;
+            break;
+        case TARGET_MSM8953:
+        case TARGET_MSM8937:
+        case TARGET_MSM8917:
+        case TARGET_MSM8940:
+        case TARGET_MSM8909:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = MTP_TYPE_DEFAULT;
+                strlcpy(config_file, config_name_mtp, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = MTP_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_SDM845:
+            if (!strncmp(nq_fw_ver, FW_MAJOR_NUM_NQ4xx, FW_MAJOR_NUM_LENGTH)) {
+                config_id = MTP_TYPE_NQ4XX;
+                strlcpy(config_file, config_name_mtp_NQ4XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            else {
+                config_id = MTP_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        case TARGET_SDM660:
+        case TARGET_SDM630:
+        case TARGET_MSM8998:
+        case TARGET_MSM8997:
+            if (nq2xx_present) {
+                // NQ210 or NQ220
+                config_id = MTP_TYPE_1;
+                strlcpy(config_file, config_name_mtp1, MAX_DATA_CONFIG_PATH_LEN);
+            } else {
+                config_id = MTP_TYPE_NQ3XX;
+                strlcpy(config_file, config_name_mtp_NQ3XX, MAX_DATA_CONFIG_PATH_LEN);
+            }
+            break;
+        default:
+            config_id = MTP_TYPE_DEFAULT;
+            strlcpy(config_file, config_name_mtp, MAX_DATA_CONFIG_PATH_LEN);
+            break;
+        }
+    }
+    if (DEBUG)
+        ALOGI("platform config id:%d, config_file_name:%s\n", config_id, config_file);
+
+    return config_id;
+}
+
 /*******************************************************************************
 **
 ** Function:    isPrintable()
@@ -260,9 +581,12 @@
   ALOGD("%s Opened %s config %s\n", __func__,
         (bResetContent ? "base" : "optional"), name);
   stat(name, &buf);
-  if (strcmp(default_nxp_config_path, name) == 0) {
-    m_timeStamp = (unsigned long)buf.st_mtime;
-  }
+  if(mDynamConfig)
+        m_timeStamp = (unsigned long)buf.st_mtime;
+    else {
+        if(strcmp(default_nxp_config_path, name) == 0)
+            m_timeStamp = (unsigned long)buf.st_mtime;
+    }
   if (strcmp(nxp_rf_config_path, name) == 0) {
     m_timeStampRF = (unsigned long)buf.st_mtime;
   }
@@ -428,6 +752,7 @@
 *******************************************************************************/
 CNfcConfig::CNfcConfig()
     : mValidFile(true),
+      mDynamConfig(true),
       m_timeStamp(0),
       m_timeStampRF(0),
       m_timeStampTransit(0),
@@ -444,6 +769,22 @@
 *******************************************************************************/
 CNfcConfig::~CNfcConfig() {}
 
+/**
+ * @brief checks whether the given file exist.
+ *
+ * This function gets the file name and checks whether the given file
+ * exist in the particular path.Internaly it uses stat system call to
+ * find the existance.
+ *
+ * @param filename The name of the file whose existance has to be checked.
+ * @return it returns true if the given file name exist.
+ */
+int CNfcConfig::file_exist (const char* filename)
+{
+    struct stat   buffer;
+    return (stat (filename, &buffer) == 0);
+}
+
 /*******************************************************************************
 **
 ** Function:    CNfcConfig::GetInstance()
@@ -455,26 +796,49 @@
 *******************************************************************************/
 CNfcConfig& CNfcConfig::GetInstance() {
   static CNfcConfig theInstance;
+  int gconfigpathid=0;
+  char config_name_generic[MAX_DATA_CONFIG_PATH_LEN] = {'\0'};
 
-  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;
-      }
-    }
-    findConfigFilePathFromTransportConfigPaths(config_name, strPath);
-    theInstance.readConfig(strPath.c_str(), true);
-#if (NXP_EXTNS == TRUE)
-    readOptionalConfig("brcm");
-    theInstance.readNxpTransitConfig(transit_config_path);
-    theInstance.readNxpRFConfig(nxp_rf_config_path);
+    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;
+            }
+        }
+        findConfigFilePathFromTransportConfigPaths(config_name, strPath);
+        //checks whether the default config file is present in th target
+        if (theInstance.file_exist(strPath.c_str())) {
+            ALOGI("default config file exists = %s, disables dynamic selection", strPath.c_str());
+            theInstance.mDynamConfig = false;
+            theInstance.readConfig(strPath.c_str(), true);
+            /*
+             * if libnfc-nxp.conf exists then dynamic selection will
+             * be turned off by default we will not have this file.
+             */
+            return theInstance;
+        }
+
+        gconfigpathid = theInstance.getconfiguration_id(config_name_generic);
+        findConfigFilePathFromTransportConfigPaths(config_name_generic, strPath);
+        if (!(theInstance.file_exist(strPath.c_str()))) {
+            ALOGI("no matching file found, using default file for stability\n");
+            findConfigFilePathFromTransportConfigPaths(config_name_default, strPath);
+        }
+        ALOGI("config file used = %s\n",strPath.c_str());
+        theInstance.readConfig(strPath.c_str(), true);
+#if(NXP_EXTNS == TRUE)
+        readOptionalConfig("brcm");
+        theInstance.readNxpTransitConfig("nxpTransit");
 #endif
-  }
-  return theInstance;
+    }
+    return theInstance;
 }
 
 /*******************************************************************************
@@ -799,6 +1163,7 @@
   }
   return ret;
 }
+
 /*******************************************************************************
 **
 ** Function:    CNfcConfig::updateTimestamp()
diff --git a/halimpl/pn54x/utils/phNxpConfig.h b/halimpl/pn54x/utils/phNxpConfig.h
index 954cb87..63eba34 100644
--- a/halimpl/pn54x/utils/phNxpConfig.h
+++ b/halimpl/pn54x/utils/phNxpConfig.h
@@ -105,9 +105,83 @@
 #define NAME_NXP_PROP_BLACKLIST_ROUTING "NXP_PROP_BLACKLIST_ROUTING"
 #define NAME_NXP_WIREDMODE_RESUME_TIMEOUT "NXP_WIREDMODE_RESUME_TIMEOUT"
 #define NAME_NXP_UICC_LISTEN_TECH_MASK "UICC_LISTEN_TECH_MASK"
+#define NAME_NXP_HOST_LISTEN_TECH_MASK "HOST_LISTEN_TECH_MASK"
 #define NAME_NXP_ESE_LISTEN_TECH_MASK "NXP_ESE_LISTEN_TECH_MASK"
 #define NAME_NXP_SVDD_SYNC_OFF_DELAY "NXP_SVDD_SYNC_OFF_DELAY"
 #define NAME_NXP_CORE_PROP_SYSTEM_DEBUG "NXP_CORE_PROP_SYSTEM_DEBUG"
 #define NAME_NXP_NCI_PARSER_LIBRARY "NXP_NCI_PARSER_LIBRARY"
+/**
+ *  @brief defines the different config files used.
+ */
+
+#define config_name_mtp         "libnfc-mtp_default.conf"
+#define config_name_mtp1        "libnfc-mtp_rf1.conf"
+#define config_name_mtp2        "libnfc-mtp_rf2.conf"
+#define config_name_mtp_NQ3XX   "libnfc-mtp-NQ3XX.conf"
+#define config_name_mtp_NQ4XX   "libnfc-mtp-NQ4XX.conf"
+#define config_name_qrd         "libnfc-qrd_default.conf"
+#define config_name_qrd1        "libnfc-qrd_rf1.conf"
+#define config_name_qrd2        "libnfc-qrd_rf2.conf"
+#define config_name_qrd_NQ3XX   "libnfc-qrd-NQ3XX.conf"
+#define config_name_qrd_NQ4XX   "libnfc-qrd-NQ4XX.conf"
+#define config_name_default     "libnfc-nxp_default.conf"
+
+/**
+ *  @brief defines the different major number used.
+ */
+#define FW_MAJOR_NUM_NQ2xx      "10"
+#define FW_MAJOR_NUM_NQ3xx      "11"
+#define FW_MAJOR_NUM_NQ4xx      "12"
+
+#define FW_MAJOR_NUM_LENGTH     2
+
+/**
+ *  @brief defines the maximum length of the target name.
+ */
+
+#define MAX_SOC_INFO_NAME_LEN (15)
+
+/**
+ *  @brief Defines the type of hardware platform.
+ */
+
+#define QRD_HW_PLATFORM  "qrd"
+#define MTP_HW_PLATFORM  "mtp"
+
+/**
+ *  @brief Defines the path where the hardware platform details are present.
+ */
+
+#define SYSFS_HW_PLATFORM_PATH1  "/sys/devices/soc0/hw_platform"
+#define SYSFS_HW_PLATFORM_PATH2   "/sys/devices/system/soc/soc0/hw_platform"
+
+/**
+ *  @brief Defines the path where the soc_id details are present.
+ */
+
+#define SYSFS_SOCID_PATH1    "/sys/devices/soc0/soc_id"
+#define SYSFS_SOCID_PATH2    "/sys/devices/system/soc/soc0/id"
+
+/**
+ *  @brief Defines the maximum length of the config file name.
+ */
+
+#define MAX_DATA_CONFIG_PATH_LEN 64
+
+/**
+ *  @brief Defines the NQ chip type.
+ */
+
+#define NQ210 "0x48"
+#define NQ220 "0x58"
+
+/**
+ *  @brief Defines whether debugging is enabled or disabled.
+ */
+
+#define DEBUG 0
+
+/* default configuration */
+#define default_storage_location "/data/vendor/nfc"
 
 #endif
diff --git a/p61-jcop-kit/Android.mk b/p61-jcop-kit/Android.mk
new file mode 100644
index 0000000..a2a328d
--- /dev/null
+++ b/p61-jcop-kit/Android.mk
@@ -0,0 +1,30 @@
+# 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
+
+
+LOCAL_PATH:= $(call my-dir)
+D_CFLAGS += -DNXP_LDR_SVC_VER_2=TRUE
+######################################
+# Build shared library system/vendor/lib/libp61-jcop-kit.so for stack code.
+
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_MODULE := libnqp61-jcop-kit
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := nxp
+LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils liblog libdl libhardware
+LOCAL_CFLAGS := $(D_CFLAGS)
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include/ \
+    $(LOCAL_PATH)/inc/
+LOCAL_SRC_FILES := \
+    $(call all-c-files-under, src) \
+    $(call all-cpp-files-under, src)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/p61-jcop-kit/README.md b/p61-jcop-kit/README.md
new file mode 100644
index 0000000..01eeb1c
--- /dev/null
+++ b/p61-jcop-kit/README.md
@@ -0,0 +1,30 @@
+# NXPNFC_P61_JCOP_Kit
+
+####Git Repository
+
+| DESCRIPTION        | CHECKOUT COMMAND          |
+| :-------------: |:-------------:| 
+| NXPNFC_P61_JCOP_Kit    |  git clone https://github.com/NXPNFCProject/NXPNFC_P61_JCOP_Kit.git |
+
+####Supported Android Versions
+
+| Android Version        | NXP Release          | NXP Tag  |
+| :-------------: |:-------------:| :-----:|
+| android-6.0.0_r1                     |  3.1.0_M (PN547C2/PN548C2) |  SEAccessKit_AR3.1.0_OpnSrc |
+| android-6.0.0_r1                     |  3.2.0_M (PN547C2/PN548C2) |  SEAccessKit_AR3.2.0_OpnSrc |
+| android-6.0.1_r17                    |  3.3.0_M (PN551/PN548C2)   |  SEAccessKit_AR3.3.0_OpnSrc |
+| android-6.0.1_r17                    |  3.5.0_M (PN553)   |  SEAccessKit_AR3.5.0_OpnSrc |
+| android-7.0.0_r4                     |  3.5.2 (PN553)   |  SEAccessKit_AR3.5.2_OpnSrc |
+| android-6.0.1_r17                    |  3.6.0_M (PN551/PN548C2)   |  SEAccessKit_AR3.6.0_OpnSrc |
+| android-7.0.0_r12                     |  7.0.3_N (PN548C2/PN551/PN553) |  SEAccessKit_AR7.0.3_OpnSrc |
+| android-7.0.0_r12                     |  7.1.0_N (PN553) |  SEAccessKit_AR7.1.0_OpnSrc |
+| android-7.0.0_r12                     |  7.2.0_N (PN553) |  SEAccessKit_AR7.2.0_OpnSrc |
+| android-7.1.1_r1                     |  7.3.0_N (PN548C2/PN551) |  SEAccessKit_AR7.3.0_OpnSrc |
+| android-7.1.1_r1                     |  7.4.0_N (PN553) |  SEAccessKit_AR7.4.0_OpnSrc |
+| android-o-preview2                     |  8.0.9_O (PN553/PN557) |  SEAccessKit_AR8.0.9_OpnSrc |
+| android-o-preview2                     |  8.0.C_O (PN553/PN557) |  SEAccessKit_AR8.0.C_OpnSrc |
+| android-o-preview2                     |  8.0.13_O (PN553/PN557) |  SEAccessKit_AR8.0.13_OpnSrc |
+| android-8.0.0_r4               |  8.1.0_O (PN553) |  SEAccessKit_AR8.1.0_OpnSrc |
+| android-8.0.0_r4               |  8.2.0_O (PN557) |  SEAccessKit_AR8.2.0_OpnSrc |
+| android-8.0.0_r4               |  8.2.3_O (PN557) |  SEAccessKit_AR8.2.3_OpnSrc |
+| android-8.0.0_r4               |  8.3.0_O (PN548C2/PN551/PN553) |  SEAccessKit_AR8.3.0_OpnSrc |
diff --git a/p61-jcop-kit/inc/Ala.h b/p61-jcop-kit/inc/Ala.h
new file mode 100644
index 0000000..fe27ef7
--- /dev/null
+++ b/p61-jcop-kit/inc/Ala.h
@@ -0,0 +1,282 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 ALA_H_
+#define ALA_H_
+
+#define NXP_LS_AID
+#include "data_types.h"
+#include "IChannel.h"
+#include <stdio.h>
+
+typedef struct Ala_ChannelInfo
+{
+    uint8_t channel_id;
+    bool  isOpend;
+}Ala_ChannelInfo_t;
+
+typedef struct Ala_TranscieveInfo
+{
+    int32_t timeout;
+    uint8_t sRecvData[1024];
+    uint8_t sSendData[1024];
+    int32_t sSendlength;
+    int   sRecvlength;
+    uint8_t sTemp_recvbuf[1024];
+}Ala_TranscieveInfo_t;
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+typedef struct Ala_ImageInfo
+{
+    FILE                 *fp;
+    int                  fls_size;
+    char                 fls_path[384];
+    int                  bytes_read;
+    FILE                 *fResp;
+    int                  fls_RespSize;
+    char                 fls_RespPath[384];
+    int                  bytes_wrote;
+    Ala_ChannelInfo_t    Channel_Info[10];
+    uint8_t              channel_cnt;
+}Ala_ImageInfo_t;
+typedef enum
+{
+    LS_Default = 0x00,
+    LS_Cert = 0x7F21,
+    LS_Sign = 0x60,
+    LS_Comm = 0x40
+}Ls_TagType;
+#else
+typedef struct Ala_ImageInfo
+{
+    FILE                 *fp;
+    int                  fls_size;
+    char                 fls_path[256];
+    int                  bytes_read;
+    Ala_ChannelInfo_t    Channel_Info[10];
+    uint8_t              channel_cnt;
+}Ala_ImageInfo_t;
+#endif
+typedef struct Ala_lib_Context
+{
+    IChannel_t            *mchannel;
+    Ala_ImageInfo_t       Image_info;
+    Ala_TranscieveInfo_t  Transcv_Info;
+}Ala_Dwnld_Context_t,*pAla_Dwnld_Context_t;
+
+static uint8_t OpenChannel[] = {0x00, 0x70, 0x00, 0x00, 0x01};
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+static uint8_t GetData[] = {0x80, 0xCA, 0x00, 0x46, 0x00};
+#ifndef NXP_LS_AID
+static uint8_t SelectAla[] = {0x00, 0xA4, 0x04, 0x00, 0x0D, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C, 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
+#else
+static uint8_t SelectAla[] = {0x00, 0xA4, 0x04, 0x00, 0x0F, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x54, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B
+, 0x00,0x01};
+#endif
+#else
+static uint8_t SelectAla[] = {0x00, 0xA4, 0x04, 0x00, 0x0D, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C, 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
+#endif
+/*ALA2*/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+#define NOOFAIDS     0x03
+#define LENOFAIDS    0x16
+#ifndef NXP_LS_AID
+static uint8_t ArrayOfAIDs[NOOFAIDS][LENOFAIDS] = {
+        {0x12, 0x00, 0xA4, 0x04, 0x00, 0x0D, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C, 0x41, 0x01, 0x4C, 0x44, 0x52, 0x01,0x00,0x00,0x00},
+        {0x12, 0x00, 0xA4, 0x04, 0x00, 0x0D, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C, 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01,0x00,0x00,0x00},
+        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+#else
+static uint8_t ArrayOfAIDs[NOOFAIDS][LENOFAIDS] = {
+        {0x14, 0x00, 0xA4, 0x04, 0x00, 0x0F, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x54, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B,0x00,0x02,0x00},
+        {0x14, 0x00, 0xA4, 0x04, 0x00, 0x0F, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x54, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B,0x00,0x01,0x00},
+        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+};
+#endif
+#define TAG_CERTIFICATE     0x7F21
+#define TAG_LSES_RESP       0x4E
+#define TAG_LSES_RSPLEN     0x02
+#define TAG_SERIAL_NO       0x93
+#define TAG_LSRE_ID         0x42
+#define TAG_LSRE_SIGNID     0x45
+#define TAG_CERTFHOLD_ID    0x5F20
+#define TAG_KEY_USAGE       0x95
+#define TAG_EFF_DATE        0x5F25
+#define TAG_EXP_DATE        0x5F24
+#define TAG_CCM_PERMISSION  0x53
+#define TAG_SIG_RNS_COMP    0x5F37
+
+#define TAG_LS_VER1         0x9F
+#define TAG_LS_VER2         0x08
+#define LS_DEFAULT_STATUS   0x6340
+#define LS_SUCCESS_STATUS   0x9000
+#define TAG_RE_KEYID        0x65
+
+#define LS_ABORT_SW1        0x69
+#define LS_ABORT_SW2        0x87
+#define AID_MEM_PATH       "/data/vendor/nfc/AID_MEM.txt"
+#define LS_STATUS_PATH     "/data/vendor/nfc/LS_Status.txt"
+#define LS_SRC_BACKUP      "/data/vendor/nfc/LS_Src_Backup.txt"
+#define LS_DST_BACKUP      "/data/vendor/nfc/LS_Dst_Backup.txt"
+#define MAX_CERT_LEN        (255+137)
+
+#endif
+/*ALA2*/
+
+#define JCOP3_WR
+#define APPLET_PATH        "/data/ala/"
+#define MAX_SIZE            0xFF
+#define PARAM_P1_OFFSET     0x02
+#define FIRST_BLOCK         0x05
+#define LAST_BLOCK          0x84
+#define ONLY_BLOCK          0x85
+#define CLA_BYTE            0x80
+#define JSBL_HEADER_LEN     0x03
+#define ALA_CMD_HDR_LEN     0x02
+
+/* Definations for TAG ID's present in the script file*/
+#define TAG_SELECT_ID       0x6F
+#define TAG_ALA_ID          0x84
+#define TAG_PRO_DATA_ID     0xA5
+#define TAG_JSBL_HDR_ID     0x60
+#define TAG_JSBL_KEY_ID     0x61
+#define TAG_SIGNATURE_ID    0x41
+#define TAG_ALA_CMD_ID      0x40
+#define TAG_JSBL_CER_ID     0x44
+
+/*Definitions for Install for load*/
+#define INSTAL_LOAD_ID      0xE6
+#define LOAD_CMD_ID         0xE8
+#define LOAD_MORE_BLOCKS    0x00
+#define LOAD_LAST_BLOCK     0x80
+
+#define STORE_DATA_CLA      0x80
+#define STORE_DATA_INS      0xE2
+#define STORE_DATA_LEN      32
+#define STORE_DATA_TAG      0x4F
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Initialize all member variables.
+**                  native: Native data.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool    initialize (IChannel_t *channel);
+
+/*******************************************************************************
+**
+** Function:        finalize
+**
+** Description:     Release all resources.
+**
+** Returns:         None
+**
+*******************************************************************************/
+void finalize ();
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS Perform_ALA(const char *path,const char *dest, const uint8_t *pdata, uint16_t len, uint8_t *respSW);
+#else
+tJBL_STATUS Perform_ALA(const char *path, const uint8_t *pdata, uint16_t len);
+#endif
+tJBL_STATUS GetJsbl_Certificate_Refkey(uint8_t *pkey, int32_t *pKeylen);
+
+static tJBL_STATUS
+ALA_OpenChannel(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo);
+
+static tJBL_STATUS
+ALA_SelectAla(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo);
+
+static tJBL_STATUS
+ALA_StoreData(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo);
+
+static tJBL_STATUS
+ALA_loadapplet(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+static tJBL_STATUS
+ALA_update_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo), const char *name, const char *dest);
+
+tJBL_STATUS GetLs_Version(uint8_t *pKey);
+
+tJBL_STATUS GetVer_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo));
+
+tJBL_STATUS Write_Response_To_OutFile(Ala_ImageInfo_t *image_info, uint8_t* RecvData, int32_t recvlen, Ls_TagType tType);
+
+tJBL_STATUS Check_Certificate_Tag(uint8_t *read_buf, uint16_t *offset1);
+
+tJBL_STATUS Check_SerialNo_Tag(uint8_t *read_buf, uint16_t *offset1);
+
+tJBL_STATUS Check_LSRootID_Tag(uint8_t *read_buf, uint16_t *offset1);
+
+tJBL_STATUS Check_CertHoldID_Tag(uint8_t *read_buf, uint16_t *offset1);
+
+tJBL_STATUS Check_Date_Tag(uint8_t *read_buf, uint16_t *offset1);
+
+tJBL_STATUS Check_45_Tag(uint8_t *read_buf, uint16_t *offset1, uint8_t *tag45Len);
+
+tJBL_STATUS Certificate_Verification(Ala_ImageInfo_t *Os_info, Ala_TranscieveInfo_t
+*pTranscv_Info, uint8_t *read_buf, uint16_t *offset1, uint8_t *tag45Len);
+
+tJBL_STATUS Check_Complete_7F21_Tag(Ala_ImageInfo_t *Os_info,
+       Ala_TranscieveInfo_t *pTranscv_Info, uint8_t *read_buf, uint16_t *offset);
+bool    ALA_UpdateExeStatus(uint16_t status);
+tJBL_STATUS ALA_getAppletLsStatus(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+tJBL_STATUS Get_LsStatus(uint8_t *pVersion);
+tJBL_STATUS Get_LsAppletStatus(uint8_t *pVersion);
+#else
+static tJBL_STATUS
+ALA_update_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo), const char *name);
+#endif
+static tJBL_STATUS
+JsblCerId_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo));
+
+tJBL_STATUS ALA_SendtoEse(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS GetLsStatus_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t*
+        pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo));
+tJBL_STATUS ALA_SendtoAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info, Ls_TagType tType);
+#else
+tJBL_STATUS ALA_SendtoAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+#endif
+tJBL_STATUS ALA_CloseChannel(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, int32_t recvlen, Ala_TranscieveInfo_t *trans_info, Ls_TagType tType);
+#else
+tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, int32_t recvlen, Ala_TranscieveInfo_t *trans_info);
+#endif
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_Check_KeyIdentifier(Ala_ImageInfo_t *Os_info, tJBL_STATUS status,
+   Ala_TranscieveInfo_t *pTranscv_Info, uint8_t* temp_buf, tJBL_STATUS flag,
+   int32_t wNewLen);
+#else
+tJBL_STATUS ALA_Check_KeyIdentifier(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+#endif
+tJBL_STATUS ALA_ReadScript(Ala_ImageInfo_t *Os_info, uint8_t *read_buf);
+
+tJBL_STATUS Process_EseResponse(Ala_TranscieveInfo_t *pTranscv_Info, int32_t recv_len, Ala_ImageInfo_t *Os_info);
+
+tJBL_STATUS Process_SelectRsp(uint8_t* Recv_data, int32_t Recv_len);
+#ifdef JCOP3_WR
+tJBL_STATUS Send_Backall_Loadcmds(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+
+tJBL_STATUS Bufferize_load_cmds(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+#endif
+uint8_t Numof_lengthbytes(uint8_t *read_buf, int32_t *wLen);
+#endif /*ALA_H*/
diff --git a/p61-jcop-kit/inc/JcopOsDownload.h b/p61-jcop-kit/inc/JcopOsDownload.h
new file mode 100644
index 0000000..b19f96f
--- /dev/null
+++ b/p61-jcop-kit/inc/JcopOsDownload.h
@@ -0,0 +1,146 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 "data_types.h"
+#include "IChannel.h"
+#include <stdio.h>
+
+typedef struct JcopOs_TranscieveInfo
+{
+    int32_t timeout;
+    uint8_t sRecvData[1024];
+    uint8_t *sSendData;
+    int32_t sSendlength;
+    int sRecvlength;
+}JcopOs_TranscieveInfo_t;
+
+typedef struct JcopOs_Version_Info
+{
+    uint8_t osid;
+    uint8_t ver1;
+    uint8_t ver0;
+    uint8_t OtherValid;
+    uint8_t ver_status;
+}JcopOs_Version_Info_t;
+typedef struct JcopOs_ImageInfo
+{
+    FILE *fp;
+    int   fls_size;
+    char  fls_path[256];
+    int   index;
+    uint8_t cur_state;
+    JcopOs_Version_Info_t    version_info;
+}JcopOs_ImageInfo_t;
+typedef struct JcopOs_Dwnld_Context
+{
+    JcopOs_Version_Info_t    version_info;
+    JcopOs_ImageInfo_t       Image_info;
+    JcopOs_TranscieveInfo_t  pJcopOs_TransInfo;
+    IChannel_t               *channel;
+}JcopOs_Dwnld_Context_t,*pJcopOs_Dwnld_Context_t;
+
+
+static uint8_t Trigger_APDU[] = {0x4F, 0x70, 0x80, 0x13, 0x04, 0xDE, 0xAD, 0xBE, 0xEF, 0x00};
+static uint8_t GetInfo_APDU[] = {0x00, //CLA
+                               0xA4, 0x04, 0x00, 0x0C, //INS, P1, P2, Lc
+                               0xD2, 0x76, 0x00, 0x00, 0x85, 0x41, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,   //Data
+                               0x00 //Le
+                              };
+static uint8_t GetInfo_Data[] = {0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x4F, 0x53};
+
+#define OSID_OFFSET  9
+#define VER1_OFFSET  10
+#define VER0_OFFSET  11
+#define JCOPOS_HEADER_LEN 5
+
+#define JCOP_UPDATE_STATE0 0
+#define JCOP_UPDATE_STATE1 1
+#define JCOP_UPDATE_STATE2 2
+#define JCOP_UPDATE_STATE3 3
+#define JCOP_MAX_RETRY_CNT 3
+#define JCOP_INFO_PATH  "/data/vendor/nfc/jcop_info.txt"
+
+#define JCOP_MAX_BUF_SIZE 10240
+
+class JcopOsDwnld
+{
+public:
+
+/*******************************************************************************
+**
+** Function:        getInstance
+**
+** Description:     Get the SecureElement singleton object.
+**
+** Returns:         SecureElement object.
+**
+*******************************************************************************/
+static JcopOsDwnld* getInstance ();
+
+
+/*******************************************************************************
+**
+** Function:        getJcopOsFileInfo
+**
+** Description:     Verify all the updater files required for download
+**                  are present or not
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool getJcopOsFileInfo();
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Initialize all member variables.
+**                  native: Native data.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool initialize (IChannel_t *channel);
+
+/*******************************************************************************
+**
+** Function:        finalize
+**
+** Description:     Release all resources.
+**
+** Returns:         None
+**
+*******************************************************************************/
+void finalize ();
+
+tJBL_STATUS JcopOs_Download();
+
+tJBL_STATUS TriggerApdu(JcopOs_ImageInfo_t* pVersionInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info);
+
+tJBL_STATUS GetInfo(JcopOs_ImageInfo_t* pVersionInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info);
+
+tJBL_STATUS load_JcopOS_image(JcopOs_ImageInfo_t *Os_info, tJBL_STATUS status, JcopOs_TranscieveInfo_t *pTranscv_Info);
+
+tJBL_STATUS JcopOs_update_seq_handler();
+
+IChannel_t *mchannel;
+
+private:
+static JcopOsDwnld sJcopDwnld;
+bool mIsInit;
+tJBL_STATUS GetJcopOsState(JcopOs_ImageInfo_t *Os_info, uint8_t *counter);
+tJBL_STATUS SetJcopOsState(JcopOs_ImageInfo_t *Os_info, uint8_t state);
+};
diff --git a/p61-jcop-kit/inc/data_types.h b/p61-jcop-kit/inc/data_types.h
new file mode 100644
index 0000000..689d8ee
--- /dev/null
+++ b/p61-jcop-kit/inc/data_types.h
@@ -0,0 +1,59 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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
+#include <stdint.h>
+#include <stdbool.h>
+#ifndef NULL
+#define NULL     0
+#endif
+
+/*
+#ifndef false
+#define false  0
+#endif
+*/
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+typedef uint32_t        TIME_STAMP;
+
+/*
+#ifndef true
+#define true   (!false)
+#endif
+*/
+
+#ifndef TRUE
+#define TRUE   (!FALSE)
+#endif
+
+typedef unsigned char   UBYTE;
+
+#define STATUS_SUCCESS     0x00
+#define STATUS_OK          0x00
+#define STATUS_UPTO_DATE   0x01
+#define STATUS_FAILED      0x03
+#define STATUS_INUSE       0x04
+#define STATUS_FILE_NOT_FOUND  0x05
+
+#define EE_ERROR_OPEN_FAIL -1
+
+typedef uint8_t tJBL_STATUS;
+
+#endif
diff --git a/p61-jcop-kit/include/AlaLib.h b/p61-jcop-kit/include/AlaLib.h
new file mode 100644
index 0000000..910b3f4
--- /dev/null
+++ b/p61-jcop-kit/include/AlaLib.h
@@ -0,0 +1,105 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif
+
+
+#ifndef ALALIB_H_
+#define ALALIB_H_
+
+#include "IChannel.h"
+
+/*******************************************************************************
+**
+** Function:        ALA_Init
+**
+** Description:     Initializes the ALA library and opens the DWP communication channel
+**
+** Returns:         SUCCESS if ok.
+**
+*******************************************************************************/
+unsigned char ALA_Init(IChannel *channel);
+
+/*******************************************************************************
+**
+** Function:        ALA_Start
+**
+** Description:     Starts the ALA over DWP
+**
+** Returns:         SUCCESS if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+unsigned char ALA_Start(const char *name, const char *dest, uint8_t *pdata, uint16_t len, uint8_t *respSW);
+#else
+unsigned char ALA_Start(const char *name, uint8_t *pdata, uint16_t len);
+#endif
+
+/*******************************************************************************
+**
+** Function:        ALA_DeInit
+**
+** Description:     Deinitializes the ALA Lib
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+bool ALA_DeInit();
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+/*******************************************************************************
+**
+** Function:        ALA_lsGetVersion
+**
+** Description:     Get the Loader service Applet and cleint version
+**
+** Returns:         byte[] array.
+**
+*******************************************************************************/
+unsigned char ALA_lsGetVersion(uint8_t *pVersion);
+unsigned char ALA_lsGetStatus(uint8_t *pVersion);
+unsigned char ALA_lsGetAppletStatus(uint8_t *pVersion);
+#else
+void ALA_GetlistofApplets(char *list[], uint8_t* num);
+
+unsigned char ALA_GetCertificateKey(uint8_t *pKey, int32_t *pKeylen);
+#endif
+
+inline int FSCANF_BYTE(FILE *stream, const char *format, void* pVal)
+{
+    int Result = 0;
+
+    if((NULL != stream) && (NULL != format) && (NULL != pVal))
+    {
+        unsigned int dwVal;
+        unsigned char* pTmp = (unsigned char*)pVal;
+        Result = fscanf(stream, format, &dwVal);
+
+        (*pTmp) = (unsigned char)(dwVal & 0x000000FF);
+    }
+    return Result;
+}
+
+#endif /* ALALIB_H_ */
+
+#ifdef __cplusplus
+
+}
+
+#endif
diff --git a/p61-jcop-kit/include/IChannel.h b/p61-jcop-kit/include/IChannel.h
new file mode 100644
index 0000000..3318c43
--- /dev/null
+++ b/p61-jcop-kit/include/IChannel.h
@@ -0,0 +1,88 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 ICHANNEL_H_
+#define ICHANNEL_H_
+
+#include "data_types.h"
+typedef struct IChannel
+{
+/*******************************************************************************
+**
+** Function:        Open
+**
+** Description:     Initialize the channel.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+int16_t (*open)();
+/*******************************************************************************
+**
+** Function:        close
+**
+** Description:     Close the channel.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool (*close)(int16_t mHandle);
+
+/*******************************************************************************
+**
+** Function:        transceive
+**
+** Description:     Send data to the secure element; read it's response.
+**                  xmitBuffer: Data to transmit.
+**                  xmitBufferSize: Length of data.
+**                  recvBuffer: Buffer to receive response.
+**                  recvBufferMaxSize: Maximum size of buffer.
+**                  recvBufferActualSize: Actual length of response.
+**                  timeoutMillisec: timeout in millisecond
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool (*transceive) (uint8_t* xmitBuffer, int32_t xmitBufferSize, uint8_t* recvBuffer,
+                     int32_t recvBufferMaxSize, int32_t& recvBufferActualSize, int32_t timeoutMillisec);
+
+/*******************************************************************************
+**
+** Function:        doeSE_Reset
+**
+** Description:     Power OFF and ON to eSE
+**
+** Returns:         None.
+**
+*******************************************************************************/
+
+void (*doeSE_Reset)();
+/*******************************************************************************
+**
+** Function:        doeSE_JcopDownLoadReset
+**
+** Description:     Power OFF and ON to eSE during JCOP Update
+**
+** Returns:         None.
+**
+*******************************************************************************/
+
+void (*doeSE_JcopDownLoadReset)();
+
+}IChannel_t;
+
+
+#endif /* ICHANNEL_H_ */
diff --git a/p61-jcop-kit/include/JcDnld.h b/p61-jcop-kit/include/JcDnld.h
new file mode 100644
index 0000000..630dd7d
--- /dev/null
+++ b/p61-jcop-kit/include/JcDnld.h
@@ -0,0 +1,78 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif
+
+
+#ifndef JCDNLD_H_
+#define JCDNLD_H_
+
+#include "IChannel.h"
+/*******************************************************************************
+**
+** Function:        JCDNLD_Init
+**
+** Description:     Initializes the JCOP library and opens the DWP communication channel
+**
+** Returns:         SUCCESS if ok.
+**
+*******************************************************************************/
+unsigned char JCDNLD_Init(IChannel *channel);
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_StartDownload
+**
+** Description:     Starts the JCOP update
+**
+** Returns:         SUCCESS if ok.
+**
+*******************************************************************************/
+unsigned char JCDNLD_StartDownload();
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_DeInit
+**
+** Description:     Deinitializes the JCOP Lib
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+bool JCDNLD_DeInit();
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_CheckVersion
+**
+** Description:     Check the existing JCOP OS version
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+bool JCDNLD_CheckVersion();
+
+
+#endif /* JCDNLD_H_ */
+
+#ifdef __cplusplus
+
+}
+
+#endif
diff --git a/p61-jcop-kit/src/Ala.cpp b/p61-jcop-kit/src/Ala.cpp
new file mode 100644
index 0000000..6790411
--- /dev/null
+++ b/p61-jcop-kit/src/Ala.cpp
@@ -0,0 +1,3069 @@
+ /*
+  * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+  * Not a Contribution.
+  *
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 <cutils/log.h>
+#include <Ala.h>
+#include <AlaLib.h>
+#include <IChannel.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+pAla_Dwnld_Context_t gpAla_Dwnld_Context=NULL;
+extern int32_t gTransceiveTimeout;
+#ifdef JCOP3_WR
+uint8_t Cmd_Buffer[64*1024];
+static int32_t cmd_count = 0;
+bool islastcmdLoad;
+bool SendBack_cmds = false;
+uint8_t *pBuffer;
+#endif
+bool    mIsInit;
+uint8_t Select_Rsp[1024];
+uint8_t Jsbl_RefKey[256];
+uint8_t Jsbl_keylen;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+uint8_t StoreData[22];
+#else
+uint8_t StoreData[34];
+#endif
+int Select_Rsp_Len;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+uint8_t lsVersionArr[2];
+uint8_t tag42Arr[17];
+uint8_t tag45Arr[9];
+uint8_t lsExecuteResp[4];
+uint8_t AID_ARRAY[22];
+int32_t resp_len = 0;
+FILE *fAID_MEM = NULL;
+FILE *fLS_STATUS = NULL;
+uint8_t lsGetStatusArr[2];
+tJBL_STATUS (*ls_GetStatus_seqhandler[])(Ala_ImageInfo_t *pContext, tJBL_STATUS status, Ala_TranscieveInfo_t *pInfo)=
+{
+    ALA_OpenChannel,
+    ALA_SelectAla,
+    ALA_getAppletLsStatus,
+    ALA_CloseChannel,
+    NULL
+};
+#endif
+tJBL_STATUS (*Applet_load_seqhandler[])(Ala_ImageInfo_t *pContext, tJBL_STATUS status, Ala_TranscieveInfo_t *pInfo)=
+{
+    ALA_OpenChannel,
+    ALA_SelectAla,
+    ALA_StoreData,
+    ALA_loadapplet,
+    NULL
+};
+
+tJBL_STATUS (*Jsblcer_id_seqhandler[])(Ala_ImageInfo_t *pContext, tJBL_STATUS status, Ala_TranscieveInfo_t *pInfo)=
+{
+    ALA_OpenChannel,
+    ALA_SelectAla,
+    ALA_CloseChannel,
+    NULL
+};
+
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Initialize all member variables.
+**                  native: Native data.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool initialize (IChannel_t* channel)
+{
+    static const char fn [] = "Ala_initialize";
+
+    ALOGD ("%s: enter", fn);
+
+    gpAla_Dwnld_Context = (pAla_Dwnld_Context_t)malloc(sizeof(Ala_Dwnld_Context_t));
+    if(gpAla_Dwnld_Context != NULL)
+    {
+        memset((void *)gpAla_Dwnld_Context, 0, (uint32_t)sizeof(Ala_Dwnld_Context_t));
+    }
+    else
+    {
+        ALOGD("%s: Memory allocation failed", fn);
+        return (false);
+    }
+    gpAla_Dwnld_Context->mchannel = channel;
+
+#ifdef JCOP3_WR
+    cmd_count = 0;
+    SendBack_cmds = false;
+    islastcmdLoad = false;
+#endif
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    fAID_MEM = fopen(AID_MEM_PATH,"r");
+
+    if(fAID_MEM == NULL)
+    {
+        ALOGD("%s: AID data file does not exists", fn);
+        memcpy(&ArrayOfAIDs[2][1],&SelectAla[0],sizeof(SelectAla));
+        ArrayOfAIDs[2][0] = sizeof(SelectAla);
+    }
+    else
+    {
+        /*Change is required aidLen = 0x00*/
+        uint8_t aidLen = 0x00;
+        int32_t wStatus = 0;
+
+    while(!(feof(fAID_MEM)))
+    {
+        /*the length is not incremented*/
+        wStatus = FSCANF_BYTE(fAID_MEM,"%2x",&ArrayOfAIDs[2][aidLen++]);
+        if(wStatus == 0)
+        {
+            ALOGE ("%s: exit: Error during read AID data", fn);
+            fclose(fAID_MEM);
+            return false;
+        }
+    }
+    ArrayOfAIDs[2][0] = aidLen - 1;
+    fclose(fAID_MEM);
+    }
+    lsExecuteResp[0] = TAG_LSES_RESP;
+    lsExecuteResp[1] = TAG_LSES_RSPLEN;
+    lsExecuteResp[2] = LS_ABORT_SW1;
+    lsExecuteResp[3] = LS_ABORT_SW2;
+#endif
+#ifdef JCOP3_WR
+    pBuffer = Cmd_Buffer;
+#endif
+    mIsInit = true;
+    ALOGD ("%s: exit", fn);
+    return (true);
+}
+
+
+/*******************************************************************************
+**
+** Function:        finalize
+**
+** Description:     Release all resources.
+**
+** Returns:         None
+**
+*******************************************************************************/
+void finalize ()
+{
+    static const char fn [] = "Ala_finalize";
+    ALOGD ("%s: enter", fn);
+    mIsInit       = false;
+    if(gpAla_Dwnld_Context != NULL)
+    {
+        gpAla_Dwnld_Context->mchannel = NULL;
+        free(gpAla_Dwnld_Context);
+        gpAla_Dwnld_Context = NULL;
+    }
+    ALOGD ("%s: exit", fn);
+}
+
+/*******************************************************************************
+**
+** Function:        Perform_ALA
+**
+** Description:     Performs the ALA download sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS Perform_ALA(const char *name,const char *dest, const uint8_t *pdata,
+uint16_t len, uint8_t *respSW)
+#else
+tJBL_STATUS Perform_ALA(const char *name, const uint8_t *pdata, uint16_t len)
+#endif
+{
+    static const char fn [] = "Perform_ALA";
+    static const char Ala_path[] = APPLET_PATH;
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD ("%s: enter; sha-len=%d", fn, len);
+
+    if(mIsInit == false)
+    {
+        ALOGD ("%s: ALA lib is not initialized", fn);
+        status = STATUS_FAILED;
+    }
+    else if((pdata == NULL) ||
+            (len == 0x00))
+    {
+        ALOGD ("%s: Invalid SHA-data", fn);
+    }
+    else
+    {
+        StoreData[0] = STORE_DATA_TAG;
+        StoreData[1] = len;
+        memcpy(&StoreData[2], pdata, len);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        status = ALA_update_seq_handler(Applet_load_seqhandler, name, dest);
+        if((status != STATUS_OK)&&(lsExecuteResp[2] == 0x90)&&
+        (lsExecuteResp[3] == 0x00))
+        {
+            lsExecuteResp[2] = LS_ABORT_SW1;
+            lsExecuteResp[3] = LS_ABORT_SW2;
+        }
+        memcpy(&respSW[0],&lsExecuteResp[0],4);
+        ALOGD ("%s: lsExecuteScript Response SW=%2x%2x",fn, lsExecuteResp[2],
+        lsExecuteResp[3]);
+#else
+        status = ALA_update_seq_handler(Applet_load_seqhandler, name);
+#endif
+    }
+
+    ALOGD("%s: exit; status=0x0%x", fn, status);
+    return status;
+}
+#if(NXP_LDR_SVC_VER_2 == FALSE)
+/*******************************************************************************
+**
+** Function:        GetJsbl_Certificate_ID
+**
+** Description:     Performs the GetJsbl_Certificate_ID sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS GetJsbl_Certificate_Refkey(uint8_t *pKey, int32_t *pKeylen)
+{
+    static const char fn [] = "GetJsbl_Certificate_ID";
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD ("%s: enter", fn);
+
+    if(mIsInit == false)
+    {
+        ALOGD ("%s: ALA lib is not initialized", fn);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        status = JsblCerId_seq_handler(Jsblcer_id_seqhandler);
+        if(status == STATUS_SUCCESS)
+        {
+            if(Jsbl_keylen != 0x00)
+            {
+                *pKeylen = (int32_t)Jsbl_keylen;
+                memcpy(pKey, Jsbl_RefKey, Jsbl_keylen);
+                Jsbl_keylen = 0;
+            }
+        }
+    }
+
+    ALOGD("%s: exit; status=0x0%x", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        JsblCerId_seq_handler
+**
+** Description:     Performs get JSBL Certificate Identifier sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JsblCerId_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo))
+{
+    static const char fn[] = "JsblCerId_seq_handler";
+    uint16_t seq_counter = 0;
+    Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->Image_info;
+    Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context->Transcv_Info;
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD("%s: enter", fn);
+
+    while((seq_handler[seq_counter]) != NULL )
+    {
+        status = STATUS_FAILED;
+        status = (*(seq_handler[seq_counter]))(&update_info, status, &trans_info );
+        if(STATUS_SUCCESS != status)
+        {
+            ALOGE("%s: exiting; status=0x0%X", fn, status);
+            break;
+        }
+        seq_counter++;
+    }
+
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+#else
+
+/*******************************************************************************
+**
+** Function:        GetLs_Version
+**
+** Description:     Performs the GetLs_Version sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS GetLs_Version(uint8_t *pVersion)
+{
+    static const char fn [] = "GetLs_Version";
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD ("%s: enter", fn);
+
+    if(mIsInit == false)
+    {
+        ALOGD ("%s: ALA lib is not initialized", fn);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        status = GetVer_seq_handler(Jsblcer_id_seqhandler);
+        if(status == STATUS_SUCCESS)
+        {
+            pVersion[0] = 2;
+            pVersion[1] = 0;
+            memcpy(&pVersion[2], lsVersionArr, sizeof(lsVersionArr));
+            ALOGD("%s: GetLsVersion is =0x0%x%x", fn, lsVersionArr[0],lsVersionArr[1]);
+        }
+    }
+    ALOGD("%s: exit; status=0x0%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        Get_LsAppletStatus
+**
+** Description:     Performs the Get_LsAppletStatus sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS Get_LsAppletStatus(uint8_t *pVersion)
+{
+    static const char fn [] = "GetLs_Version";
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD ("%s: enter", fn);
+
+    if(mIsInit == false)
+    {
+        ALOGD ("%s: ALA lib is not initialized", fn);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        status = GetLsStatus_seq_handler(ls_GetStatus_seqhandler);
+        if(status == STATUS_SUCCESS)
+        {
+            pVersion[0] = lsGetStatusArr[0];
+            pVersion[1] = lsGetStatusArr[1];
+            ALOGD("%s: GetLsAppletStatus is =0x0%x%x", fn, lsGetStatusArr[0],lsGetStatusArr[1]);
+        }
+    }
+    ALOGD("%s: exit; status=0x0%x", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        GetVer_seq_handler
+**
+** Description:     Performs GetVer_seq_handler sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS GetVer_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t*
+        pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo))
+{
+    static const char fn[] = "GetVer_seq_handler";
+    uint16_t seq_counter = 0;
+    Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->Image_info;
+    Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context->Transcv_Info;
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD("%s: enter", fn);
+
+    while((seq_handler[seq_counter]) != NULL )
+    {
+        status = STATUS_FAILED;
+        status = (*(seq_handler[seq_counter]))(&update_info, status, &trans_info );
+        if(STATUS_SUCCESS != status)
+        {
+            ALOGE("%s: exiting; status=0x0%X", fn, status);
+            break;
+        }
+        seq_counter++;
+    }
+
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        GetLsStatus_seq_handler
+**
+** Description:     Performs GetVer_seq_handler sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS GetLsStatus_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t*
+        pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo))
+{
+    static const char fn[] = "ls_GetStatus_seqhandler";
+    uint16_t seq_counter = 0;
+    Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->Image_info;
+    Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context->Transcv_Info;
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD("%s: enter", fn);
+
+    while((seq_handler[seq_counter]) != NULL )
+    {
+        status = STATUS_FAILED;
+        status = (*(seq_handler[seq_counter]))(&update_info, status, &trans_info );
+        if(STATUS_SUCCESS != status)
+        {
+            ALOGE("%s: exiting; status=0x0%X", fn, status);
+            break;
+        }
+        seq_counter++;
+    }
+
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+#endif
+/*******************************************************************************
+**
+** Function:        ALA_update_seq_handler
+**
+** Description:     Performs the ALA update sequence handler sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_update_seq_handler(tJBL_STATUS (*seq_handler[])
+        (Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t*
+                pInfo), const char *name, const char *dest)
+#else
+tJBL_STATUS ALA_update_seq_handler(tJBL_STATUS (*seq_handler[])(Ala_ImageInfo_t* pContext, tJBL_STATUS status, Ala_TranscieveInfo_t* pInfo), const char *name)
+#endif
+{
+    static const char fn[] = "ALA_update_seq_handler";
+    static const char Ala_path[] = APPLET_PATH;
+    uint16_t seq_counter = 0;
+    Ala_ImageInfo_t update_info = (Ala_ImageInfo_t )gpAla_Dwnld_Context->
+        Image_info;
+    Ala_TranscieveInfo_t trans_info = (Ala_TranscieveInfo_t )gpAla_Dwnld_Context
+    ->Transcv_Info;
+    tJBL_STATUS status = STATUS_FAILED;
+    ALOGD("%s: enter", fn);
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    if(dest != NULL)
+    {
+        strlcat(update_info.fls_RespPath, dest, sizeof(update_info.fls_RespPath));
+        ALOGD("Loader Service response data path/destination: %s", dest);
+        update_info.bytes_wrote = 0xAA;
+    }
+    else
+    {
+        update_info.bytes_wrote = 0x55;
+    }
+    if((ALA_UpdateExeStatus(LS_DEFAULT_STATUS))!= true)
+    {
+        return false;
+    }
+#endif
+    strlcat(update_info.fls_path, name, sizeof(update_info.fls_path));
+    ALOGD("Selected applet to install is: %s", update_info.fls_path);
+
+    while((seq_handler[seq_counter]) != NULL )
+    {
+        status = STATUS_FAILED;
+        status = (*(seq_handler[seq_counter]))(&update_info, status,
+                &trans_info);
+        if(STATUS_SUCCESS != status)
+        {
+            ALOGE("%s: exiting; status=0x0%X", fn, status);
+            break;
+        }
+        seq_counter++;
+    }
+
+    ALA_CloseChannel(&update_info, STATUS_FAILED, &trans_info);
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+
+}
+/*******************************************************************************
+**
+** Function:        ALA_OpenChannel
+**
+** Description:     Creates the logical channel with ala
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_OpenChannel(Ala_ImageInfo_t *Os_info, tJBL_STATUS status,
+        Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn[] = "ALA_OpenChannel";
+    bool stat = false;
+    int32_t recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+    }
+    else
+    {
+        Os_info->channel_cnt = 0x00;
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (int32_t)sizeof(OpenChannel);
+        pTranscv_Info->sRecvlength = 1024;//(int32_t)sizeof(int32_t);
+        memcpy(pTranscv_Info->sSendData, OpenChannel, pTranscv_Info->sSendlength);
+
+        ALOGD("%s: Calling Secure Element Transceive", fn);
+        stat = mchannel->transceive (pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+        if(stat != true &&
+           (recvBufferActualSize < 0x03))
+        {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            if(recvBufferActualSize == 0x02)
+            memcpy(&lsExecuteResp[2],
+                    &pTranscv_Info->sRecvData[recvBufferActualSize-2],2);
+#endif
+            status = STATUS_FAILED;
+            ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
+        }
+        else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] != 0x90) &&
+               (pTranscv_Info->sRecvData[recvBufferActualSize-1] != 0x00)))
+        {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            memcpy(&lsExecuteResp[2],
+                    &pTranscv_Info->sRecvData[recvBufferActualSize-2],2);
+#endif
+            status = STATUS_FAILED;
+            ALOGE("%s: invalid response = 0x%X", fn, status);
+        }
+        else
+        {
+            uint8_t cnt = Os_info->channel_cnt;
+            Os_info->Channel_Info[cnt].channel_id = pTranscv_Info->sRecvData[recvBufferActualSize-3];
+            Os_info->Channel_Info[cnt].isOpend = true;
+            Os_info->channel_cnt++;
+            status = STATUS_OK;
+        }
+    }
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_SelectAla
+**
+** Description:     Creates the logical channel with ala
+**                  Channel_id will be used for any communication with Ala
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_SelectAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn[] = "ALA_SelectAla";
+    bool stat = false;
+    int32_t recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    uint8_t selectCnt = 3;
+#endif
+    ALOGD("%s: enter", fn);
+
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+    }
+    else
+    {
+        pTranscv_Info->sSendData[0] = Os_info->Channel_Info[0].channel_id;
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (int32_t)sizeof(SelectAla);
+        pTranscv_Info->sRecvlength = 1024;//(int32_t)sizeof(int32_t);
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    while((selectCnt--) > 0)
+    {
+        memcpy(&(pTranscv_Info->sSendData[1]), &ArrayOfAIDs[selectCnt][2],
+                ((ArrayOfAIDs[selectCnt][0])-1));
+        pTranscv_Info->sSendlength = (int32_t)ArrayOfAIDs[selectCnt][0];
+        /*If NFC/SPI Deinitialize requested*/
+#else
+        memcpy(&(pTranscv_Info->sSendData[1]), &SelectAla[1], sizeof(SelectAla)-1);
+#endif
+        ALOGD("%s: Calling Secure Element Transceive with Loader service AID", fn);
+
+        stat = mchannel->transceive (pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+        if(stat != true &&
+           (recvBufferActualSize == 0x00))
+        {
+            status = STATUS_FAILED;
+            ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            break;
+#endif
+        }
+        else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+               (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)))
+        {
+            status = Process_SelectRsp(pTranscv_Info->sRecvData, (recvBufferActualSize-2));
+            if(status != STATUS_OK)
+            {
+                ALOGE("%s: Select Ala Rsp doesnt have a valid key; status = 0x%X", fn, status);
+            }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+           /*If AID is found which is successfully selected break while loop*/
+           if(status == STATUS_OK)
+           {
+               uint8_t totalLen = ArrayOfAIDs[selectCnt][0];
+               uint8_t cnt  = 0;
+               int32_t wStatus= 0;
+               status = STATUS_FAILED;
+
+               fAID_MEM = fopen(AID_MEM_PATH,"w+");
+
+               if(fAID_MEM == NULL)
+               {
+                   ALOGE("Error opening AID data file for writing: %s",
+                           strerror(errno));
+                   return status;
+               }
+               while(cnt <= totalLen)
+               {
+                   wStatus = fprintf(fAID_MEM, "%02x",
+                           ArrayOfAIDs[selectCnt][cnt++]);
+                   if(wStatus != 2)
+                   {
+                      ALOGE("%s: Error writing AID data to AID_MEM file: %s",
+                              fn, strerror(errno));
+                      break;
+                   }
+               }
+               if(wStatus == 2)
+                   status = STATUS_OK;
+               fclose(fAID_MEM);
+               break;
+           }
+#endif
+        }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] != 0x90)))
+        {
+            /*Copy the response SW in failure case*/
+            memcpy(&lsExecuteResp[2], &(pTranscv_Info->
+                    sRecvData[recvBufferActualSize-2]),2);
+        }
+#endif
+        else
+        {
+            status = STATUS_FAILED;
+        }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    }
+#endif
+    }
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_StoreData
+**
+** Description:     It is used to provide the ALA with an Unique
+**                  Identifier of the Application that has triggered the ALA script.
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_StoreData(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn[] = "ALA_StoreData";
+    bool stat = false;
+    int32_t recvBufferActualSize = 0;
+    int32_t xx=0, len = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+    }
+    else
+    {
+        len = StoreData[1] + 2;  //+2 offset is for tag value and length byte
+        pTranscv_Info->sSendData[xx++] = STORE_DATA_CLA | (Os_info->Channel_Info[0].channel_id);
+        pTranscv_Info->sSendData[xx++] = STORE_DATA_INS;
+        pTranscv_Info->sSendData[xx++] = 0x00; //P1
+        pTranscv_Info->sSendData[xx++] = 0x00; //P2
+        pTranscv_Info->sSendData[xx++] = len;
+        memcpy(&(pTranscv_Info->sSendData[xx]), StoreData, len);
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (int32_t)(xx + sizeof(StoreData));
+        pTranscv_Info->sRecvlength = 1024;
+
+        ALOGD("%s: Calling Secure Element Transceive", fn);
+        stat = mchannel->transceive (pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+        if((stat != true) &&
+           (recvBufferActualSize == 0x00))
+        {
+            status = STATUS_FAILED;
+            ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
+        }
+        else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
+        {
+            ALOGE("STORE CMD is successful");
+            status = STATUS_SUCCESS;
+        }
+        else
+        {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            /*Copy the response SW in failure case*/
+            memcpy(&lsExecuteResp[2], &(pTranscv_Info->sRecvData
+                    [recvBufferActualSize-2]),2);
+#endif
+            status = STATUS_FAILED;
+        }
+    }
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_loadapplet
+**
+** Description:     Reads the script from the file and sent to Ala
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_loadapplet(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn [] = "ALA_loadapplet";
+    bool    stat = false;
+    int wResult, size =0;
+    int32_t wIndex,wCount=0;
+    int32_t wLen = 0;
+    int32_t recvBufferActualSize = 0;
+    uint8_t temp_buf[1024];
+    uint8_t len_byte=0, offset =0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGE("%s: invalid parameter", fn);
+        return status;
+    }
+    Os_info->bytes_read = 0;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    bool    reachEOFCheck = false;
+    tJBL_STATUS tag40_found = STATUS_FAILED;
+    if(Os_info->bytes_wrote == 0xAA)
+    {
+        Os_info->fResp = fopen(Os_info->fls_RespPath, "a+");
+        if(Os_info->fResp == NULL)
+        {
+            ALOGE("Error opening response recording file <%s> for reading: %s",
+            Os_info->fls_path, strerror(errno));
+            return status;
+        }
+        ALOGD("%s: Response OUT FILE path is successfully created", fn);
+    }
+    else
+    {
+        ALOGD("%s: Response Out file is optional as per input", fn);
+    }
+#endif
+    Os_info->fp = fopen(Os_info->fls_path, "r");
+
+    if (Os_info->fp == NULL) {
+        ALOGE("Error opening OS image file <%s> for reading: %s",
+                    Os_info->fls_path, strerror(errno));
+        return status;
+    }
+    wResult = fseek(Os_info->fp, 0L, SEEK_END);
+    if (wResult) {
+        ALOGE("Error seeking end OS image file %s", strerror(errno));
+        goto exit;
+    }
+    Os_info->fls_size = ftell(Os_info->fp);
+    ALOGE("fls_size=%d", Os_info->fls_size);
+    if (Os_info->fls_size < 0) {
+        ALOGE("Error ftelling file %s", strerror(errno));
+        goto exit;
+    }
+    wResult = fseek(Os_info->fp, 0L, SEEK_SET);
+    if (wResult) {
+        ALOGE("Error seeking start image file %s", strerror(errno));
+        goto exit;
+    }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    status = ALA_Check_KeyIdentifier(Os_info, status, pTranscv_Info,
+        NULL, STATUS_FAILED, 0);
+#else
+    status = ALA_Check_KeyIdentifier(Os_info, status, pTranscv_Info);
+#endif
+    if(status != STATUS_OK)
+    {
+        goto exit;
+    }
+    while(!feof(Os_info->fp) &&
+            (Os_info->bytes_read < Os_info->fls_size))
+    {
+        len_byte = 0x00;
+        offset = 0;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        /*Check if the certificate/ is verified or not*/
+        if(status != STATUS_OK)
+        {
+            goto exit;
+        }
+#endif
+        memset(temp_buf, 0, sizeof(temp_buf));
+        ALOGE("%s; Start of line processing", fn);
+        status = ALA_ReadScript(Os_info, temp_buf);
+        if(status != STATUS_OK)
+        {
+            goto exit;
+        }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        else if(status == STATUS_OK)
+        {
+            /*Reset the flag in case further commands exists*/
+            reachEOFCheck = false;
+        }
+#endif
+        if(temp_buf[offset] == TAG_ALA_CMD_ID)
+        {
+            /*
+             * start sending the packet to Ala
+             * */
+            offset = offset+1;
+            len_byte = Numof_lengthbytes(&temp_buf[offset], &wLen);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            /*If the len data not present or
+             * len is less than or equal to 32*/
+            if((len_byte == 0)||(wLen <= 32))
+#else
+            if((len_byte == 0))
+#endif
+            {
+                ALOGE("Invalid length zero");
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                goto exit;
+#else
+                return status;
+#endif
+            }
+            else
+            {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                tag40_found = STATUS_OK;
+#endif
+                offset = offset+len_byte;
+                pTranscv_Info->sSendlength = wLen;
+                memcpy(pTranscv_Info->sSendData, &temp_buf[offset], wLen);
+            }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
+#else
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
+#endif
+            if(status != STATUS_OK)
+            {
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                /*When the switching of LS 6320 case*/
+                if(status == STATUS_FILE_NOT_FOUND)
+                {
+                    /*When 6320 occurs close the existing channels*/
+                    ALA_CloseChannel(Os_info,status,pTranscv_Info);
+
+                    status = STATUS_FAILED;
+                    status = ALA_OpenChannel(Os_info,status,pTranscv_Info);
+                    if(status == STATUS_OK)
+                    {
+                        ALOGD("SUCCESS:Post Switching LS open channel");
+                        status = STATUS_FAILED;
+                        status = ALA_SelectAla(Os_info,status,pTranscv_Info);
+                        if(status == STATUS_OK)
+                        {
+                            ALOGD("SUCCESS:Post Switching LS select");
+                            status = STATUS_FAILED;
+                            status = ALA_StoreData(Os_info,status,pTranscv_Info);
+                            if(status == STATUS_OK)
+                            {
+                                /*Enable certificate and signature verification*/
+                                tag40_found = STATUS_OK;
+                                lsExecuteResp[2] = 0x90;
+                                lsExecuteResp[3] = 0x00;
+                                reachEOFCheck = true;
+                                continue;
+                            }
+                            ALOGE("Post Switching LS store data failure");
+                        }
+                        ALOGE("Post Switching LS select failure");
+                    }
+                    ALOGE("Post Switching LS failure");
+                }
+                ALOGE("Sending packet to ala failed");
+                goto exit;
+#else
+                return status;
+#endif
+            }
+        }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        else if((temp_buf[offset] == (0x7F))&&(temp_buf[offset+1] == (0x21)))
+        {
+            ALOGD("TAGID: Encountered again certificate tag 7F21");
+            if(tag40_found == STATUS_OK)
+            {
+            ALOGD("2nd Script processing starts with reselect");
+            status = STATUS_FAILED;
+            status = ALA_SelectAla(Os_info,status,pTranscv_Info);
+            if(status == STATUS_OK)
+            {
+                ALOGD("2nd Script select success next store data command");
+                status = STATUS_FAILED;
+                status = ALA_StoreData(Os_info,status,pTranscv_Info);
+                if(status == STATUS_OK)
+                {
+                    ALOGD("2nd Script store data success next certificate verification");
+                    offset = offset+2;
+                    len_byte = Numof_lengthbytes(&temp_buf[offset], &wLen);
+                    status = ALA_Check_KeyIdentifier(Os_info, status, pTranscv_Info,
+                    temp_buf, STATUS_OK, wLen+len_byte+2);
+                    }
+                }
+                /*If the certificate and signature is verified*/
+                if(status == STATUS_OK)
+                {
+                    /*If the certificate is verified for 6320 then new
+                     * script starts*/
+                    tag40_found = STATUS_FAILED;
+                }
+                /*If the certificate or signature verification failed*/
+                else{
+                  goto exit;
+                }
+            }
+            /*Already certificate&Sginature verified previously skip 7f21& tag 60*/
+            else
+            {
+                memset(temp_buf, 0, sizeof(temp_buf));
+                status = ALA_ReadScript(Os_info, temp_buf);
+                if(status != STATUS_OK)
+                {
+                    ALOGE("%s; Next Tag has to TAG 60 not found", fn);
+                    goto exit;
+                }
+                if(temp_buf[offset] == TAG_JSBL_HDR_ID)
+                continue;
+                else
+                    goto exit;
+            }
+        }
+#endif
+        else
+        {
+            /*
+             * Invalid packet received in between stop processing packet
+             * return failed status
+             * */
+            status = STATUS_FAILED;
+            break;
+        }
+    }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    if(Os_info->bytes_wrote == 0xAA)
+    {
+        fclose(Os_info->fResp);
+    }
+    ALA_UpdateExeStatus(LS_SUCCESS_STATUS);
+#endif
+    wResult = fclose(Os_info->fp);
+    ALOGE("%s exit;End of Load Applet; status=0x%x",fn, status);
+    return status;
+exit:
+    wResult = fclose(Os_info->fp);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    if(Os_info->bytes_wrote == 0xAA)
+    {
+        fclose(Os_info->fResp);
+    }
+    /*Script ends with SW 6320 and reached END OF FILE*/
+    if(reachEOFCheck == true)
+    {
+       status = STATUS_OK;
+       ALA_UpdateExeStatus(LS_SUCCESS_STATUS);
+    }
+#endif
+    ALOGE("%s close fp and exit; status= 0x%X", fn,status);
+    return status;
+
+}
+/*******************************************************************************
+**
+** Function:        ALA_ProcessResp
+**
+** Description:     Process the response packet received from Ala
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_Check_KeyIdentifier(Ala_ImageInfo_t *Os_info, tJBL_STATUS status,
+   Ala_TranscieveInfo_t *pTranscv_Info, uint8_t* temp_buf, tJBL_STATUS flag,
+   int32_t wNewLen)
+#else
+tJBL_STATUS ALA_Check_KeyIdentifier(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+#endif
+{
+    static const char fn[] = "ALA_Check_KeyIdentifier";
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    uint16_t offset = 0x00, len_byte=0;
+#else
+    uint8_t offset = 0x00, len_byte=0;
+#endif
+    tJBL_STATUS key_found = STATUS_FAILED;
+    status = STATUS_FAILED;
+    uint8_t read_buf[1024];
+    bool stat = false;
+    int32_t wLen, recvBufferActualSize=0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    uint8_t certf_found = STATUS_FAILED;
+    uint8_t sign_found = STATUS_FAILED;
+#endif
+    ALOGD("%s: enter", fn);
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    while(!feof(Os_info->fp) &&
+            (Os_info->bytes_read < Os_info->fls_size))
+    {
+        offset = 0x00;
+        wLen = 0;
+        if(flag == STATUS_OK)
+        {
+            /*If the 7F21 TAG is already read: After TAG 40*/
+            memcpy(read_buf, temp_buf, wNewLen);
+            status = STATUS_OK;
+            flag   = STATUS_FAILED;
+        }
+        else
+        {
+            /*If the 7F21 TAG is not read: Before TAG 40*/
+            status = ALA_ReadScript(Os_info, read_buf);
+        }
+        if(status != STATUS_OK)
+            return status;
+        if(STATUS_OK == Check_Complete_7F21_Tag(Os_info,pTranscv_Info,
+                read_buf, &offset))
+        {
+            ALOGD("%s: Certificate is verified", fn);
+            certf_found = STATUS_OK;
+            break;
+        }
+        /*The Loader Service Client ignores all subsequent commands starting by tag
+         * �7F21� or tag �60� until the first command starting by tag �40� is found*/
+        else if(((read_buf[offset] == TAG_ALA_CMD_ID)&&(certf_found != STATUS_OK)))
+        {
+            ALOGE("%s: NOT FOUND Root entity identifier's certificate", fn);
+            status = STATUS_FAILED;
+            return status;
+        }
+    }
+#endif
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    memset(read_buf, 0, sizeof(read_buf));
+    if(certf_found == STATUS_OK)
+    {
+#else
+        while(!feof(Os_info->fp))
+        {
+#endif
+        offset  = 0x00;
+        wLen    = 0;
+        status  = ALA_ReadScript(Os_info, read_buf);
+        if(status != STATUS_OK)
+            return status;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        else
+            status = STATUS_FAILED;
+
+        if((read_buf[offset] == TAG_JSBL_HDR_ID)&&
+        (certf_found != STATUS_FAILED)&&(sign_found != STATUS_OK))
+#else
+        if(read_buf[offset] == TAG_JSBL_HDR_ID &&
+           key_found != STATUS_OK)
+#endif
+        {
+            //TODO check the SElect cmd response and return status accordingly
+            ALOGD("TAGID: TAG_JSBL_HDR_ID");
+            offset = offset+1;
+            len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
+            offset = offset + len_byte;
+#if(NXP_LDR_SVC_VER_2 == FALSE)
+            if(read_buf[offset] == TAG_JSBL_KEY_ID)
+            {
+                ALOGE("TAGID: TAG_JSBL_KEY_ID");
+                offset = offset+1;
+                wLen = read_buf[offset];
+                offset = offset+1;
+                key_found = memcmp(&read_buf[offset], Select_Rsp,
+                Select_Rsp_Len);
+
+                if(key_found == STATUS_OK)
+                {
+                    ALOGE("Key is matched");
+                    offset = offset + wLen;
+#endif
+                    if(read_buf[offset] == TAG_SIGNATURE_ID)
+                    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                        offset = offset+1;
+                        len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
+                        offset = offset + len_byte;
+#endif
+                        ALOGE("TAGID: TAG_SIGNATURE_ID");
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                        pTranscv_Info->sSendlength = wLen+5;
+
+                        pTranscv_Info->sSendData[0] = 0x00;
+                        pTranscv_Info->sSendData[1] = 0xA0;
+                        pTranscv_Info->sSendData[2] = 0x00;
+                        pTranscv_Info->sSendData[3] = 0x00;
+                        pTranscv_Info->sSendData[4] = wLen;
+
+                        memcpy(&(pTranscv_Info->sSendData[5]),
+                        &read_buf[offset], wLen);
+#else
+                        offset = offset+1;
+                        wLen = 0;
+                        len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
+                        if(len_byte == 0)
+                        {
+                            ALOGE("Invalid length zero");
+                            return STATUS_FAILED;
+                        }
+                        else
+                        {
+                            offset = offset+len_byte;
+                            pTranscv_Info->sSendlength = wLen;
+                            memcpy(pTranscv_Info->sSendData, &read_buf[offset],
+                            wLen);
+                        }
+#endif
+                        ALOGE("%s: start transceive for length %ld", fn,
+                        pTranscv_Info->sSendlength);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                        status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Sign);
+#else
+                        status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
+#endif
+                        if(status != STATUS_OK)
+                        {
+                            return status;
+                        }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+                        else
+                        {
+                            sign_found = STATUS_OK;
+                        }
+#endif
+                    }
+#if(NXP_LDR_SVC_VER_2 == FALSE)
+                }
+                else
+                {
+                    /*
+                     * Discard the packet and goto next line
+                     * */
+                }
+            }
+            else
+            {
+                ALOGE("Invalid Tag ID");
+                status = STATUS_FAILED;
+                break;
+            }
+#endif
+        }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        else if(read_buf[offset] != TAG_JSBL_HDR_ID )
+        {
+            status = STATUS_FAILED;
+        }
+#else
+        else if(read_buf[offset] == TAG_ALA_CMD_ID &&
+                key_found == STATUS_OK)
+        {
+            /*Key match is success and start sending the packet to Ala
+             * return status ok
+             * */
+            ALOGE("TAGID: TAG_ALA_CMD_ID");
+            offset = offset+1;
+            wLen = 0;
+            len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
+            if(len_byte == 0)
+            {
+                ALOGE("Invalid length zero");
+                return STATUS_FAILED;
+            }
+            else
+            {
+                offset = offset+len_byte;
+                pTranscv_Info->sSendlength = wLen;
+                memcpy(pTranscv_Info->sSendData, &read_buf[offset], wLen);
+            }
+
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
+            break;
+        }
+        else if(read_buf[offset] == TAG_JSBL_HDR_ID &&
+                key_found == STATUS_OK)
+        {
+            /*Key match is success
+             * Discard the packets untill we found header T=0x40
+             * */
+        }
+        else
+        {
+            /*Invalid header*/
+            status = STATUS_FAILED;
+            break;
+        }
+#endif
+
+#if(NXP_LDR_SVC_VER_2 == FALSE)
+        }
+#else
+    }
+    else
+    {
+        ALOGE("%s : Exit certificate verification failed", fn);
+    }
+#endif
+
+    ALOGD("%s: exit: status=0x%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_ReadScript
+**
+** Description:     Reads the current line if the script
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_ReadScript(Ala_ImageInfo_t *Os_info, uint8_t *read_buf)
+{
+    static const char fn[]="ALA_ReadScript";
+    int32_t wCount, wLen, wIndex = 0;
+    uint8_t len_byte = 0;
+    int wResult = 0;
+    tJBL_STATUS status = STATUS_FAILED;
+    int32_t lenOff = 1;
+
+    ALOGD("%s: enter", fn);
+
+    for(wCount =0; (wCount < 2 && !feof(Os_info->fp)); wCount++, wIndex++)
+    {
+        wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
+    }
+    if(wResult == 0)
+        return STATUS_FAILED;
+
+    Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
+
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    if((read_buf[0]==0x7f) && (read_buf[1]==0x21))
+    {
+        for(wCount =0; (wCount < 1 && !feof(Os_info->fp)); wCount++, wIndex++)
+        {
+            wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
+        }
+        if(wResult == 0)
+        {
+            ALOGE("%s: Exit Read Script failed in 7F21 ", fn);
+            return STATUS_FAILED;
+        }
+        /*Read_Script from wCount*2 to wCount*1 */
+        Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
+        lenOff = 2;
+    }
+    else if((read_buf[0] == 0x40)||(read_buf[0] == 0x60))
+    {
+        lenOff = 1;
+    }
+    /*If TAG is neither 7F21 nor 60 nor 40 then ABORT execution*/
+    else
+    {
+        ALOGE("Invalid TAG 0x%X found in the script", read_buf[0]);
+        return STATUS_FAILED;
+    }
+#endif
+
+    if(read_buf[lenOff] == 0x00)
+    {
+        ALOGE("Invalid length zero");
+        len_byte = 0x00;
+        return STATUS_FAILED;
+    }
+    else if((read_buf[lenOff] & 0x80) == 0x80)
+    {
+        len_byte = read_buf[lenOff] & 0x0F;
+        len_byte = len_byte +1; //1 byte added for byte 0x81
+
+        ALOGD("%s: Length byte Read from 0x80 is 0x%x ", fn, len_byte);
+
+        if(len_byte == 0x02)
+        {
+            for(wCount =0; (wCount < 1 && !feof(Os_info->fp)); wCount++, wIndex++)
+            {
+                wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
+            }
+            if(wResult == 0)
+            {
+                ALOGE("%s: Exit Read Script failed in length 0x02 ", fn);
+                return STATUS_FAILED;
+            }
+
+            wLen = read_buf[lenOff+1];
+            Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
+            ALOGD("%s: Length of Read Script in len_byte= 0x02 is 0x%lx ", fn, wLen);
+        }
+        else if(len_byte == 0x03)
+        {
+            for(wCount =0; (wCount < 2 && !feof(Os_info->fp)); wCount++, wIndex++)
+            {
+                wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
+            }
+            if(wResult == 0)
+            {
+                ALOGE("%s: Exit Read Script failed in length 0x03 ", fn);
+                return STATUS_FAILED;
+            }
+
+            Os_info->bytes_read = Os_info->bytes_read + (wCount*2);
+            wLen = read_buf[lenOff+1]; //Length of the packet send to ALA
+            wLen = ((wLen << 8) | (read_buf[lenOff+2]));
+            ALOGD("%s: Length of Read Script in len_byte= 0x03 is 0x%lx ", fn, wLen);
+        }
+        else
+        {
+            /*Need to provide the support if length is more than 2 bytes*/
+            ALOGE("Length recived is greater than 3");
+            return STATUS_FAILED;
+        }
+    }
+    else
+    {
+        len_byte = 0x01;
+        wLen = read_buf[lenOff];
+        ALOGE("%s: Length of Read Script in len_byte= 0x01 is 0x%lx ", fn, wLen);
+    }
+
+
+    for(wCount =0; (wCount < wLen && !feof(Os_info->fp)); wCount++, wIndex++)
+    {
+        wResult = FSCANF_BYTE(Os_info->fp,"%2X",(unsigned int*)&read_buf[wIndex]);
+    }
+
+    if(wResult == 0)
+    {
+        ALOGE("%s: Exit Read Script failed in fscanf function ", fn);
+        return status;
+    }
+    else
+    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        Os_info->bytes_read = Os_info->bytes_read + (wCount*2)+1; //not sure why 2 added
+#else
+        Os_info->bytes_read = Os_info->bytes_read + (wCount*2)+2; //not sure why 2 added
+#endif
+        status = STATUS_OK;
+    }
+
+    ALOGD("%s: exit: status=0x%x; Num of bytes read=%d and index=%ld",
+    fn, status, Os_info->bytes_read,wIndex);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_SendtoEse
+**
+** Description:     It is used to send the packet to p61
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_SendtoEse(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn [] = "ALA_SendtoEse";
+    bool stat =false, chanl_open_cmd = false;
+    uint8_t xx=0;
+    status = STATUS_FAILED;
+    int32_t recvBufferActualSize=0, recv_len = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    ALOGD("%s: enter", fn);
+#ifdef JCOP3_WR
+    /*
+     * Bufferize_load_cmds function is implemented in JCOP
+     * */
+    status = Bufferize_load_cmds(Os_info, status, pTranscv_Info);
+    if(status != STATUS_FAILED)
+    {
+#endif
+        if(pTranscv_Info->sSendData[1] == 0x70)
+        {
+            if(pTranscv_Info->sSendData[2] == 0x00)
+            {
+                ALOGE("Channel open");
+                chanl_open_cmd = true;
+            }
+            else
+            {
+                ALOGE("Channel close");
+                for(uint8_t cnt=0; cnt < Os_info->channel_cnt; cnt++)
+                {
+                    if(Os_info->Channel_Info[cnt].channel_id == pTranscv_Info->sSendData[3])
+                    {
+                        ALOGE("Closed channel id = 0x0%x", Os_info->Channel_Info[cnt].channel_id);
+                        Os_info->Channel_Info[cnt].isOpend = false;
+                    }
+                }
+            }
+        }
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sRecvlength = 1024;
+        stat = mchannel->transceive(pTranscv_Info->sSendData,
+                                    pTranscv_Info->sSendlength,
+                                    pTranscv_Info->sRecvData,
+                                    pTranscv_Info->sRecvlength,
+                                    recvBufferActualSize,
+                                    pTranscv_Info->timeout);
+        if(stat != true)
+        {
+            ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
+        }
+        else
+        {
+            if(chanl_open_cmd == true)
+            {
+                if((recvBufferActualSize == 0x03) &&
+                   ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+                    (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)))
+                {
+                    ALOGE("open channel success");
+                    uint8_t cnt = Os_info->channel_cnt;
+                    Os_info->Channel_Info[cnt].channel_id = pTranscv_Info->sRecvData[recvBufferActualSize-3];
+                    Os_info->Channel_Info[cnt].isOpend = true;
+                    Os_info->channel_cnt++;
+                }
+                else
+                {
+                    ALOGE("channel open faield");
+                }
+            }
+            status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
+        }
+#ifdef JCOP3_WR
+    }
+    else if(SendBack_cmds == false)
+    {
+        /*
+         * Workaround for issue in JCOP
+         * Send the fake response back
+         * */
+        recvBufferActualSize = 0x03;
+        pTranscv_Info->sRecvData[0] = 0x00;
+        pTranscv_Info->sRecvData[1] = 0x90;
+        pTranscv_Info->sRecvData[2] = 0x00;
+        status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
+    }
+    else
+    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        if(islastcmdLoad == true)
+        {
+            status = Send_Backall_Loadcmds(Os_info, status, pTranscv_Info);
+            SendBack_cmds = false;
+        }else
+        {
+            memset(Cmd_Buffer, 0, sizeof(Cmd_Buffer));
+            SendBack_cmds = false;
+            status = STATUS_FAILED;
+        }
+#else
+        status = Send_Backall_Loadcmds(Os_info, status, pTranscv_Info);
+        SendBack_cmds = false;
+#endif
+    }
+#endif
+    ALOGD("%s: exit: status=0x%x", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_SendtoAla
+**
+** Description:     It is used to forward the packet to Ala
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_SendtoAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info, Ls_TagType tType)
+#else
+tJBL_STATUS ALA_SendtoAla(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+#endif
+{
+    static const char fn [] = "ALA_SendtoAla";
+    bool stat =false;
+    status = STATUS_FAILED;
+    int32_t recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    ALOGD("%s: enter", fn);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    pTranscv_Info->sSendData[0] = (0x80 | Os_info->Channel_Info[0].channel_id);
+#else
+    pTranscv_Info->sSendData[0] = (pTranscv_Info->sSendData[0] | Os_info->Channel_Info[0].channel_id);
+#endif
+    pTranscv_Info->timeout = gTransceiveTimeout;
+    pTranscv_Info->sRecvlength = 1024;
+
+    stat = mchannel->transceive(pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+    if(stat != true)
+    {
+        ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
+    }
+    else
+    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        status = ALA_ProcessResp(Os_info, recvBufferActualSize, pTranscv_Info, tType);
+#else
+        status = ALA_ProcessResp(Os_info, recvBufferActualSize, pTranscv_Info);
+#endif
+    }
+    ALOGD("%s: exit: status=0x%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_CloseChannel
+**
+** Description:     Closes the previously opened logical channel
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_CloseChannel(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn [] = "ALA_CloseChannel";
+    status = STATUS_FAILED;
+    bool stat = false;
+    uint8_t xx =0;
+    int32_t recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    uint8_t cnt = 0;
+    ALOGD("%s: enter",fn);
+
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGE("Invalid parameter");
+    }
+    else
+    {
+        for(cnt =0; (cnt < Os_info->channel_cnt); cnt++)
+        {
+            if(Os_info->Channel_Info[cnt].isOpend == false)
+                continue;
+            xx = 0;
+            pTranscv_Info->sSendData[xx++] = Os_info->Channel_Info[cnt].channel_id;
+            pTranscv_Info->sSendData[xx++] = 0x70;
+            pTranscv_Info->sSendData[xx++] = 0x80;
+            pTranscv_Info->sSendData[xx++] = Os_info->Channel_Info[cnt].channel_id;
+            pTranscv_Info->sSendData[xx++] = 0x00;
+            pTranscv_Info->sSendlength = xx;
+            pTranscv_Info->timeout = gTransceiveTimeout;
+            pTranscv_Info->sRecvlength = 1024;
+            stat = mchannel->transceive(pTranscv_Info->sSendData,
+                                        pTranscv_Info->sSendlength,
+                                        pTranscv_Info->sRecvData,
+                                        pTranscv_Info->sRecvlength,
+                                        recvBufferActualSize,
+                                        pTranscv_Info->timeout);
+            if(stat != true &&
+               recvBufferActualSize < 2)
+            {
+                ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
+            }
+            else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+                    (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
+            {
+                ALOGE("Close channel id = 0x0%x is success", Os_info->Channel_Info[cnt].channel_id);
+                status = STATUS_OK;
+            }
+            else
+            {
+                ALOGE("Close channel id = 0x0%x is failed", Os_info->Channel_Info[cnt].channel_id);
+            }
+        }
+
+    }
+    ALOGD("%s: exit; status=0x0%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_ProcessResp
+**
+** Description:     Process the response packet received from Ala
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, int32_t recvlen, Ala_TranscieveInfo_t *trans_info, Ls_TagType tType)
+#else
+tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, int32_t recvlen, Ala_TranscieveInfo_t *trans_info)
+#endif
+{
+    static const char fn [] = "ALA_ProcessResp";
+    tJBL_STATUS status = STATUS_FAILED;
+    static int32_t temp_len = 0;
+    uint8_t* RecvData = trans_info->sRecvData;
+    uint8_t xx =0;
+    char sw[2];
+
+    ALOGD("%s: enter", fn);
+
+    if(RecvData == NULL &&
+            recvlen == 0x00)
+    {
+        ALOGE("%s: Invalid parameter: status=0x%x", fn, status);
+        return status;
+    }
+    else if(recvlen >= 2)
+    {
+        sw[0] = RecvData[recvlen-2];
+        sw[1] = RecvData[recvlen-1];
+    }
+    else
+    {
+        ALOGE("%s: Invalid response; status=0x%x", fn, status);
+        return status;
+    }
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    /*Update the Global variable for storing response length*/
+    resp_len = recvlen;
+    if((sw[0] != 0x63))
+    {
+        lsExecuteResp[2] = sw[0];
+        lsExecuteResp[3] = sw[1];
+        ALOGD("%s: Process Response SW; status = 0x%x", fn, sw[0]);
+        ALOGD("%s: Process Response SW; status = 0x%x", fn, sw[1]);
+    }
+#endif
+    if((recvlen == 0x02) &&
+       (sw[0] == 0x90) &&
+       (sw[1] == 0x00))
+    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        tJBL_STATUS wStatus = STATUS_FAILED;
+        ALOGE("%s: Before Write Response", fn);
+        wStatus = Write_Response_To_OutFile(image_info, RecvData, recvlen, tType);
+        if(wStatus != STATUS_FAILED)
+#endif
+            status = STATUS_OK;
+    }
+    else if((recvlen > 0x02) &&
+            (sw[0] == 0x90) &&
+            (sw[1] == 0x00))
+    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        tJBL_STATUS wStatus = STATUS_FAILED;
+        ALOGE("%s: Before Write Response", fn);
+        wStatus = Write_Response_To_OutFile(image_info, RecvData, recvlen, tType);
+        if(wStatus != STATUS_FAILED)
+            status = STATUS_OK;
+#else
+        if(temp_len != 0)
+        {
+            memcpy((trans_info->sTemp_recvbuf+temp_len), RecvData, (recvlen-2));
+            trans_info->sSendlength = temp_len + (recvlen-2);
+            memcpy(trans_info->sSendData, trans_info->sTemp_recvbuf, trans_info->sSendlength);
+            temp_len = 0;
+        }
+        else
+        {
+            memcpy(trans_info->sSendData, RecvData, (recvlen-2));
+            trans_info->sSendlength = recvlen-2;
+        }
+        status = ALA_SendtoEse(image_info, status, trans_info);
+#endif
+    }
+#if(NXP_LDR_SVC_VER_2 == FALSE)
+    else if ((recvlen > 0x02) &&
+             (sw[0] == 0x61))
+    {
+        memcpy((trans_info->sTemp_recvbuf+temp_len), RecvData, (recvlen-2));
+        temp_len = temp_len + recvlen-2;
+        trans_info->sSendData[xx++] = image_info->Channel_Info[0].channel_id;
+        trans_info->sSendData[xx++] = 0xC0;
+        trans_info->sSendData[xx++] = 0x00;
+        trans_info->sSendData[xx++] = 0x00;
+        trans_info->sSendData[xx++] = sw[1];
+        trans_info->sSendlength = xx;
+        status = ALA_SendtoAla(image_info, status, trans_info);
+    }
+#endif
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    else if ((recvlen > 0x02) &&
+            (sw[0] == 0x63) &&
+            (sw[1] == 0x10))
+    {
+        if(temp_len != 0)
+        {
+            memcpy((trans_info->sTemp_recvbuf+temp_len), RecvData, (recvlen-2));
+            trans_info->sSendlength = temp_len + (recvlen-2);
+            memcpy(trans_info->sSendData, trans_info->sTemp_recvbuf,
+                    trans_info->sSendlength);
+            temp_len = 0;
+        }
+        else
+        {
+            memcpy(trans_info->sSendData, RecvData, (recvlen-2));
+            trans_info->sSendlength = recvlen-2;
+        }
+        status = ALA_SendtoEse(image_info, status, trans_info);
+    }
+    else if ((recvlen > 0x02) &&
+            (sw[0] == 0x63) &&
+            (sw[1] == 0x20))
+    {
+        uint8_t respLen = 0;
+        int32_t wStatus = 0;
+
+        AID_ARRAY[0] = recvlen+3;
+        AID_ARRAY[1] = 00;
+        AID_ARRAY[2] = 0xA4;
+        AID_ARRAY[3] = 0x04;
+        AID_ARRAY[4] = 0x00;
+        AID_ARRAY[5] = recvlen-2;
+        memcpy(&AID_ARRAY[6], &RecvData[0],recvlen-2);
+        memcpy(&ArrayOfAIDs[2][0], &AID_ARRAY[0], recvlen+4);
+
+        fAID_MEM = fopen(AID_MEM_PATH,"w");
+
+        if (fAID_MEM == NULL) {
+            ALOGE("Error opening AID data for writing: %s",strerror(errno));
+            return status;
+        }
+
+        /*Updating the AID_MEM with new value into AID file*/
+        while(respLen <= (recvlen+4))
+        {
+            wStatus = fprintf(fAID_MEM, "%2x", AID_ARRAY[respLen++]);
+            if(wStatus != 2)
+            {
+                ALOGE("%s: Invalid Response during fprintf; status=0x%x",
+                        fn, status);
+                fclose(fAID_MEM);
+                break;
+            }
+        }
+        if(wStatus == 2)
+        {
+            status = STATUS_FILE_NOT_FOUND;
+        }
+        else
+        {
+           status = STATUS_FAILED;
+        }
+    }
+    else if((recvlen >= 0x02) &&(
+            (sw[0] != 0x90) &&
+            (sw[0] != 0x63)&&(sw[0] != 0x61)))
+    {
+        tJBL_STATUS wStatus = STATUS_FAILED;
+        wStatus = Write_Response_To_OutFile(image_info, RecvData, recvlen, tType);
+        //if(wStatus != STATUS_FAILED)
+            //status = STATUS_OK;
+    }
+#endif
+    ALOGD("%s: exit: status=0x%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_SendtoEse
+**
+** Description:     It is used to process the received response packet from p61
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS Process_EseResponse(Ala_TranscieveInfo_t *pTranscv_Info, int32_t recv_len, Ala_ImageInfo_t *Os_info)
+{
+    static const char fn[] = "Process_EseResponse";
+    tJBL_STATUS status = STATUS_OK;
+    uint8_t xx = 0;
+    ALOGD("%s: enter", fn);
+
+    pTranscv_Info->sSendData[xx++] = (CLA_BYTE | Os_info->Channel_Info[0].channel_id);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    pTranscv_Info->sSendData[xx++] = 0xA2;
+#else
+    pTranscv_Info->sSendData[xx++] = 0xA0;
+#endif
+    if(recv_len <= 0xFF)
+    {
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        pTranscv_Info->sSendData[xx++] = 0x80;
+#else
+        pTranscv_Info->sSendData[xx++] = ONLY_BLOCK;
+#endif
+        pTranscv_Info->sSendData[xx++] = 0x00;
+        pTranscv_Info->sSendData[xx++] = (uint8_t)recv_len;
+        memcpy(&(pTranscv_Info->sSendData[xx]),pTranscv_Info->sRecvData,recv_len);
+        pTranscv_Info->sSendlength = xx+ recv_len;
+#if(NXP_LDR_SVC_VER_2)
+        status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
+#else
+        status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
+#endif
+    }
+    else
+    {
+        while(recv_len > MAX_SIZE)
+        {
+            xx = PARAM_P1_OFFSET;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            pTranscv_Info->sSendData[xx++] = 0x00;
+#else
+            pTranscv_Info->sSendData[xx++] = FIRST_BLOCK;
+#endif
+            pTranscv_Info->sSendData[xx++] = 0x00;
+            pTranscv_Info->sSendData[xx++] = MAX_SIZE;
+            recv_len = recv_len - MAX_SIZE;
+            memcpy(&(pTranscv_Info->sSendData[xx]),pTranscv_Info->sRecvData,MAX_SIZE);
+            pTranscv_Info->sSendlength = xx+ MAX_SIZE;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            /*Need not store Process eSE response's response in the out file so
+             * LS_Comm = 0*/
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
+#else
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
+#endif
+            if(status != STATUS_OK)
+            {
+                ALOGE("Sending packet to Ala failed: status=0x%x", status);
+                return status;
+            }
+        }
+        xx = PARAM_P1_OFFSET;
+        pTranscv_Info->sSendData[xx++] = LAST_BLOCK;
+        pTranscv_Info->sSendData[xx++] = 0x01;
+        pTranscv_Info->sSendData[xx++] = recv_len;
+        memcpy(&(pTranscv_Info->sSendData[xx]),pTranscv_Info->sRecvData,recv_len);
+        pTranscv_Info->sSendlength = xx+ recv_len;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info, LS_Comm);
+#else
+            status = ALA_SendtoAla(Os_info, status, pTranscv_Info);
+#endif
+    }
+    ALOGD("%s: exit: status=0x%x", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        Process_SelectRsp
+**
+** Description:     It is used to process the received response for SELECT ALA cmd
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS Process_SelectRsp(uint8_t* Recv_data, int32_t Recv_len)
+{
+    static const char fn[]="Process_SelectRsp";
+    tJBL_STATUS status = STATUS_FAILED;
+    int i = 0, len=0;
+    ALOGE("%s: enter", fn);
+
+    if(Recv_data[i] == TAG_SELECT_ID)
+    {
+        ALOGD("TAG: TAG_SELECT_ID");
+        i = i +1;
+        len = Recv_data[i];
+        i = i+1;
+        if(Recv_data[i] == TAG_ALA_ID)
+        {
+            ALOGD("TAG: TAG_ALA_ID");
+            i = i+1;
+            len = Recv_data[i];
+            i = i + 1 + len; //points to next tag name A5
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+            //points to TAG 9F08 for LS application version
+            if((Recv_data[i] == TAG_LS_VER1)&&(Recv_data[i+1] == TAG_LS_VER2))
+            {
+                uint8_t lsaVersionLen = 0;
+                ALOGD("TAG: TAG_LS_APPLICATION_VER");
+
+                i = i+2;
+                lsaVersionLen = Recv_data[i];
+                //points to TAG 9F08 LS application version
+                i = i+1;
+                memcpy(lsVersionArr, &Recv_data[i],lsaVersionLen);
+
+                //points to Identifier of the Root Entity key set identifier
+                i = i+lsaVersionLen;
+
+                if(Recv_data[i] == TAG_RE_KEYID)
+                {
+                    uint8_t rootEntityLen = 0;
+                    i = i+1;
+                    rootEntityLen = Recv_data[i];
+
+                    i = i+1;
+                    if(Recv_data[i] == TAG_LSRE_ID)
+                    {
+                        uint8_t tag42Len = 0;
+                        i = i+1;
+                        tag42Len = Recv_data[i];
+                        //copy the data including length
+                        memcpy(tag42Arr, &Recv_data[i], tag42Len+1);
+                        i = i+tag42Len+1;
+
+                        if(Recv_data[i] == TAG_LSRE_SIGNID)
+                        {
+                            uint8_t tag45Len = Recv_data[i+1];
+                            memcpy(tag45Arr, &Recv_data[i+1],tag45Len+1);
+                            status = STATUS_OK;
+                        }
+                        else
+                        {
+                            ALOGE("Invalid Root entity for TAG 45 = 0x%x; "
+                            "status=0x%x", Recv_data[i], status);
+                            return status;
+                        }
+                    }
+                    else
+                    {
+                        ALOGE("Invalid Root entity for TAG 42 = 0x%x; "
+                        "status=0x%x", Recv_data[i], status);
+                        return status;
+                    }
+                }
+                else
+                {
+                    ALOGE("Invalid Root entity key set TAG ID = 0x%x; "
+                    "status=0x%x", Recv_data[i], status);
+                    return status;
+                }
+            }
+        }
+        else
+        {
+            ALOGE("Invalid Loader Service AID TAG ID = 0x%x; status=0x%x",
+            Recv_data[i], status);
+            return status;
+        }
+    }
+    else
+    {
+        ALOGE("Invalid FCI TAG = 0x%x; status=0x%x", Recv_data[i], status);
+        return status;
+    }
+#else
+            if(Recv_data[i] == TAG_PRO_DATA_ID)
+            {
+                ALOGE("TAG: TAG_PRO_DATA_ID");
+                i = i+1;
+                len = Recv_data[i];
+                i = i + 1; //points to next tag name 61
+            }
+        }
+    }
+    else
+    {
+        /*
+         * Invalid start of TAG Name found
+         * */
+        ALOGE("Invalid TAG ID = 0x%x; status=0x%x", Recv_data[i], status);
+        return status;
+    }
+
+    if((i < Recv_len) &&
+       (Recv_data[i] == TAG_JSBL_KEY_ID))
+    {
+        /*
+         * Valid Key is found
+         * Copy the data into Select_Rsp
+         * */
+        ALOGE("Valid key id is found");
+        i = i +1;
+        len = Recv_data[i];
+        if(len != 0x00)
+        {
+            i = i+1;
+            memcpy(Select_Rsp, &Recv_data[i], len);
+            Select_Rsp_Len = len;
+            status = STATUS_OK;
+        }
+        /*
+         * Identifier of the certificate storing
+         * JSBL encryption key
+         * */
+        i = i + len;
+        if(Recv_data[i] == TAG_JSBL_CER_ID)
+        {
+            i = i+1;
+            len = Recv_data[i];
+            if(len != 0x00)
+            {
+                i = i+1;
+                Jsbl_keylen = len;
+                memcpy(Jsbl_RefKey, &Recv_data[i], len);
+            }
+        }
+    }
+#endif
+    ALOGE("%s: Exiting status = 0x%x", fn, status);
+    return status;
+}
+
+
+#ifdef JCOP3_WR
+tJBL_STATUS Bufferize_load_cmds(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn[] = "Bufferize_load_cmds";
+    uint8_t Param_P2;
+    status = STATUS_FAILED;
+
+    if(cmd_count == 0x00)
+    {
+        if((pTranscv_Info->sSendData[1] == INSTAL_LOAD_ID) &&
+           (pTranscv_Info->sSendData[2] == PARAM_P1_OFFSET) &&
+           (pTranscv_Info->sSendData[3] == 0x00))
+        {
+            ALOGE("BUffer: install for load");
+            pBuffer[0] = pTranscv_Info->sSendlength;
+            memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
+            pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
+            cmd_count++;
+        }
+        else
+        {
+            /*
+             * Do not buffer this cmd
+             * Send this command to eSE
+             * */
+            status = STATUS_OK;
+        }
+
+    }
+    else
+    {
+        Param_P2 = cmd_count -1;
+        if((pTranscv_Info->sSendData[1] == LOAD_CMD_ID) &&
+           (pTranscv_Info->sSendData[2] == LOAD_MORE_BLOCKS) &&
+           (pTranscv_Info->sSendData[3] == Param_P2))
+        {
+            ALOGE("BUffer: load");
+            pBuffer[0] = pTranscv_Info->sSendlength;
+            memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
+            pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
+            cmd_count++;
+        }
+        else if((pTranscv_Info->sSendData[1] == LOAD_CMD_ID) &&
+                (pTranscv_Info->sSendData[2] == LOAD_LAST_BLOCK) &&
+                (pTranscv_Info->sSendData[3] == Param_P2))
+        {
+            ALOGE("BUffer: last load");
+            SendBack_cmds = true;
+            pBuffer[0] = pTranscv_Info->sSendlength;
+            memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
+            pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
+            cmd_count++;
+            islastcmdLoad = true;
+        }
+        else
+        {
+            ALOGE("BUffer: Not a load cmd");
+            SendBack_cmds = true;
+            pBuffer[0] = pTranscv_Info->sSendlength;
+            memcpy(&pBuffer[1], &(pTranscv_Info->sSendData[0]), pTranscv_Info->sSendlength);
+            pBuffer = pBuffer + pTranscv_Info->sSendlength + 1;
+            islastcmdLoad = false;
+            cmd_count++;
+        }
+    }
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    return status;
+}
+
+tJBL_STATUS Send_Backall_Loadcmds(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn [] = "Send_Backall_Loadcmds";
+    bool stat =false;
+    uint8_t xx=0;
+    status = STATUS_FAILED;
+    int32_t recvBufferActualSize=0, recv_len = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    ALOGD("%s: enter", fn);
+    pBuffer = Cmd_Buffer; // Points to start of first cmd to send
+    if(cmd_count == 0x00)
+    {
+        ALOGE("No cmds to stored to send to eSE");
+    }
+    else
+    {
+        while(cmd_count-- > 0)
+        {
+            pTranscv_Info->sSendlength = pBuffer[0];
+            memcpy(pTranscv_Info->sSendData, &pBuffer[1], pTranscv_Info->sSendlength);
+            pBuffer = pBuffer + 1 + pTranscv_Info->sSendlength;
+
+            stat = mchannel->transceive(pTranscv_Info->sSendData,
+                                        pTranscv_Info->sSendlength,
+                                        pTranscv_Info->sRecvData,
+                                        pTranscv_Info->sRecvlength,
+                                        recvBufferActualSize,
+                                        pTranscv_Info->timeout);
+
+            if(stat != true ||
+               (recvBufferActualSize < 2))
+            {
+                ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
+            }
+            else if(cmd_count == 0x00) //Last command in the buffer
+            {
+
+                if (islastcmdLoad == false)
+                {
+                    status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
+                }
+                else if((recvBufferActualSize == 0x02) &&
+                        (pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+                        (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
+                {
+                    recvBufferActualSize = 0x03;
+                    pTranscv_Info->sRecvData[0] = 0x00;
+                    pTranscv_Info->sRecvData[1] = 0x90;
+                    pTranscv_Info->sRecvData[2] = 0x00;
+                    status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
+                }
+                else
+                {
+                    status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
+                }
+            }
+            else if((recvBufferActualSize == 0x02) &&
+                    (pTranscv_Info->sRecvData[0] == 0x90) &&
+                    (pTranscv_Info->sRecvData[1] == 0x00))
+            {
+                /*Do not do anything
+                 * send next command in the buffer*/
+            }
+            else if((recvBufferActualSize == 0x03) &&
+                    (pTranscv_Info->sRecvData[0] == 0x00) &&
+                    (pTranscv_Info->sRecvData[1] == 0x90) &&
+                    (pTranscv_Info->sRecvData[2] == 0x00))
+            {
+                /*Do not do anything
+                 * Send next cmd in the buffer*/
+            }
+            else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] != 0x90) &&
+                    (pTranscv_Info->sRecvData[recvBufferActualSize-1] != 0x00))
+            {
+                /*Error condition hence exiting the loop*/
+                status = Process_EseResponse(pTranscv_Info, recvBufferActualSize, Os_info);
+                /*If the sending of Load fails reset the count*/
+                cmd_count=0;
+                break;
+            }
+        }
+    }
+    memset(Cmd_Buffer, 0, sizeof(Cmd_Buffer));
+    pBuffer = Cmd_Buffer; //point back to start of line
+    cmd_count = 0x00;
+    ALOGD("%s: exit: status=0x%x", fn, status);
+    return status;
+}
+#endif
+/*******************************************************************************
+**
+** Function:        Numof_lengthbytes
+**
+** Description:     Checks the number of length bytes and assigns
+**                  length value to wLen.
+**
+** Returns:         Number of Length bytes
+**
+*******************************************************************************/
+uint8_t Numof_lengthbytes(uint8_t *read_buf, int32_t *pLen)
+{
+    static const char fn[]= "Numof_lengthbytes";
+    uint8_t len_byte=0, i=0;
+    int32_t wLen = 0;
+    ALOGE("%s:enter", fn);
+
+    if(read_buf[i] == 0x00)
+    {
+        ALOGE("Invalid length zero");
+        len_byte = 0x00;
+    }
+    else if((read_buf[i] & 0x80) == 0x80)
+    {
+        len_byte = read_buf[i] & 0x0F;
+        len_byte = len_byte +1; //1 byte added for byte 0x81
+    }
+    else
+    {
+        len_byte = 0x01;
+    }
+    /*
+     * To get the length of the value field
+     * */
+    switch(len_byte)
+    {
+    case 0:
+        wLen = read_buf[0];
+        break;
+    case 1:
+        /*1st byte is the length*/
+        wLen = read_buf[0];
+        break;
+    case 2:
+        /*2nd byte is the length*/
+        wLen = read_buf[1];
+        break;
+    case 3:
+        /*1st and 2nd bytes are length*/
+        wLen = read_buf[1];
+        wLen = ((wLen << 8) | (read_buf[2]));
+        break;
+    case 4:
+        /*3bytes are the length*/
+        wLen = read_buf[1];
+        wLen = ((wLen << 16) | (read_buf[2] << 8));
+        wLen = (wLen | (read_buf[3]));
+        break;
+    default:
+        ALOGE("default case");
+        break;
+    }
+
+    *pLen = wLen;
+    ALOGE("%s:exit; len_bytes=0x0%x, Length=%ld", fn, len_byte, *pLen);
+    return len_byte;
+}
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+/*******************************************************************************
+**
+** Function:        Write_Response_To_OutFile
+**
+** Description:     Write the response to Out file
+**                  with length recvlen from buffer RecvData.
+**
+** Returns:         Success if OK
+**
+*******************************************************************************/
+tJBL_STATUS Write_Response_To_OutFile(Ala_ImageInfo_t *image_info, uint8_t* RecvData,
+    int32_t recvlen, Ls_TagType tType)
+{
+    int32_t respLen       = 0;
+    tJBL_STATUS wStatus = STATUS_FAILED;
+    static const char fn [] = "Write_Response_to_OutFile";
+    int32_t status = 0;
+    uint8_t tagBuffer[12] = {0x61,0,0,0,0,0,0,0,0,0,0,0};
+    int32_t tag44Len = 0;
+    int32_t tag61Len = 0;
+    uint8_t tag43Len = 1;
+    uint8_t tag43off = 0;
+    uint8_t tag44off = 0;
+    uint8_t ucTag44[3] = {0x00,0x00,0x00};
+    uint8_t tagLen = 0;
+    uint8_t tempLen = 0;
+    /*If the Response out file is NULL or Other than LS commands*/
+    if((image_info->bytes_wrote == 0x55)||(tType == LS_Default))
+    {
+        return STATUS_OK;
+    }
+    /*Certificate TAG occupies 2 bytes*/
+    if(tType == LS_Cert)
+    {
+        tag43Len = 2;
+    }
+    ALOGE("%s: Enter", fn);
+
+    /* |TAG | LEN(BERTLV)|                                VAL                         |
+     * | 61 |      XX    |  TAG | LEN |     VAL    | TAG | LEN(BERTLV) |      VAL     |
+     *                   |  43  | 1/2 | 7F21/60/40 | 44  | apduRespLen | apduResponse |
+     **/
+    if(recvlen < 0x80)
+    {
+        tag44Len = 1;
+        ucTag44[0] = recvlen;
+        tag61Len = recvlen + 4 + tag43Len;
+
+        if(tag61Len&0x80)
+        {
+            tagBuffer[1] = 0x81;
+            tagBuffer[2] = tag61Len;
+            tag43off = 3;
+            tag44off = 5+tag43Len;
+            tagLen = tag44off+2;
+        }
+        else
+        {
+            tagBuffer[1] = tag61Len;
+            tag43off = 2;
+            tag44off = 4+tag43Len;
+            tagLen = tag44off+2;
+        }
+    }
+    else if((recvlen >= 0x80)&&(recvlen <= 0xFF))
+    {
+        ucTag44[0] = 0x81;
+        ucTag44[1] = recvlen;
+        tag61Len = recvlen + 5 + tag43Len;
+        tag44Len = 2;
+
+        if((tag61Len&0xFF00) != 0)
+        {
+            tagBuffer[1] = 0x82;
+            tagBuffer[2] = (tag61Len & 0xFF00)>>8;
+            tagBuffer[3] = (tag61Len & 0xFF);
+            tag43off = 4;
+            tag44off = 6+tag43Len;
+            tagLen = tag44off+3;
+        }
+        else
+        {
+            tagBuffer[1] = 0x81;
+            tagBuffer[2] = (tag61Len & 0xFF);
+            tag43off = 3;
+            tag44off = 5+tag43Len;
+            tagLen = tag44off+3;
+        }
+    }
+    else if((recvlen > 0xFF) &&(recvlen <= 0xFFFF))
+    {
+        ucTag44[0] = 0x82;
+        ucTag44[1] = (recvlen&0xFF00)>>8;
+        ucTag44[2] = (recvlen&0xFF);
+        tag44Len = 3;
+
+        tag61Len = recvlen + 6 + tag43Len;
+
+        if((tag61Len&0xFF00) != 0)
+        {
+            tagBuffer[1] = 0x82;
+            tagBuffer[2] = (tag61Len & 0xFF00)>>8;
+            tagBuffer[3] = (tag61Len & 0xFF);
+            tag43off = 4;
+            tag44off = 6+tag43Len;
+            tagLen = tag44off+4;
+        }
+    }
+    tagBuffer[tag43off] = 0x43;
+    tagBuffer[tag43off+1] = tag43Len;
+    tagBuffer[tag44off] = 0x44;
+    memcpy(&tagBuffer[tag44off+1], &ucTag44[0],tag44Len);
+
+
+    if(tType == LS_Cert)
+    {
+        tagBuffer[tag43off+2] = 0x7F;
+        tagBuffer[tag43off+3] = 0x21;
+    }
+    else if(tType == LS_Sign)
+    {
+        tagBuffer[tag43off+2] = 0x60;
+    }
+    else if(tType == LS_Comm)
+    {
+        tagBuffer[tag43off+2] = 0x40;
+    }
+    else
+    {
+       /*Do nothing*/
+    }
+    while(tempLen < tagLen)
+    {
+        status = fprintf(image_info->fResp, "%02X", tagBuffer[tempLen++]);
+        if(status != 2)
+        {
+            ALOGE("%s: Invalid Response during fprintf; status=0x%lx", fn, (status));
+            wStatus = STATUS_FAILED;
+            break;
+        }
+    }
+    /*Updating the response data into out script*/
+    while(respLen < recvlen)
+    {
+        status = fprintf(image_info->fResp, "%02X", RecvData[respLen++]);
+        if(status != 2)
+        {
+            ALOGE("%s: Invalid Response during fprintf; status=0x%lx", fn, (status));
+            wStatus = STATUS_FAILED;
+            break;
+        }
+    }
+    if((status == 2))
+    {
+        fprintf(image_info->fResp, "%s\n", "");
+        ALOGE("%s: SUCCESS Response written to script out file; status=0x%lx", fn, (status));
+        wStatus = STATUS_OK;
+    }
+    fflush(image_info->fResp);
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function:        Check_Certificate_Tag
+**
+** Description:     Check certificate Tag presence in script
+**                  by 7F21 .
+**
+** Returns:         Success if Tag found
+**
+*******************************************************************************/
+tJBL_STATUS Check_Certificate_Tag(uint8_t *read_buf, uint16_t *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint16_t len_byte = 0;
+    int32_t wLen, recvBufferActualSize=0;
+    uint16_t offset = *offset1;
+
+    if(((read_buf[offset]<<8|read_buf[offset+1]) == TAG_CERTIFICATE))
+    {
+        ALOGD("TAGID: TAG_CERTIFICATE");
+        offset = offset+2;
+        len_byte = Numof_lengthbytes(&read_buf[offset], &wLen);
+        offset = offset + len_byte;
+        *offset1 = offset;
+        if(wLen <= MAX_CERT_LEN)
+        status = STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Check_SerialNo_Tag
+**
+** Description:     Check Serial number Tag presence in script
+**                  by 0x93 .
+**
+** Returns:         Success if Tag found
+**
+*******************************************************************************/
+tJBL_STATUS Check_SerialNo_Tag(uint8_t *read_buf, uint16_t *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint16_t offset = *offset1;
+    static const char fn[] = "Check_SerialNo_Tag";
+
+    if((read_buf[offset] == TAG_SERIAL_NO))
+    {
+        ALOGD("TAGID: TAG_SERIAL_NO");
+        uint8_t serNoLen = read_buf[offset+1];
+        offset = offset + serNoLen + 2;
+        *offset1 = offset;
+        ALOGD("%s: TAG_LSROOT_ENTITY is %x", fn, read_buf[offset]);
+        status = STATUS_OK;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Check_LSRootID_Tag
+**
+** Description:     Check LS root ID tag presence in script and compare with
+**                  select response root ID value.
+**
+** Returns:         Success if Tag found
+**
+*******************************************************************************/
+tJBL_STATUS Check_LSRootID_Tag(uint8_t *read_buf, uint16_t *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint16_t offset      = *offset1;
+
+    if(read_buf[offset] == TAG_LSRE_ID)
+    {
+        ALOGD("TAGID: TAG_LSROOT_ENTITY");
+        if(tag42Arr[0] == read_buf[offset+1])
+        {
+            uint8_t tag42Len = read_buf[offset+1];
+            offset = offset+2;
+            status = memcmp(&read_buf[offset],&tag42Arr[1],tag42Arr[0]);
+            ALOGD("ALA_Check_KeyIdentifier : TAG 42 verified");
+
+            if(status == STATUS_OK)
+            {
+                ALOGD("ALA_Check_KeyIdentifier : Loader service root entity "
+                "ID is matched");
+                offset = offset+tag42Len;
+                *offset1 = offset;
+                }
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Check_CertHoldID_Tag
+**
+** Description:     Check certificate holder ID tag presence in script.
+**
+** Returns:         Success if Tag found
+**
+*******************************************************************************/
+tJBL_STATUS Check_CertHoldID_Tag(uint8_t *read_buf, uint16_t *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint16_t offset      = *offset1;
+
+    if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_CERTFHOLD_ID)
+    {
+        uint8_t certfHoldIDLen = 0;
+        ALOGD("TAGID: TAG_CERTFHOLD_ID");
+        certfHoldIDLen = read_buf[offset+2];
+        offset = offset+certfHoldIDLen+3;
+        if(read_buf[offset] == TAG_KEY_USAGE)
+        {
+            uint8_t keyusgLen = 0;
+            ALOGD("TAGID: TAG_KEY_USAGE");
+            keyusgLen = read_buf[offset+1];
+            offset = offset+keyusgLen+2;
+            *offset1 = offset;
+            status = STATUS_OK;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Check_Date_Tag
+**
+** Description:     Check date tags presence in script.
+**
+** Returns:         Success if Tag found
+**
+*******************************************************************************/
+tJBL_STATUS Check_Date_Tag(uint8_t *read_buf, uint16_t *offset1)
+{
+    tJBL_STATUS status = STATUS_OK;
+    uint16_t offset      = *offset1;
+
+    if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EFF_DATE)
+    {
+        uint8_t effDateLen = read_buf[offset+2];
+        offset = offset+3+effDateLen;
+        ALOGD("TAGID: TAG_EFF_DATE");
+        if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EXP_DATE)
+        {
+            uint8_t effExpLen = read_buf[offset+2];
+            offset = offset+3+effExpLen;
+            ALOGD("TAGID: TAG_EXP_DATE");
+            status = STATUS_OK;
+        }else if(read_buf[offset] == TAG_LSRE_SIGNID)
+        {
+            status = STATUS_OK;
+        }
+    }
+    else if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EXP_DATE)
+    {
+        uint8_t effExpLen = read_buf[offset+2];
+        offset = offset+3+effExpLen;
+        ALOGD("TAGID: TAG_EXP_DATE");
+        status = STATUS_OK;
+    }else if(read_buf[offset] == TAG_LSRE_SIGNID)
+    {
+        status = STATUS_OK;
+    }
+    else
+    {
+    /*STATUS_FAILED*/
+    }
+    *offset1 = offset;
+    return status;
+}
+
+
+/*******************************************************************************
+**
+** Function:        Check_45_Tag
+**
+** Description:     Check 45 tags presence in script and compare the value
+**                  with select response tag 45 value
+**
+** Returns:         Success if Tag found
+**
+*******************************************************************************/
+tJBL_STATUS Check_45_Tag(uint8_t *read_buf, uint16_t *offset1, uint8_t *tag45Len)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint16_t offset      = *offset1;
+    if(read_buf[offset] == TAG_LSRE_SIGNID)
+    {
+        *tag45Len = read_buf[offset+1];
+        offset = offset+2;
+        if(tag45Arr[0] == *tag45Len)
+        {
+            status = memcmp(&read_buf[offset],&tag45Arr[1],tag45Arr[0]);
+            if(status == STATUS_OK)
+            {
+                ALOGD("ALA_Check_KeyIdentifier : TAG 45 verified");
+                *offset1 = offset;
+            }
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Certificate_Verification
+**
+** Description:     Perform the certificate verification by forwarding it to
+**                  LS applet.
+**
+** Returns:         Success if certificate is verified
+**
+*******************************************************************************/
+tJBL_STATUS Certificate_Verification(Ala_ImageInfo_t *Os_info,
+Ala_TranscieveInfo_t *pTranscv_Info, uint8_t *read_buf, uint16_t *offset1,
+uint8_t *tag45Len)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint16_t offset      = *offset1;
+    int32_t wCertfLen = (read_buf[2]<<8|read_buf[3]);
+    tJBL_STATUS certf_found = STATUS_FAILED;
+    static const char fn[] = "Certificate_Verification";
+    uint8_t tag_len_byte = Numof_lengthbytes(&read_buf[2], &wCertfLen);
+
+    pTranscv_Info->sSendData[0] = 0x80;
+    pTranscv_Info->sSendData[1] = 0xA0;
+    pTranscv_Info->sSendData[2] = 0x01;
+    pTranscv_Info->sSendData[3] = 0x00;
+    /*If the certificate is less than 255 bytes*/
+    if(wCertfLen <= 251)
+    {
+        uint8_t tag7f49Off = 0;
+        uint8_t u7f49Len = 0;
+        uint8_t tag5f37Len = 0;
+        ALOGD("Certificate is greater than 255");
+        offset = offset+*tag45Len;
+        ALOGD("%s: Before TAG_CCM_PERMISSION = %x",fn, read_buf[offset]);
+        if(read_buf[offset] == TAG_CCM_PERMISSION)
+        {
+            int32_t tag53Len = 0;
+            uint8_t len_byte = 0;
+            offset =offset+1;
+            len_byte = Numof_lengthbytes(&read_buf[offset], &tag53Len);
+            offset = offset+tag53Len+len_byte;
+            ALOGD("%s: Verified TAG TAG_CCM_PERMISSION = 0x53",fn);
+            if((uint16_t)(read_buf[offset]<<8|read_buf[offset+1]) == TAG_SIG_RNS_COMP)
+            {
+                tag7f49Off = offset;
+                u7f49Len   = read_buf[offset+2];
+                offset     = offset+3+u7f49Len;
+                if(u7f49Len != 64)
+                {
+                    return STATUS_FAILED;
+                }
+                if((uint16_t)(read_buf[offset]<<8|read_buf[offset+1]) == 0x7f49)
+                {
+                    tag5f37Len = read_buf[offset+2];
+                    if(read_buf[offset+3] != 0x86 || (read_buf[offset+4] != 65))
+                    {
+                        return STATUS_FAILED;
+                    }
+                }
+                else
+                {
+                    return STATUS_FAILED;
+                }
+             }
+             else
+             {
+                 return STATUS_FAILED;
+             }
+        }
+        else
+        {
+            return STATUS_FAILED;
+        }
+        pTranscv_Info->sSendData[4] = wCertfLen+2+tag_len_byte;
+        pTranscv_Info->sSendlength  = wCertfLen+7+tag_len_byte;
+        memcpy(&(pTranscv_Info->sSendData[5]), &read_buf[0], wCertfLen+2+tag_len_byte);
+
+        ALOGD("%s: start transceive for length %ld", fn, pTranscv_Info->
+            sSendlength);
+        status = ALA_SendtoAla(Os_info, status, pTranscv_Info,LS_Cert);
+        if(status != STATUS_OK)
+        {
+            return status;
+        }
+        else
+        {
+            certf_found = STATUS_OK;
+            ALOGD("Certificate is verified");
+            return status;
+        }
+    }
+    /*If the certificate is more than 255 bytes*/
+    else
+    {
+        uint8_t tag7f49Off = 0;
+        uint8_t u7f49Len = 0;
+        uint8_t tag5f37Len = 0;
+        ALOGD("Certificate is greater than 255");
+        offset = offset+*tag45Len;
+        ALOGD("%s: Before TAG_CCM_PERMISSION = %x",fn, read_buf[offset]);
+        if(read_buf[offset] == TAG_CCM_PERMISSION)
+        {
+            int32_t tag53Len = 0;
+            uint8_t len_byte = 0;
+            offset =offset+1;
+            len_byte = Numof_lengthbytes(&read_buf[offset], &tag53Len);
+            offset = offset+tag53Len+len_byte;
+            ALOGD("%s: Verified TAG TAG_CCM_PERMISSION = 0x53",fn);
+            if((uint16_t)(read_buf[offset]<<8|read_buf[offset+1]) == TAG_SIG_RNS_COMP)
+            {
+                tag7f49Off = offset;
+                u7f49Len   = read_buf[offset+2];
+                offset     = offset+3+u7f49Len;
+                if(u7f49Len != 64)
+                {
+                    return STATUS_FAILED;
+                }
+                if((uint16_t)(read_buf[offset]<<8|read_buf[offset+1]) == 0x7f49)
+                {
+                    tag5f37Len = read_buf[offset+2];
+                    if(read_buf[offset+3] != 0x86 || (read_buf[offset+4] != 65))
+                    {
+                        return STATUS_FAILED;
+                    }
+                }
+                else
+                {
+                    return STATUS_FAILED;
+                }
+                pTranscv_Info->sSendData[4] = tag7f49Off;
+                memcpy(&(pTranscv_Info->sSendData[5]), &read_buf[0], tag7f49Off);
+                pTranscv_Info->sSendlength = tag7f49Off+5;
+                ALOGD("%s: start transceive for length %ld", fn,
+                pTranscv_Info->sSendlength);
+
+                status = ALA_SendtoAla(Os_info, status, pTranscv_Info,LS_Default);
+                if(status != STATUS_OK)
+                {
+
+                    uint8_t* RecvData = pTranscv_Info->sRecvData;
+                    Write_Response_To_OutFile(Os_info, RecvData,
+                    resp_len, LS_Cert);
+                    return status;
+                }
+
+                pTranscv_Info->sSendData[2] = 0x00;
+                pTranscv_Info->sSendData[4] = u7f49Len+tag5f37Len+6;
+                memcpy(&(pTranscv_Info->sSendData[5]), &read_buf[tag7f49Off],
+                    u7f49Len+tag5f37Len+6);
+                pTranscv_Info->sSendlength = u7f49Len+tag5f37Len+11;
+                ALOGD("%s: start transceive for length %ld", fn,
+                    pTranscv_Info->sSendlength);
+
+                status = ALA_SendtoAla(Os_info, status, pTranscv_Info,LS_Cert);
+                if(status != STATUS_OK)
+                {
+                    return status;
+                }
+                else
+                {
+                    ALOGD("Certificate is verified");
+                    certf_found = STATUS_OK;
+                    return status;
+
+                }
+            }
+            else
+            {
+                return STATUS_FAILED;
+            }
+        }
+        else
+        {
+            return STATUS_FAILED;
+        }
+    }
+return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Check_Complete_7F21_Tag
+**
+** Description:     Traverses the 7F21 tag for verification of each sub tag with
+**                  in the 7F21 tag.
+**
+** Returns:         Success if all tags are verified
+**
+*******************************************************************************/
+tJBL_STATUS Check_Complete_7F21_Tag(Ala_ImageInfo_t *Os_info,
+       Ala_TranscieveInfo_t *pTranscv_Info, uint8_t *read_buf, uint16_t *offset)
+{
+    static const char fn[] = "Check_Complete_7F21_Tag";
+    uint8_t tag45Len = 0;
+
+    if(STATUS_OK == Check_Certificate_Tag(read_buf, offset))
+    {
+        if(STATUS_OK == Check_SerialNo_Tag(read_buf, offset))
+        {
+           if(STATUS_OK == Check_LSRootID_Tag(read_buf, offset))
+           {
+               if(STATUS_OK == Check_CertHoldID_Tag(read_buf, offset))
+               {
+                   if(STATUS_OK == Check_Date_Tag(read_buf, offset))
+                   {
+                       uint8_t tag45Len = 0;
+                       if(STATUS_OK == Check_45_Tag(read_buf, offset,
+                       &tag45Len))
+                       {
+                           if(STATUS_OK == Certificate_Verification(
+                           Os_info, pTranscv_Info, read_buf, offset,
+                           &tag45Len))
+                           {
+                               return STATUS_OK;
+                           }
+                       }else{
+                       ALOGE("%s: FAILED in Check_45_Tag", fn);}
+                   }else{
+                   ALOGE("%s: FAILED in Check_Date_Tag", fn);}
+               }else{
+               ALOGE("%s: FAILED in Check_CertHoldID_Tag", fn);}
+           }else{
+           ALOGE("%s: FAILED in Check_LSRootID_Tag", fn);}
+        }else{
+        ALOGE("%s: FAILED in Check_SerialNo_Tag", fn);}
+    }
+    else
+    {
+        ALOGE("%s: FAILED in Check_Certificate_Tag", fn);
+    }
+return STATUS_FAILED;
+}
+
+bool    ALA_UpdateExeStatus(uint16_t status)
+{
+    fLS_STATUS = fopen(LS_STATUS_PATH, "w+");
+    ALOGD("enter: ALA_UpdateExeStatus");
+    if(fLS_STATUS == NULL)
+    {
+        ALOGE("Error opening LS Status file for backup: %s",strerror(errno));
+        return false;
+    }
+    if((fprintf(fLS_STATUS, "%04x",status)) != 4)
+    {
+        ALOGE("Error updating LS Status backup: %s",strerror(errno));
+        fclose(fLS_STATUS);
+        return false;
+    }
+    ALOGD("exit: ALA_UpdateExeStatus");
+    fclose(fLS_STATUS);
+    return true;
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_getAppletLsStatus
+**
+** Description:     Interface to fetch Loader service Applet status to JNI, Services
+**
+** Returns:         SUCCESS/FAILURE
+**
+*******************************************************************************/
+tJBL_STATUS ALA_getAppletLsStatus(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn[] = "ALA_getAppletLsStatus";
+    bool stat = false;
+    int32_t recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+
+    ALOGD("%s: enter", fn);
+
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+    }
+    else
+    {
+        pTranscv_Info->sSendData[0] = STORE_DATA_CLA | Os_info->Channel_Info[0].channel_id;
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (int32_t)sizeof(GetData);
+        pTranscv_Info->sRecvlength = 1024;//(int32_t)sizeof(int32_t);
+
+
+        memcpy(&(pTranscv_Info->sSendData[1]), &GetData[1],
+                ((sizeof(GetData))-1));
+        ALOGD("%s: Calling Secure Element Transceive with GET DATA apdu", fn);
+
+        stat = mchannel->transceive (pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+        if((stat != true) &&
+           (recvBufferActualSize == 0x00))
+        {
+            status = STATUS_FAILED;
+            ALOGE("%s: SE transceive failed status = 0x%X", fn, status);
+        }
+        else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
+        {
+            ALOGE("STORE CMD is successful");
+            if((pTranscv_Info->sRecvData[0] == 0x46 )&& (pTranscv_Info->sRecvData[1] == 0x01 ))
+            {
+               if((pTranscv_Info->sRecvData[2] == 0x01))
+               {
+                   lsGetStatusArr[0]=0x63;lsGetStatusArr[1]=0x40;
+                   ALOGE("%s: Script execution status FAILED", fn);
+               }
+               else if((pTranscv_Info->sRecvData[2] == 0x00))
+               {
+                   lsGetStatusArr[0]=0x90;lsGetStatusArr[1]=0x00;
+                   ALOGE("%s: Script execution status SUCCESS", fn);
+               }
+               else
+               {
+                   lsGetStatusArr[0]=0x90;lsGetStatusArr[1]=0x00;
+                   ALOGE("%s: Script execution status UNKNOWN", fn);
+               }
+            }
+            else
+            {
+                lsGetStatusArr[0]=0x90;lsGetStatusArr[1]=0x00;
+                ALOGE("%s: Script execution status UNKNOWN", fn);
+            }
+            status = STATUS_SUCCESS;
+        }
+        else
+        {
+            status = STATUS_FAILED;
+        }
+
+    ALOGE("%s: exit; status=0x%x", fn, status);
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        Get_LsStatus
+**
+** Description:     Interface to fetch Loader service client status to JNI, Services
+**
+** Returns:         SUCCESS/FAILURE
+**
+*******************************************************************************/
+tJBL_STATUS Get_LsStatus(uint8_t *pStatus)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    uint8_t lsStatus[2]    = {0x63,0x40};
+    uint8_t loopcnt = 0;
+    fLS_STATUS = fopen(LS_STATUS_PATH, "r");
+    if(fLS_STATUS == NULL)
+    {
+        ALOGE("Error opening LS Status file for backup: %s",strerror(errno));
+        return status;
+    }
+    for(loopcnt=0;loopcnt<2;loopcnt++)
+    {
+        if((FSCANF_BYTE(fLS_STATUS, "%2x", &lsStatus[loopcnt])) == 0)
+        {
+            ALOGE("Error updating LS Status backup: %s",strerror(errno));
+            fclose(fLS_STATUS);
+            return status;
+        }
+    }
+    ALOGD("enter: ALA_getLsStatus 0x%X 0x%X",lsStatus[0],lsStatus[1] );
+    memcpy(pStatus, lsStatus, 2);
+    fclose(fLS_STATUS);
+    return STATUS_OK;
+}
+
+
+#endif
diff --git a/p61-jcop-kit/src/AlaLib.cpp b/p61-jcop-kit/src/AlaLib.cpp
new file mode 100644
index 0000000..9dba416
--- /dev/null
+++ b/p61-jcop-kit/src/AlaLib.cpp
@@ -0,0 +1,314 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 "Ala.h"
+#include "AlaLib.h"
+#include <data_types.h>
+#include <cutils/log.h>
+#include <dirent.h>
+
+static int16_t alaHandle;
+extern pAla_Dwnld_Context_t gpAla_Dwnld_Context;
+/*static bool Ala_inUse = false;*/
+/*******************************************************************************
+**
+** Function:        JCDNLD_Init
+**
+** Description:     Initializes the JCOP library and opens the DWP communication channel
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_Init(IChannel_t *channel)
+{
+    static const char fn[] = "ALA_Init";
+    bool    stat = false;
+    alaHandle  = EE_ERROR_OPEN_FAIL;
+    ALOGD("%s: enter", fn);
+
+/*    if (Ala_inUse == true)
+    {
+        return STATUS_INUSE;
+    }*/
+    if(channel == NULL)
+    {
+        return STATUS_FAILED;
+    }
+    /*TODO: inUse assignment should be with protection like using semaphore*/
+    /*Ala_inUse = true;*/
+    stat = initialize (channel);
+    if(stat != true)
+    {
+        ALOGE("%s: failed", fn);
+    }
+    else
+    {
+        channel = gpAla_Dwnld_Context->mchannel;
+        if((channel != NULL) &&
+           (channel->open) != NULL)
+        {
+            alaHandle = channel->open();
+            if(alaHandle == EE_ERROR_OPEN_FAIL)
+            {
+                ALOGE("%s:Open DWP communication is failed", fn);
+                stat = false;
+            }
+            else
+            {
+                ALOGE("%s:Open DWP communication is success", fn);
+                stat = true;
+            }
+        }
+        else
+        {
+            ALOGE("%s: NULL DWP channel", fn);
+            stat = false;
+        }
+    }
+    return (stat == true)?STATUS_OK:STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_Start
+**
+** Description:     Starts the ALA update over DWP
+**
+** Returns:         SUCCESS if ok.
+**
+*******************************************************************************/
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+tJBL_STATUS ALA_Start(const char *name, const char *dest, uint8_t *pdata, uint16_t len, uint8_t *respSW)
+#else
+tJBL_STATUS ALA_Start(const char *name, uint8_t *pdata, uint16_t len)
+#endif
+{
+    static const char fn[] = "ALA_Start";
+    tJBL_STATUS status = STATUS_FAILED;
+    IChannel_t *channel = gpAla_Dwnld_Context->mchannel;
+    if(name != NULL)
+    {
+        ALOGE("%s: name is %s", fn, name);
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+        ALOGE("%s: Dest is %s", fn, dest);
+        status = Perform_ALA(name, dest, pdata, len, respSW);
+#else
+        status = Perform_ALA(name, pdata, len);
+#endif
+    }
+    else
+    {
+        ALOGE("Invalid parameter");
+    }
+    ALOGE("%s: Exit; status=0x0%X", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_DeInit
+**
+** Description:     Deinitializes the ALA module
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+bool ALA_DeInit()
+{
+    static const char fn[] = "ALA_DeInit";
+    bool    stat = false;
+    IChannel_t* channel = gpAla_Dwnld_Context->mchannel;
+    ALOGD("%s: enter", fn);
+    if(channel != NULL)
+    {
+        if(channel->doeSE_Reset != NULL)
+        {
+            //channel->doeSE_Reset();
+            if(channel->close != NULL)
+            {
+                stat = channel->close(alaHandle);
+                if(stat != true)
+                {
+                    ALOGE("%s:closing DWP channel is failed", fn);
+                }
+            }
+            else
+            {
+                ALOGE("%s: NULL fp DWP_close", fn);
+                stat = false;
+            }
+        }
+    }
+    else
+    {
+        ALOGE("%s: NULL dwp channel", fn);
+    }
+    finalize();
+    /*TODO: inUse assignment should be with protection like using semaphore*/
+    /*Ala_inUse = false;*/
+    return stat;
+}
+#if(NXP_LDR_SVC_VER_2 != TRUE)
+/*******************************************************************************
+**
+** Function:        ALA_GetlistofApplets
+**
+** Description:     Gets the list of applets present the pre-defined directory
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+void ALA_GetlistofApplets(char *list[], uint8_t* num)
+{
+  static const char dir[] = "/data/ala/";
+  struct dirent *dp;
+  uint8_t xx =0;
+  DIR *fd;
+
+  if ((fd = opendir(dir)) == NULL)
+  {
+    fprintf(stderr, "listdir: can't open %s\n", dir);
+    return;
+  }
+  while ((dp = readdir(fd)) != NULL)
+  {
+      if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
+       continue;    /* skip self and parent */
+
+      ALOGE("%s/%s\n", dir, dp->d_name);
+      list[xx] = (char *)malloc(strlen(dp->d_name)+1);
+      if(list[xx] != NULL)
+      {
+          memset((void *)list[xx],0, strlen(dp->d_name)+1);
+          memcpy(list[xx++], dp->d_name, strlen(dp->d_name)+1);
+      }
+      else
+      {
+          ALOGE("Memory allocation failed");
+      }
+
+  }
+  *num = xx;
+  ALOGD("%s: number of applets found=0x0%x", __func__, *num);
+  closedir(fd);
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_GetCertificateKey
+**
+** Description:     Get the JSBL reference key
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_GetCertificateKey(uint8_t *pKey, int32_t *pKeylen)
+{
+    static const char fn[] = "ALA_GetCertificateKey";
+    tJBL_STATUS status = STATUS_FAILED;
+    IChannel_t *channel = gpAla_Dwnld_Context->mchannel;
+    if(pKey != NULL)
+    {
+        status = GetJsbl_Certificate_Refkey(pKey, pKeylen);
+    }
+    else
+    {
+        ALOGE("Invalid parameter");
+    }
+    ALOGE("%s: Exit; status=0x0%X", fn, status);
+    return status;
+}
+#else
+
+/*******************************************************************************
+**
+** Function:        ALA_lsGetVersion
+**
+** Description:     Get the version of Loder service client and applet
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_lsGetVersion(uint8_t *pVersion)
+{
+    static const char fn[] = "ALA_lsGetVersion";
+    tJBL_STATUS status = STATUS_FAILED;
+    IChannel_t *channel = gpAla_Dwnld_Context->mchannel;
+    if(pVersion!= NULL)
+    {
+        status = GetLs_Version(pVersion);
+        ALOGE("%s: LS Lib lsGetVersion status =0x0%X%X", fn, *pVersion, *(pVersion+1));
+    }
+    else
+    {
+        ALOGE("Invalid parameter");
+    }
+    ALOGE("%s: Exit; status=0x0%X", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_lsGetStatus
+**
+** Description:     Get the version of Loder service client and applet
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_lsGetStatus(uint8_t *pVersion)
+{
+    static const char fn[] = "ALA_lsGetStatus";
+    tJBL_STATUS status = STATUS_FAILED;
+    IChannel_t *channel = gpAla_Dwnld_Context->mchannel;
+    if(pVersion!= NULL)
+    {
+        status = Get_LsStatus(pVersion);
+        ALOGE("%s: lsGetStatus ALALIB status=0x0%X 0x0%X", fn, pVersion[0], pVersion[1]);
+    }
+    else
+    {
+        ALOGE("Invalid parameter");
+    }
+    ALOGE("%s: Exit; status=0x0%X", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        ALA_lsGetAppletStatus
+**
+** Description:     Get the version of Loder service client and applet
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_lsGetAppletStatus(uint8_t *pVersion)
+{
+    static const char fn[] = "ALA_lsGetStatus";
+    tJBL_STATUS status = STATUS_FAILED;
+    IChannel_t *channel = gpAla_Dwnld_Context->mchannel;
+    if(pVersion!= NULL)
+    {
+        status = Get_LsAppletStatus(pVersion);
+        ALOGE("%s: lsGetStatus ALALIB status=0x0%X 0x0%X", fn, pVersion[0], pVersion[1]);
+    }
+    else
+    {
+        ALOGE("Invalid parameter");
+    }
+    ALOGE("%s: Exit; status=0x0%X", fn, status);
+    return status;
+}
+
+#endif
diff --git a/p61-jcop-kit/src/JcDnld.cpp b/p61-jcop-kit/src/JcDnld.cpp
new file mode 100644
index 0000000..e73a0ac
--- /dev/null
+++ b/p61-jcop-kit/src/JcDnld.cpp
@@ -0,0 +1,166 @@
+ /*
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 "JcDnld.h"
+#include "JcopOsDownload.h"
+#include <data_types.h>
+#include <cutils/log.h>
+
+JcopOsDwnld *jd;
+IChannel_t *channel;
+static bool inUse = false;
+static int16_t jcHandle;
+extern pJcopOs_Dwnld_Context_t gpJcopOs_Dwnld_Context;
+/*******************************************************************************
+**
+** Function:        JCDNLD_Init
+**
+** Description:     Initializes the JCOP library and opens the DWP communication channel
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JCDNLD_Init(IChannel_t *channel)
+{
+    static const char fn[] = "JCDNLD_Init";
+    bool    stat = false;
+    jcHandle = EE_ERROR_OPEN_FAIL;
+    ALOGD("%s: enter", fn);
+
+    if (inUse == true)
+    {
+        return STATUS_INUSE;
+    }
+    else if(channel == NULL)
+    {
+        return STATUS_FAILED;
+    }
+    /*TODO: inUse assignment should be with protection like using semaphore*/
+    inUse = true;
+    jd = JcopOsDwnld::getInstance();
+    stat = jd->initialize (channel);
+    if(stat != true)
+    {
+        ALOGE("%s: failed", fn);
+    }
+    else
+    {
+        if((channel != NULL) &&
+           (channel->open) != NULL)
+        {
+            jcHandle = channel->open();
+            if(jcHandle == EE_ERROR_OPEN_FAIL)
+            {
+                ALOGE("%s:Open DWP communication is failed", fn);
+                stat = false;
+            }
+            else
+            {
+                ALOGE("%s:Open DWP communication is success", fn);
+                stat = true;
+            }
+        }
+        else
+        {
+            ALOGE("%s: NULL DWP channel", fn);
+            stat = false;
+        }
+    }
+    return (stat == true)?STATUS_OK:STATUS_FAILED;
+}
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_StartDownload
+**
+** Description:     Starts the JCOP update
+**
+** Returns:         SUCCESS if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JCDNLD_StartDownload()
+{
+    static const char fn[] = "JCDNLD_StartDownload";
+    tJBL_STATUS status = STATUS_FAILED;
+    bool    stat = false;
+
+    status = jd->JcopOs_Download();
+    ALOGE("%s: Exit; status=0x0%X", fn, status);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_DeInit
+**
+** Description:     Deinitializes the JCOP Lib
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+bool JCDNLD_DeInit()
+{
+    static const char fn[] = "JCDNLD_DeInit";
+    bool    stat = false;
+    ALOGD("%s: enter", fn);
+
+    if(gpJcopOs_Dwnld_Context != NULL)
+    {
+        channel = gpJcopOs_Dwnld_Context->channel;
+        if((channel != NULL) && (channel->doeSE_JcopDownLoadReset != NULL))
+        {
+            channel->doeSE_JcopDownLoadReset();
+            if(channel->close != NULL)
+            {
+                stat = channel->close(jcHandle);
+                if(stat != true)
+                {
+                    ALOGE("%s:closing DWP channel is failed", fn);
+                }
+            }
+            else
+            {
+                ALOGE("%s: NULL fp DWP_close", fn);
+                stat = false;
+            }
+        }
+    }
+    else
+    {
+        ALOGE("%s: NULL dwnld context", fn);
+    }
+    jd->finalize();
+    /*TODO: inUse assignment should be with protection like using semaphore*/
+    inUse = false;
+    return stat;
+}
+
+/*******************************************************************************
+**
+** Function:        JCDNLD_CheckVersion
+**
+** Description:     Check the existing JCOP OS version
+**
+** Returns:         true if ok.
+**
+*******************************************************************************/
+bool JCDNLD_CheckVersion()
+{
+
+    /**
+     * Need to implement in case required
+     * */
+    return true;
+}
diff --git a/p61-jcop-kit/src/JcopOsDownload.cpp b/p61-jcop-kit/src/JcopOsDownload.cpp
new file mode 100644
index 0000000..645c22b
--- /dev/null
+++ b/p61-jcop-kit/src/JcopOsDownload.cpp
@@ -0,0 +1,703 @@
+ /*
+  * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+  * Not a Contribution.
+  *
+  * Copyright (C) 2015 NXP Semiconductors
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  *      http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT 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 <cutils/log.h>
+#include <semaphore.h>
+#include <AlaLib.h>
+#include <JcopOsDownload.h>
+#include <IChannel.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+JcopOsDwnld JcopOsDwnld::sJcopDwnld;
+int32_t gTransceiveTimeout = 120000;
+
+tJBL_STATUS (JcopOsDwnld::*JcopOs_dwnld_seqhandler[])(
+            JcopOs_ImageInfo_t* pContext, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pInfo)={
+       &JcopOsDwnld::TriggerApdu,
+       &JcopOsDwnld::GetInfo,
+       &JcopOsDwnld::load_JcopOS_image,
+       &JcopOsDwnld::GetInfo,
+       &JcopOsDwnld::load_JcopOS_image,
+       &JcopOsDwnld::GetInfo,
+       &JcopOsDwnld::load_JcopOS_image,
+       NULL
+   };
+
+pJcopOs_Dwnld_Context_t gpJcopOs_Dwnld_Context = NULL;
+static const char *path[3] = {"/data/vendor/nfc/JcopOs_Update1.apdu",
+                             "/data/vendor/nfc/JcopOs_Update2.apdu",
+                             "/data/vendor/nfc/JcopOs_Update3.apdu"};
+
+/*******************************************************************************
+**
+** Function:        getInstance
+**
+** Description:     Get the JcopOsDwnld singleton object.
+**
+** Returns:         JcopOsDwnld object.
+**
+*******************************************************************************/
+JcopOsDwnld* JcopOsDwnld::getInstance()
+{
+    JcopOsDwnld *jd = new JcopOsDwnld();
+    return jd;
+}
+
+/*******************************************************************************
+**
+** Function:        getJcopOsFileInfo
+**
+** Description:     Verify all the updater files required for download
+**                  are present or not
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool JcopOsDwnld::getJcopOsFileInfo()
+{
+    static const char fn [] = "JcopOsDwnld::getJcopOsFileInfo";
+    bool status = true;
+    struct stat st;
+
+    for (int num = 0; num < 3; num++)
+    {
+        if (stat(path[num], &st))
+        {
+            status = false;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        initialize
+**
+** Description:     Initialize all member variables.
+**                  native: Native data.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool JcopOsDwnld::initialize (IChannel_t *channel)
+{
+    static const char fn [] = "JcopOsDwnld::initialize";
+
+    ALOGD ("%s: enter", fn);
+
+    if (!getJcopOsFileInfo())
+    {
+        ALOGD("%s: insufficient resources, file not present", fn);
+        return (false);
+    }
+    gpJcopOs_Dwnld_Context = (pJcopOs_Dwnld_Context_t)malloc(sizeof(JcopOs_Dwnld_Context_t));
+    if(gpJcopOs_Dwnld_Context != NULL)
+    {
+        memset((void *)gpJcopOs_Dwnld_Context, 0, (uint32_t)sizeof(JcopOs_Dwnld_Context_t));
+        gpJcopOs_Dwnld_Context->channel = (IChannel_t*)malloc(sizeof(IChannel_t));
+        if(gpJcopOs_Dwnld_Context->channel != NULL)
+        {
+            memset(gpJcopOs_Dwnld_Context->channel, 0, sizeof(IChannel_t));
+        }
+        else
+        {
+            ALOGD("%s: Memory allocation for IChannel is failed", fn);
+            return (false);
+        }
+        gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData = (uint8_t*)malloc(sizeof(uint8_t)*JCOP_MAX_BUF_SIZE);
+        if(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData != NULL)
+        {
+            memset(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData, 0, JCOP_MAX_BUF_SIZE);
+        }
+        else
+        {
+            ALOGD("%s: Memory allocation for SendBuf is failed", fn);
+            return (false);
+        }
+    }
+    else
+    {
+        ALOGD("%s: Memory allocation failed", fn);
+        return (false);
+    }
+    mIsInit = true;
+    memcpy(gpJcopOs_Dwnld_Context->channel, channel, sizeof(IChannel_t));
+    ALOGD ("%s: exit", fn);
+    return (true);
+}
+/*******************************************************************************
+**
+** Function:        finalize
+**
+** Description:     Release all resources.
+**
+** Returns:         None
+**
+*******************************************************************************/
+void JcopOsDwnld::finalize ()
+{
+    static const char fn [] = "JcopOsDwnld::finalize";
+    ALOGD ("%s: enter", fn);
+    mIsInit       = false;
+    if(gpJcopOs_Dwnld_Context != NULL)
+    {
+        if(gpJcopOs_Dwnld_Context->channel != NULL)
+        {
+            free(gpJcopOs_Dwnld_Context->channel);
+            gpJcopOs_Dwnld_Context->channel = NULL;
+        }
+        if(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData != NULL)
+        {
+            free(gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData);
+            gpJcopOs_Dwnld_Context->pJcopOs_TransInfo.sSendData = NULL;
+        }
+        free(gpJcopOs_Dwnld_Context);
+        gpJcopOs_Dwnld_Context = NULL;
+    }
+    ALOGD ("%s: exit", fn);
+}
+
+/*******************************************************************************
+**
+** Function:        JcopOs_Download
+**
+** Description:     Starts the OS download sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::JcopOs_Download()
+{
+    static const char fn [] = "JcopOsDwnld::JcopOs_Download";
+    tJBL_STATUS wstatus = STATUS_FAILED;
+    JcopOs_TranscieveInfo_t pTranscv_Info;
+    JcopOs_ImageInfo_t ImageInfo;
+    uint8_t retry_cnt = 0x00;
+    ALOGD("%s: enter:", fn);
+    if(mIsInit == false)
+    {
+        ALOGD ("%s: JcopOs Dwnld is not initialized", fn);
+        wstatus = STATUS_FAILED;
+    }
+    else
+    {
+        do
+        {
+            wstatus = JcopOsDwnld::JcopOs_update_seq_handler();
+            if(wstatus == STATUS_FAILED)
+                retry_cnt++;
+            else
+                break;
+        }while(retry_cnt < JCOP_MAX_RETRY_CNT);
+    }
+    ALOGD("%s: exit; status = 0x%x", fn, wstatus);
+    return wstatus;
+}
+/*******************************************************************************
+**
+** Function:        JcopOs_update_seq_handler
+**
+** Description:     Performs the JcopOS download sequence
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::JcopOs_update_seq_handler()
+{
+    static const char fn[] = "JcopOsDwnld::JcopOs_update_seq_handler";
+    uint8_t seq_counter = 0;
+    JcopOs_ImageInfo_t update_info = (JcopOs_ImageInfo_t )gpJcopOs_Dwnld_Context->Image_info;
+    JcopOs_TranscieveInfo_t trans_info = (JcopOs_TranscieveInfo_t )gpJcopOs_Dwnld_Context->pJcopOs_TransInfo;
+    update_info.index = 0x00;
+    update_info.cur_state = 0x00;
+    tJBL_STATUS status = STATUS_FAILED;
+
+    ALOGD("%s: enter", fn);
+    status = GetJcopOsState(&update_info, &seq_counter);
+    if(status != STATUS_SUCCESS)
+    {
+        ALOGE("Error in getting JcopOsState info");
+    }
+    else
+    {
+        ALOGE("seq_counter %d", seq_counter);
+        while((JcopOs_dwnld_seqhandler[seq_counter]) != NULL )
+        {
+            status = STATUS_FAILED;
+            status = (*this.*(JcopOs_dwnld_seqhandler[seq_counter]))(&update_info, status, &trans_info );
+            if(STATUS_SUCCESS != status)
+            {
+                ALOGE("%s: exiting; status=0x0%X", fn, status);
+                break;
+            }
+            seq_counter++;
+        }
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        TriggerApdu
+**
+** Description:     Switch to updater OS
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::TriggerApdu(JcopOs_ImageInfo_t* pVersionInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info)
+{
+    static const char fn [] = "JcopOsDwnld::TriggerApdu";
+    bool stat = false;
+    IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
+    int32_t recvBufferActualSize = 0;
+
+    ALOGD("%s: enter;", fn);
+
+    if(pTranscv_Info == NULL ||
+       pVersionInfo == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (int32_t)sizeof(Trigger_APDU);
+        pTranscv_Info->sRecvlength = 1024;//(int32_t)sizeof(int32_t);
+        memcpy(pTranscv_Info->sSendData, Trigger_APDU, pTranscv_Info->sSendlength);
+
+        ALOGD("%s: Calling Secure Element Transceive", fn);
+        stat = mchannel->transceive (pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+        if (stat != true)
+        {
+            status = STATUS_FAILED;
+            ALOGE("%s: SE transceive failed status = 0x%X", fn, status);//Stop JcopOs Update
+        }
+        else if(((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x68) &&
+               (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x81))||
+               ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+               (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))||
+               ((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6F) &&
+               (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)))
+        {
+            mchannel->doeSE_JcopDownLoadReset();
+            status = STATUS_OK;
+            ALOGD("%s: Trigger APDU Transceive status = 0x%X", fn, status);
+        }
+        else
+        {
+            /* status {90, 00} */
+            status = STATUS_OK;
+        }
+    }
+    ALOGD("%s: exit; status = 0x%X", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        GetInfo
+**
+** Description:     Get the JCOP OS info
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::GetInfo(JcopOs_ImageInfo_t* pImageInfo, tJBL_STATUS status, JcopOs_TranscieveInfo_t* pTranscv_Info)
+{
+    static const char fn [] = "JcopOsDwnld::GetInfo";
+
+    bool stat = false;
+    IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
+    int32_t recvBufferActualSize = 0;
+
+    ALOGD("%s: enter;", fn);
+
+    if(pTranscv_Info == NULL ||
+       pImageInfo == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        memcpy(pImageInfo->fls_path, (char *)path[pImageInfo->index], strlen(path[pImageInfo->index]));
+
+        memset(pTranscv_Info->sSendData, 0, JCOP_MAX_BUF_SIZE);
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (uint32_t)sizeof(GetInfo_APDU);
+        pTranscv_Info->sRecvlength = 1024;
+        memcpy(pTranscv_Info->sSendData, GetInfo_APDU, pTranscv_Info->sSendlength);
+
+        ALOGD("%s: Calling Secure Element Transceive", fn);
+        stat = mchannel->transceive (pTranscv_Info->sSendData,
+                                pTranscv_Info->sSendlength,
+                                pTranscv_Info->sRecvData,
+                                pTranscv_Info->sRecvlength,
+                                recvBufferActualSize,
+                                pTranscv_Info->timeout);
+        if (stat != true)
+        {
+            status = STATUS_FAILED;
+            pImageInfo->index =0;
+            ALOGE("%s: SE transceive failed status = 0x%X", fn, status);//Stop JcopOs Update
+        }
+        else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90) &&
+                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00))
+        {
+            pImageInfo->version_info.osid = pTranscv_Info->sRecvData[recvBufferActualSize-6];
+            pImageInfo->version_info.ver1 = pTranscv_Info->sRecvData[recvBufferActualSize-5];
+            pImageInfo->version_info.ver0 = pTranscv_Info->sRecvData[recvBufferActualSize-4];
+            pImageInfo->version_info.OtherValid = pTranscv_Info->sRecvData[recvBufferActualSize-3];
+#if 0
+            if((pImageInfo->index != 0) &&
+               (pImageInfo->version_info.osid == 0x01) &&
+               (pImageInfo->version_info.OtherValid == 0x11))
+            {
+                ALOGE("3-Step update is not required");
+                memset(pImageInfo->fls_path,0,sizeof(pImageInfo->fls_path));
+                pImageInfo->index=0;
+            }
+            else
+#endif
+            {
+                ALOGE("Starting 3-Step update");
+                memcpy(pImageInfo->fls_path, path[pImageInfo->index], strlen(path[pImageInfo->index]));
+                pImageInfo->index++;
+            }
+            status = STATUS_OK;
+            ALOGD("%s: GetInfo Transceive status = 0x%X", fn, status);
+        }
+        else if((pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6A) &&
+                (pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x82) &&
+                 pImageInfo->version_info.ver_status == STATUS_UPTO_DATE)
+        {
+            status = STATUS_UPTO_DATE;
+        }
+        else
+        {
+            status = STATUS_FAILED;
+            ALOGD("%s; Invalid response for GetInfo", fn);
+        }
+    }
+
+    if (status == STATUS_FAILED)
+    {
+        ALOGD("%s; status failed, doing reset...", fn);
+        mchannel->doeSE_JcopDownLoadReset();
+    }
+    ALOGD("%s: exit; status = 0x%X", fn, status);
+    return status;
+}
+/*******************************************************************************
+**
+** Function:        load_JcopOS_image
+**
+** Description:     Used to update the JCOP OS
+**                  Get Info function has to be called before this
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::load_JcopOS_image(JcopOs_ImageInfo_t *Os_info, tJBL_STATUS status, JcopOs_TranscieveInfo_t *pTranscv_Info)
+{
+    static const char fn [] = "JcopOsDwnld::load_JcopOS_image";
+    bool stat = false;
+    int wResult, size =0;
+    int32_t wIndex,wCount=0;
+    int32_t wLen;
+
+    IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
+    int32_t recvBufferActualSize = 0;
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGE("%s: invalid parameter", fn);
+        return status;
+    }
+    Os_info->fp = fopen(Os_info->fls_path, "r+");
+
+    if (Os_info->fp == NULL) {
+        ALOGE("Error opening OS image file <%s> for reading: %s",
+                    Os_info->fls_path, strerror(errno));
+        return STATUS_FILE_NOT_FOUND;
+    }
+    wResult = fseek(Os_info->fp, 0L, SEEK_END);
+    if (wResult) {
+        ALOGE("Error seeking end OS image file %s", strerror(errno));
+        goto exit;
+    }
+    Os_info->fls_size = ftell(Os_info->fp);
+    if (Os_info->fls_size < 0) {
+        ALOGE("Error ftelling file %s", strerror(errno));
+        goto exit;
+    }
+    wResult = fseek(Os_info->fp, 0L, SEEK_SET);
+    if (wResult) {
+        ALOGE("Error seeking start image file %s", strerror(errno));
+        goto exit;
+    }
+    while(!feof(Os_info->fp))
+    {
+        ALOGE("%s; Start of line processing", fn);
+
+        wIndex=0;
+        wLen=0;
+        wCount=0;
+        memset(pTranscv_Info->sSendData,0x00,JCOP_MAX_BUF_SIZE);
+        pTranscv_Info->sSendlength=0;
+
+        ALOGE("%s; wIndex = 0", fn);
+        for(wCount =0; (wCount < 5 && !feof(Os_info->fp)); wCount++, wIndex++)
+        {
+            wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex]);
+        }
+        if(wResult != 0)
+        {
+            wLen = pTranscv_Info->sSendData[4];
+            ALOGE("%s; Read 5byes success & len=%d", fn,wLen);
+            if(wLen == 0x00)
+            {
+                ALOGE("%s: Extended APDU", fn);
+                wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex++]);
+                wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex++]);
+                wLen = ((pTranscv_Info->sSendData[5] << 8) | (pTranscv_Info->sSendData[6]));
+            }
+            for(wCount =0; (wCount < wLen && !feof(Os_info->fp)); wCount++, wIndex++)
+            {
+                wResult = FSCANF_BYTE(Os_info->fp,"%2X",&pTranscv_Info->sSendData[wIndex]);
+            }
+        }
+        else
+        {
+            ALOGE("%s: JcopOs image Read failed", fn);
+            goto exit;
+        }
+
+        pTranscv_Info->sSendlength = wIndex;
+        ALOGE("%s: start transceive for length %d", fn, pTranscv_Info->sSendlength);
+        if((pTranscv_Info->sSendlength != 0x03) &&
+           (pTranscv_Info->sSendData[0] != 0x00) &&
+           (pTranscv_Info->sSendData[1] != 0x00))
+        {
+
+            stat = mchannel->transceive(pTranscv_Info->sSendData,
+                                    pTranscv_Info->sSendlength,
+                                    pTranscv_Info->sRecvData,
+                                    pTranscv_Info->sRecvlength,
+                                    recvBufferActualSize,
+                                    pTranscv_Info->timeout);
+        }
+        else
+        {
+            ALOGE("%s: Invalid packet", fn);
+            continue;
+        }
+        if(stat != true)
+        {
+            ALOGE("%s: Transceive failed; status=0x%X", fn, stat);
+            status = STATUS_FAILED;
+            goto exit;
+        }
+        else if(recvBufferActualSize != 0 &&
+                pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x90 &&
+                pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)
+        {
+            //ALOGE("%s: END transceive for length %d", fn, pTranscv_Info->sSendlength);
+            status = STATUS_SUCCESS;
+        }
+        else if(pTranscv_Info->sRecvData[recvBufferActualSize-2] == 0x6F &&
+                pTranscv_Info->sRecvData[recvBufferActualSize-1] == 0x00)
+        {
+            ALOGE("%s: JcopOs is already upto date-No update required exiting", fn);
+            Os_info->version_info.ver_status = STATUS_UPTO_DATE;
+            status = STATUS_FAILED;
+            break;
+        }
+        else
+        {
+            status = STATUS_FAILED;
+            ALOGE("%s: Invalid response", fn);
+            goto exit;
+        }
+        ALOGE("%s: Going for next line", fn);
+    }
+
+    if(status == STATUS_SUCCESS)
+    {
+        Os_info->cur_state++;
+        SetJcopOsState(Os_info, Os_info->cur_state);
+    }
+
+exit:
+    mchannel->doeSE_JcopDownLoadReset();
+    ALOGE("%s close fp and exit; status= 0x%X", fn,status);
+    wResult = fclose(Os_info->fp);
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        GetJcopOsState
+**
+** Description:     Used to update the JCOP OS state
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::GetJcopOsState(JcopOs_ImageInfo_t *Os_info, uint8_t *counter)
+{
+    static const char fn [] = "JcopOsDwnld::GetJcopOsState";
+    tJBL_STATUS status = STATUS_SUCCESS;
+    FILE *fp;
+    uint8_t xx=0;
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL)
+    {
+        ALOGE("%s: invalid parameter", fn);
+        return STATUS_FAILED;
+    }
+    fp = fopen(JCOP_INFO_PATH, "r");
+
+    if (fp == NULL) {
+        ALOGE("file <%s> not exits for reading- creating new file: %s",
+                JCOP_INFO_PATH, strerror(errno));
+        fp = fopen(JCOP_INFO_PATH, "w+");
+        if (fp == NULL)
+        {
+            ALOGE("Error opening OS image file <%s> for reading: %s",
+                    JCOP_INFO_PATH, strerror(errno));
+            return STATUS_FAILED;
+        }
+        fprintf(fp, "%u", xx);
+        fclose(fp);
+    }
+    else
+    {
+        FSCANF_BYTE(fp, "%u", &xx);
+        ALOGE("JcopOsState %d", xx);
+        fclose(fp);
+    }
+
+    switch(xx)
+    {
+    case JCOP_UPDATE_STATE0:
+    case JCOP_UPDATE_STATE3:
+        ALOGE("Starting update from step1");
+        Os_info->index = JCOP_UPDATE_STATE0;
+        Os_info->cur_state = JCOP_UPDATE_STATE0;
+        *counter = 0;
+        break;
+    case JCOP_UPDATE_STATE1:
+        ALOGE("Starting update from step2");
+        Os_info->index = JCOP_UPDATE_STATE1;
+        Os_info->cur_state = JCOP_UPDATE_STATE1;
+        *counter = 3;
+        break;
+    case JCOP_UPDATE_STATE2:
+        ALOGE("Starting update from step3");
+        Os_info->index = JCOP_UPDATE_STATE2;
+        Os_info->cur_state = JCOP_UPDATE_STATE2;
+        *counter = 5;
+        break;
+    default:
+        ALOGE("invalid state");
+        status = STATUS_FAILED;
+        break;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function:        SetJcopOsState
+**
+** Description:     Used to set the JCOP OS state
+**
+** Returns:         Success if ok.
+**
+*******************************************************************************/
+tJBL_STATUS JcopOsDwnld::SetJcopOsState(JcopOs_ImageInfo_t *Os_info, uint8_t state)
+{
+    static const char fn [] = "JcopOsDwnld::SetJcopOsState";
+    tJBL_STATUS status = STATUS_FAILED;
+    FILE *fp;
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL)
+    {
+        ALOGE("%s: invalid parameter", fn);
+        return status;
+    }
+    fp = fopen(JCOP_INFO_PATH, "w");
+
+    if (fp == NULL) {
+        ALOGE("Error opening OS image file <%s> for reading: %s",
+                JCOP_INFO_PATH, strerror(errno));
+    }
+    else
+    {
+        fprintf(fp, "%u", state);
+        fflush(fp);
+        ALOGE("Current JcopOsState: %d", state);
+        status = STATUS_SUCCESS;
+    int fd=fileno(fp);
+    int ret = fdatasync(fd);
+        ALOGE("ret value: %d", ret);
+        fclose(fp);
+    }
+    return status;
+}
+
+#if 0
+void *JcopOsDwnld::GetMemory(uint32_t size)
+{
+    void *pMem;
+    static const char fn [] = "JcopOsDwnld::GetMemory";
+    pMem = (void *)malloc(size);
+
+    if(pMem != NULL)
+    {
+        memset(pMem, 0, size);
+    }
+    else
+    {
+        ALOGD("%s: memory allocation failed", fn);
+    }
+    return pMem;
+}
+
+void JcopOsDwnld::FreeMemory(void *pMem)
+{
+    if(pMem != NULL)
+    {
+        free(pMem);
+        pMem = NULL;
+    }
+}
+
+#endif
diff --git a/src/Android.bp b/src/Android.bp
deleted file mode 100644
index e626a3c..0000000
--- a/src/Android.bp
+++ /dev/null
@@ -1,69 +0,0 @@
-cc_library_shared {
-    arch: {
-        arm: {
-            instruction_set: "arm",
-        },
-    },
-    name: "libnfc-nci",
-    shared_libs: [
-        "libcutils",
-        "liblog",
-        "libdl",
-        "libhardware",
-        "libpower",
-
-        // Treble configuration
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "libutils",
-        "android.hardware.nfc@1.0",
-        "vendor.nxp.nxpnfc@1.0",
-    ],
-    cflags: [
-        "-DBUILDCFG=1",
-        "-Wno-deprecated-register",
-        "-Wno-unused-parameter",
-        "-Wno-missing-field-initializers",
-        "-DNXP_EXTNS=TRUE",
-        "-DNFC_NXP_AID_MAX_SIZE_DYN=TRUE",
-        "-DNXP_NFCC_HCE_F=TRUE",
-        "-DNFC_NXP_LISTEN_ROUTE_TBL_OPTIMIZATION=TRUE",
-        "-DANDROID"
-    ],
-    local_include_dirs: [
-        "include",
-        "gki/ulinux",
-        "gki/common",
-        "hal/include",
-        "hal/int",
-        "nfa/include",
-        "nfa/int",
-        "nfc/include",
-        "nfc/int",
-    ],
-    include_dirs: [
-        "vendor/nxp/opensource/hardware/interfaces/nxpnfc/1.0/default/",
-    ],
-    srcs: [
-        "nfa/ce/*.c",
-        "nfa/dm/*.c",
-        "nfa/ee/*.c",
-        "nfa/hci/*.c",
-        "nfa/int/*.c",
-        "nfa/p2p/*.c",
-        "nfa/rw/*.c",
-        "nfa/sys/*.c",
-        "nfc/int/*.c",
-        "nfc/llcp/*.c",
-        "nfc/nci/*.c",
-        "nfc/ndef/*.c",
-        "nfc/nfc/*.c",
-        "nfc/tags/*.c",
-        "adaptation/*.c",
-        "adaptation/*.cpp",
-        "gki/common/*.c",
-        "gki/ulinux/*.c",
-        "nfca_version.c",
-    ],
-}
diff --git a/src/adaptation/NfcAdaptation.cpp b/src/adaptation/NfcAdaptation.cpp
index bc89f23..25d94b7 100644
--- a/src/adaptation/NfcAdaptation.cpp
+++ b/src/adaptation/NfcAdaptation.cpp
@@ -1,5 +1,11 @@
 /******************************************************************************
  *
+ *  Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
  *  Copyright (C) 1999-2012 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,39 +21,22 @@
  *  limitations under the License.
  *
  ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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 <android/hardware/nfc/1.0/INfc.h>
+#include <vendor/nxp/hardware/nfc/1.0/INqNfc.h>
 #include <android/hardware/nfc/1.0/INfcClientCallback.h>
 #include <android/hardware/nfc/1.0/types.h>
 #include <hwbinder/ProcessState.h>
 #include <pthread.h>
 #include "NfcAdaptation.h"
-extern "C" {
-#include "gki.h"
-#include "nfa_api.h"
-#include "nfc_int.h"
-#include "nfc_target.h"
-#include "vendor_cfg.h"
+extern "C"
+{
+    #include "gki.h"
+    #include "nfa_api.h"
+    #include "nfc_int.h"
+    #include "nfc_target.h"
+    #include "vendor_cfg.h"
 }
 #include "config.h"
 #include "android_logmsg.h"
@@ -63,9 +52,9 @@
 using android::hardware::Return;
 using android::hardware::Void;
 using android::hardware::nfc::V1_0::INfc;
+using vendor::nxp::hardware::nfc::V1_0::INqNfc;
 using android::hardware::nfc::V1_0::INfcClientCallback;
 using android::hardware::hidl_vec;
-using vendor::nxp::nxpnfc::V1_0::INxpNfc;
 
 extern "C" void GKI_shutdown();
 extern void resetConfig();
@@ -75,14 +64,15 @@
 NfcAdaptation* NfcAdaptation::mpInstance = NULL;
 ThreadMutex NfcAdaptation::sLock;
 ThreadMutex NfcAdaptation::sIoctlLock;
-sp<INxpNfc> NfcAdaptation::mHalNxpNfc;
 sp<INfc> NfcAdaptation::mHal;
+sp<INqNfc> NfcAdaptation::mNqHal;
 INfcClientCallback* NfcAdaptation::mCallback;
+nfc_nci_device_t* NfcAdaptation::mHalDeviceContext = NULL;
 tHAL_NFC_CBACK* NfcAdaptation::mHalCallback = NULL;
 tHAL_NFC_DATA_CBACK* NfcAdaptation::mHalDataCallback = NULL;
 ThreadCondVar NfcAdaptation::mHalOpenCompletedEvent;
 ThreadCondVar NfcAdaptation::mHalCloseCompletedEvent;
-
+ThreadCondVar NfcAdaptation::mHalIoctlEvent;
 #if (NXP_EXTNS == TRUE)
 ThreadCondVar NfcAdaptation::mHalCoreResetCompletedEvent;
 ThreadCondVar NfcAdaptation::mHalCoreInitCompletedEvent;
@@ -202,7 +192,7 @@
   }
   if (!GetStrValue(NAME_NFA_STORAGE, bcm_nfc_location,
                    sizeof(bcm_nfc_location))) {
-    strlcpy(bcm_nfc_location, "/data/vendor/nfc", sizeof(bcm_nfc_location));
+    strlcpy(bcm_nfc_location, "/data/nfc", sizeof(bcm_nfc_location));
   }
 
   initializeProtocolLogLevel();
@@ -397,32 +387,29 @@
   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;
-#if (NXP_EXTNS == TRUE)
-  mHalEntryFuncs.ioctl = HalIoctl;
+    mHalEntryFuncs.initialize = HalInitialize;
+    mHalEntryFuncs.terminate = HalTerminate;
+    mHalEntryFuncs.open = HalOpen;
+    mHalEntryFuncs.close = HalClose;
+    mHalEntryFuncs.core_initialized = HalCoreInitialized;
+    mHalEntryFuncs.write = HalWrite;
+#if(NXP_EXTNS == TRUE)
+    mHalEntryFuncs.ioctl = HalIoctl;
 #endif
-  mHalEntryFuncs.prediscover = HalPrediscover;
-  mHalEntryFuncs.control_granted = HalControlGranted;
-  mHalEntryFuncs.power_cycle = HalPowerCycle;
-  mHalEntryFuncs.get_max_ee = HalGetMaxNfcee;
-  ALOGI("%s: INfc::getService()", func);
-  mHal = INfc::getService();
-  LOG_FATAL_IF(mHal == nullptr, "Failed to retrieve the NFC HAL!");
-  ALOGI("%s: INfc::getService() returned %p (%s)", func, mHal.get(),
-        (mHal->isRemote() ? "remote" : "local"));
-  ALOGI("%s: INxpNfc::getService()", func);
-  mHalNxpNfc = INxpNfc::getService();
-  LOG_FATAL_IF(mHalNxpNfc == nullptr, "Failed to retrieve the NXP NFC HAL!");
-  ALOGI("%s: INxpNfc::getService() returned %p (%s)", func, mHalNxpNfc.get(),
-        (mHalNxpNfc->isRemote() ? "remote" : "local"));
-  ALOGD("%s: exit", func);
+    mHalEntryFuncs.prediscover = HalPrediscover;
+    mHalEntryFuncs.control_granted = HalControlGranted;
+    mHalEntryFuncs.power_cycle = HalPowerCycle;
+    mHalEntryFuncs.get_max_ee = HalGetMaxNfcee;
+    ALOGI("%s: INfc::getService()", func);
+    mHal = INfc::getService();
+    LOG_FATAL_IF(mHal == nullptr, "Failed to retrieve the NFC HAL!");
+    ALOGI("%s: INfc::getService() returned %p (%s)", func,
+          mHal.get(), (mHal->isRemote() ? "remote" : "local"));
+    mNqHal = INqNfc::getService();
+    LOG_FATAL_IF(mNqHal == nullptr, "Failed to retrieve the vendor NFC HAL!");
+    ALOGI("%s: INqNfc::getService() returned %p (%s)", func,
+          mNqHal.get(), (mNqHal->isRemote() ? "remote" : "local"));
+    ALOGD ("%s: exit", func);
 }
 
 /*******************************************************************************
@@ -538,6 +525,14 @@
 }
 
 #if (NXP_EXTNS == TRUE)
+typedef struct {
+    struct nfc_nci_device nci_device;
+
+    /* Local definitions */
+    int(*ioctl)(const struct nfc_nci_device *p_dev, long arg, void *p_data);
+    int(*check_fw_dwnld_flag)(const struct nfc_nci_device *p_dev, uint8_t* param1);
+
+} pn547_dev_t;
 /*******************************************************************************
 **
 ** Function:    IoctlCallback
@@ -577,6 +572,7 @@
 *******************************************************************************/
 int NfcAdaptation::HalIoctl(long arg, void* p_data) {
   const char* func = "NfcAdaptation::HalIoctl";
+  mHalIoctlEvent.lock();
   ::android::hardware::nfc::V1_0::NfcData data;
   AutoThreadMutex a(sIoctlLock);
   nfc_nci_IoctlInOutData_t* pInpOutData = (nfc_nci_IoctlInOutData_t*)p_data;
@@ -585,9 +581,9 @@
   pInpOutData->inp.context = &NfcAdaptation::GetInstance();
   NfcAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
   data.setToExternal((uint8_t*)pInpOutData, sizeof(nfc_nci_IoctlInOutData_t));
-  if(mHalNxpNfc != nullptr)
-      mHalNxpNfc->ioctl(arg, data, IoctlCallback);
+  mNqHal->ioctl(arg, data, IoctlCallback);
   ALOGD("%s Ioctl Completed for Type=%llu", func, pInpOutData->out.ioctlType);
+  mHalIoctlEvent.unlock();
   return (pInpOutData->out.result);
 }
 
diff --git a/src/adaptation/libmain.c b/src/adaptation/libmain.c
index 7b61025..c4ad050 100644
--- a/src/adaptation/libmain.c
+++ b/src/adaptation/libmain.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2011-2012 Broadcom Corporation
  *
@@ -81,13 +83,13 @@
 
   memset(filename, 0, sizeof(filename));
   memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
   if (strlen(filename2) > 200) {
     ALOGE("%s: filename too long", __func__);
     return;
   }
-  sprintf(filename, "%s%u", filename2, block);
+  snprintf (filename, 256, "%s%u", filename2, block);
 
   ALOGD("%s: buffer len=%u; file=%s", __func__, nbytes, filename);
   int fileStream = open(filename, O_RDONLY);
@@ -134,13 +136,13 @@
 
   memset(filename, 0, sizeof(filename));
   memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
   if (strlen(filename2) > 200) {
     ALOGE("%s: filename too long", __func__);
     return;
   }
-  sprintf(filename, "%s%u", filename2, block);
+  snprintf (filename, 256, "%s%u", filename2, block);
   ALOGD("%s: bytes=%u; file=%s", __func__, nbytes, filename);
 
   int fileStream = 0;
@@ -187,21 +189,21 @@
 
   memset(filename, 0, sizeof(filename));
   memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
   if (strlen(filename2) > 200) {
     ALOGE("%s: filename too long", __func__);
     return;
   }
-  sprintf(filename, "%s%u", filename2, DH_NV_BLOCK);
+  snprintf (filename, 256, "%s%u", filename2, DH_NV_BLOCK);
   remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F3_NV_BLOCK);
+  snprintf (filename, 256, "%s%u", filename2, HC_F3_NV_BLOCK);
   remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F4_NV_BLOCK);
+  snprintf (filename, 256, "%s%u", filename2, HC_F4_NV_BLOCK);
   remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F2_NV_BLOCK);
+  snprintf (filename, 256, "%s%u", filename2, HC_F2_NV_BLOCK);
   remove(filename);
-  sprintf(filename, "%s%u", filename2, HC_F5_NV_BLOCK);
+  snprintf (filename, 256, "%s%u", filename2, HC_F5_NV_BLOCK);
   remove(filename);
 }
 
@@ -223,22 +225,22 @@
 
   memset(filename, 0, sizeof(filename));
   memset(filename2, 0, sizeof(filename2));
-  strcpy(filename2, bcm_nfc_location);
-  strncat(filename2, sNfaStorageBin, sizeof(filename2) - strlen(filename2) - 1);
+  strlcpy(filename2, bcm_nfc_location, sizeof(filename2));
+  strlcat(filename2, sNfaStorageBin, sizeof(filename2)-strlen(filename2)-1);
   if (strlen(filename2) > 200) {
     ALOGE("%s: filename too long", __func__);
     return;
   }
 
-  sprintf(filename, "%s%u", filename2, DH_NV_BLOCK);
+  snprintf (filename, 256, "%s%u", filename2, DH_NV_BLOCK);
   if (crcChecksumVerifyIntegrity(filename)) {
-    sprintf(filename, "%s%u", filename2, HC_F3_NV_BLOCK);
+    snprintf (filename, 256, "%s%u", filename2, HC_F3_NV_BLOCK);
     if (crcChecksumVerifyIntegrity(filename)) {
-      sprintf(filename, "%s%u", filename2, HC_F4_NV_BLOCK);
+      snprintf (filename, 256, "%s%u", filename2, HC_F4_NV_BLOCK);
       if (crcChecksumVerifyIntegrity(filename)) {
-        sprintf(filename, "%s%u", filename2, HC_F2_NV_BLOCK);
+        snprintf (filename, 256, "%s%u", filename2, HC_F2_NV_BLOCK);
         if (crcChecksumVerifyIntegrity(filename)) {
-          sprintf(filename, "%s%u", filename2, HC_F5_NV_BLOCK);
+          snprintf (filename, 256, "%s%u", filename2, HC_F5_NV_BLOCK);
           if (crcChecksumVerifyIntegrity(filename)) isValid = true;
         }
       }
diff --git a/src/gki/common/gki_buffer.c b/src/gki/common/gki_buffer.c
index 674d8b0..a99c352 100644
--- a/src/gki/common/gki_buffer.c
+++ b/src/gki/common/gki_buffer.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 1999-2012 Broadcom Corporation
  *
@@ -444,7 +446,7 @@
            (uint8_t*)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);
+      strlcpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
       p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
       p_hdr->_line = _line_;
 #endif
@@ -554,7 +556,7 @@
          (uint8_t*)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);
+    strlcpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
     p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
     p_hdr->_line = _line_;
 #endif
diff --git a/src/gki/common/gki_time.c b/src/gki/common/gki_time.c
index 4ee8dda..85d68c2 100644
--- a/src/gki/common/gki_time.c
+++ b/src/gki/common/gki_time.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 1999-2012 Broadcom Corporation
  *
diff --git a/src/gki/ulinux/data_types.h b/src/gki/ulinux/data_types.h
index 40a1622..5ede586 100644
--- a/src/gki/ulinux/data_types.h
+++ b/src/gki/ulinux/data_types.h
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 1999-2012 Broadcom Corporation
  *
@@ -59,4 +61,14 @@
 #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))
+#define NQ_STRLCPY_S(x1,x2,x3,x4)   strlcpy((x1),(x3),(x2))
+
 #endif
diff --git a/src/gki/ulinux/gki_ulinux.c b/src/gki/ulinux/gki_ulinux.c
old mode 100755
new mode 100644
index 089b0d0..bbcff6e
--- a/src/gki/ulinux/gki_ulinux.c
+++ b/src/gki/ulinux/gki_ulinux.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 1999-2012 Broadcom Corporation
  *
@@ -71,6 +73,7 @@
 #if (NXP_EXTNS == TRUE)
 uint8_t gki_buf_init_done = false;
 #endif
+/* For Android */
 
 typedef struct {
   uint8_t task_id;         /* GKI task id */
@@ -996,7 +999,7 @@
     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);
+    strlcpy((char*)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
   }
 
   GKI_enable();
diff --git a/src/hal/include/Nxp_Features.h b/src/hal/include/Nxp_Features.h
new file mode 100644
index 0000000..84ab3dc
--- /dev/null
+++ b/src/hal/include/Nxp_Features.h
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2012-2016 NXP Semiconductors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NXP features declarations
+ */
+#include <unistd.h>
+#include <string.h>
+#ifndef NXP_FEATURES_H
+#define NXP_FEATURES_H
+
+#define STRMAX_1 40
+#define STRMAX_2 100
+#define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+#define FW_DLL_EXTENSION ".so"
+
+#define FW_MOBILE_MAJOR_NUMBER_PN553 0x01
+#define FW_MOBILE_MAJOR_NUMBER_PN551 0x05
+#define FW_MOBILE_MAJOR_NUMBER_PN48AD 0x01
+
+#define NFA_EE_MAX_EE_SUPPORTED 4
+
+#define JCOP_VER_3_1    1
+#define JCOP_VER_3_2    2
+#define JCOP_VER_3_3    3
+#define JCOP_VER_4_0    4
+
+typedef enum {
+    pn547C2 = 0x01,
+    pn65T,
+    pn548C2,
+    pn66T,
+    pn551,
+    pn67T,
+    pn553,
+    pn80T,
+    pn557,
+    pn81T
+}tNFC_chipType;
+
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    /*Flags common to all chip types*/
+    uint8_t _NXP_NFCC_EMPTY_DATA_PACKET                     : 1;
+    uint8_t _GEMALTO_SE_SUPPORT                             : 1;
+    uint8_t _NFCC_I2C_READ_WRITE_IMPROVEMENT                : 1;
+    uint8_t _NFCC_MIFARE_TIANJIN                            : 1;
+    uint8_t _NFCC_MW_RCVRY_BLK_FW_DNLD                      : 1;
+    uint8_t _NFCC_DYNAMIC_DUAL_UICC                         : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH              : 1;
+    uint8_t _NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH           : 1;
+    uint8_t _NFCC_FW_WA                                     : 1;
+    uint8_t _NFCC_FORCE_NCI1_0_INIT                         : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT                         : 1;
+    uint8_t _NFCC_SPI_FW_DOWNLOAD_SYNC                      : 1;
+    uint8_t _HW_ANTENNA_LOOP4_SELF_TEST                     : 1;
+    uint8_t _NFCEE_REMOVED_NTF_RECOVERY                     : 1;
+    uint8_t _NFCC_FORCE_FW_DOWNLOAD                         : 1;
+    uint8_t _UICC_CREATE_CONNECTIVITY_PIPE                  : 1;
+    uint8_t _NFCC_AID_MATCHING_PLATFORM_CONFIG              : 1;
+    uint8_t _NFCC_ROUTING_BLOCK_BIT_PROP                    : 1;
+    uint8_t _NXP_NFC_UICC_ETSI12                            : 1;
+    uint8_t _NFA_EE_MAX_EE_SUPPORTED                        : 3;
+}tNfc_nfccFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _ESE_EXCLUSIVE_WIRED_MODE                    : 2;
+    uint8_t _ESE_WIRED_MODE_RESUME                       : 2;
+    uint8_t _ESE_WIRED_MODE_TIMEOUT                      : 2;
+    uint8_t _ESE_PN67T_RESET                             : 2;
+    uint8_t _ESE_APDU_GATE_RESET                         : 2;
+    uint8_t _ESE_WIRED_MODE_DISABLE_DISCOVERY            : 1;
+    uint8_t _LEGACY_APDU_GATE                            : 1;
+    uint8_t _TRIPLE_MODE_PROTECTION                      : 1;
+    uint8_t _ESE_FELICA_CLT                              : 1;
+    uint8_t _WIRED_MODE_STANDBY_PROP                     : 1;
+    uint8_t _WIRED_MODE_STANDBY                          : 1;
+    uint8_t _ESE_DUAL_MODE_PRIO_SCHEME                   : 2;
+    uint8_t _ESE_FORCE_ENABLE                            : 1;
+    uint8_t _ESE_RESET_METHOD                            : 1;
+    uint8_t _EXCLUDE_NV_MEM_DEPENDENCY                   : 1;
+    uint8_t _ESE_ETSI_READER_ENABLE                      : 1;
+    uint8_t _ESE_SVDD_SYNC                               : 1;
+    uint8_t _NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION  : 1;
+    uint8_t _ESE_JCOP_DWNLD_PROTECTION                   : 1;
+    uint8_t _UICC_HANDLE_CLEAR_ALL_PIPES                 : 1;
+    uint8_t _GP_CONTINOUS_PROCESSING                     : 1;
+    uint8_t _ESE_DWP_SPI_SYNC_ENABLE                     : 1;
+    uint8_t _ESE_ETSI12_PROP_INIT                        : 1;
+    uint8_t _ESE_WIRED_MODE_PRIO                         : 1;
+    uint8_t _ESE_UICC_EXCLUSIVE_WIRED_MODE               : 1;
+    uint8_t _ESE_POWER_MODE                              : 1;
+    uint8_t _ESE_P73_ISO_RST                             : 1;
+    uint8_t _BLOCK_PROPRIETARY_APDU_GATE                 : 1;
+    uint8_t _JCOP_WA_ENABLE                              : 1;
+    uint8_t _NXP_LDR_SVC_VER_2                           : 1;
+    uint8_t _NXP_ESE_VER                                 : 3;
+}tNfc_eseFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t _NFCC_RESET_RSP_LEN;
+}tNfc_platformFeatureList;
+
+typedef struct {
+    uint8_t _NCI_INTERFACE_UICC_DIRECT;
+    uint8_t _NCI_INTERFACE_ESE_DIRECT;
+    uint8_t _NCI_PWR_LINK_PARAM_CMD_SIZE;
+    uint8_t _NCI_EE_PWR_LINK_ALWAYS_ON;
+    uint8_t _NFA_EE_MAX_AID_ENTRIES;
+    uint8_t _NFC_NXP_AID_MAX_SIZE_DYN : 1;
+    uint8_t _FW_LIB_PATH[STRMAX_2];
+    uint8_t _PLATFORM_LIB_PATH[STRMAX_2];
+    uint8_t _PKU_LIB_PATH[STRMAX_2];
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+    uint16_t _PHDNLDNFC_USERDATA_EEPROM_LEN;
+    uint8_t  _FW_MOBILE_MAJOR_NUMBER;
+}tNfc_nfcMwFeatureList;
+/*
+ * TODO renaming
+ * */
+typedef struct {
+    uint8_t nfcNxpEse : 1;
+    tNFC_chipType chipType;
+    tNfc_nfccFeatureList nfccFL;
+    tNfc_eseFeatureList eseFL;
+    tNfc_platformFeatureList platformFL;
+    tNfc_nfcMwFeatureList nfcMwFL;
+}tNfc_featureList;
+
+extern tNfc_featureList nfcFL;
+
+#define CONFIGURE_FEATURELIST(chipType) {                                   \
+        nfcFL.chipType = chipType;                                          \
+        nfcFL.nfcMwFL._NFC_NXP_AID_MAX_SIZE_DYN = true;                     \
+        if(chipType == pn81T) {                                             \
+            nfcFL.chipType = pn557;                                         \
+        }                                                                   \
+        else if(chipType == pn80T) {                                        \
+            nfcFL.chipType = pn553;                                         \
+        }                                                                   \
+        else if(chipType == pn67T) {                                        \
+            nfcFL.chipType = pn551;                                         \
+        }                                                                   \
+        else if(chipType == pn66T) {                                        \
+            nfcFL.chipType = pn548C2;                                       \
+        }                                                                   \
+        else if(chipType == pn65T) {                                        \
+            nfcFL.chipType = pn547C2;                                       \
+        }                                                                   \
+        if ((chipType == pn65T) || (chipType == pn66T) ||                   \
+                (chipType == pn67T) || (chipType == pn80T) ||               \
+                (chipType == pn81T)) {                                      \
+            nfcFL.nfcNxpEse = true;                                         \
+            CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType)                   \
+        } \
+        else {                                                              \
+            nfcFL.nfcNxpEse = false;                                        \
+            CONFIGURE_FEATURELIST_NFCC(chipType)                            \
+        }                                                                   \
+        \
+        \
+}
+
+#define CONFIGURE_FEATURELIST_NFCC_WITH_ESE(chipType) {                     \
+        nfcFL.nfccFL._NXP_NFCC_EMPTY_DATA_PACKET = true;                    \
+        nfcFL.nfccFL._GEMALTO_SE_SUPPORT = true;                            \
+        \
+        \
+        nfcFL.eseFL._ESE_EXCLUSIVE_WIRED_MODE = 1;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_RESUME = 2;                             \
+        nfcFL.eseFL._ESE_PN67T_RESET = 1;                                   \
+        nfcFL.eseFL._ESE_APDU_GATE_RESET = 2;                               \
+        nfcFL.eseFL._NXP_ESE_VER = JCOP_VER_4_0;                            \
+        nfcFL.eseFL._NXP_LDR_SVC_VER_2 = true;                              \
+        \
+        \
+        if (chipType == pn81T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn557)                               \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                   \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+        }                                                                   \
+        if (chipType == pn80T) {                                            \
+            CONFIGURE_FEATURELIST_NFCC(pn553)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 4;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FELICA_CLT = true;                             \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                        \
+            nfcFL.eseFL._ESE_WIRED_MODE_RESUME;                             \
+            nfcFL.eseFL._ESE_RESET_METHOD = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = true;                  \
+            nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = true;                \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+            nfcFL.eseFL._ESE_POWER_MODE = true;                             \
+            nfcFL.eseFL._ESE_P73_ISO_RST = true;                            \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;              \
+            nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                \
+        }                                                                   \
+        else if (chipType == pn67T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn551)                               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn66T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn548C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._TRIPLE_MODE_PROTECTION = true;                     \
+            nfcFL.eseFL._WIRED_MODE_STANDBY = true;                         \
+            nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = true;                    \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI_READER_ENABLE = true;                     \
+            nfcFL.eseFL._ESE_SVDD_SYNC = true;                              \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+            nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = true; \
+            nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = true;                    \
+        }                                                                   \
+        else if (chipType == pn65T)                                         \
+        {                                                                   \
+            CONFIGURE_FEATURELIST_NFCC(pn547C2)                             \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = true;           \
+            nfcFL.eseFL._LEGACY_APDU_GATE = true;                           \
+        }                                                                   \
+}
+
+
+#define CONFIGURE_FEATURELIST_NFCC(chipType) {                              \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT = 3;                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_DISABLE_DISCOVERY = false;              \
+        nfcFL.eseFL._LEGACY_APDU_GATE = false;                              \
+        nfcFL.eseFL._TRIPLE_MODE_PROTECTION = false;                        \
+        nfcFL.eseFL._ESE_FELICA_CLT = false;                                \
+        nfcFL.eseFL._WIRED_MODE_STANDBY_PROP = false;                       \
+        nfcFL.eseFL._WIRED_MODE_STANDBY = false;                            \
+        nfcFL.eseFL._ESE_DUAL_MODE_PRIO_SCHEME =                            \
+        nfcFL.eseFL._ESE_WIRED_MODE_TIMEOUT;                                \
+        nfcFL.eseFL._ESE_FORCE_ENABLE = false;                              \
+        nfcFL.eseFL._ESE_RESET_METHOD = false;                              \
+        nfcFL.eseFL._ESE_ETSI_READER_ENABLE = false;                        \
+        nfcFL.eseFL._ESE_SVDD_SYNC = false;                                 \
+        nfcFL.eseFL._NFCC_ESE_UICC_CONCURRENT_ACCESS_PROTECTION = false;    \
+        nfcFL.eseFL._ESE_JCOP_DWNLD_PROTECTION = false;                     \
+        nfcFL.eseFL._UICC_HANDLE_CLEAR_ALL_PIPES = false;                   \
+        nfcFL.eseFL._GP_CONTINOUS_PROCESSING = false;                       \
+        nfcFL.eseFL._ESE_DWP_SPI_SYNC_ENABLE = false;                       \
+        nfcFL.eseFL._ESE_ETSI12_PROP_INIT = false;                          \
+        nfcFL.eseFL._ESE_WIRED_MODE_PRIO = false;                           \
+        nfcFL.eseFL._ESE_UICC_EXCLUSIVE_WIRED_MODE = false;                 \
+        nfcFL.eseFL._ESE_POWER_MODE = false;                                \
+        nfcFL.eseFL._ESE_P73_ISO_RST = false;                               \
+        nfcFL.eseFL._BLOCK_PROPRIETARY_APDU_GATE = false;                   \
+        nfcFL.eseFL._JCOP_WA_ENABLE = true;                                 \
+        nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = false;                     \
+        nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                          \
+        nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                    \
+        \
+        \
+        nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0;                           \
+        \
+        \
+        nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x00;                    \
+        nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x00;                     \
+        nfcFL.nfcMwFL._NCI_PWR_LINK_PARAM_CMD_SIZE = 0x02;                  \
+        nfcFL.nfcMwFL._NCI_EE_PWR_LINK_ALWAYS_ON = 0x01;                    \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x023CU;          \
+        nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C80U;             \
+        nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                             \
+        FW_MOBILE_MAJOR_NUMBER_PN48AD;                                      \
+        \
+        \
+        if (chipType == pn557)                                              \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NXP_NFC_UICC_ETSI12 = false;                      \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn553)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = false;                      \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = true;                 \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = true;                    \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = true;      \
+            nfcFL.nfccFL._NFCC_FW_WA = true;                                \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = true;                    \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = true;                    \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = true;                 \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = false;               \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = true;                    \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = true;             \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = false;        \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 3;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            nfcFL.eseFL._JCOP_WA_ENABLE = false;                            \
+            nfcFL.eseFL._EXCLUDE_NV_MEM_DEPENDENCY = true;                  \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x10U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn553tc_fw", "libpn553tc_fw_platform",            \
+                    "libpn553tc_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN553;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn551)                                         \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            \
+            \
+            nfcFL.platformFL._NFCC_RESET_RSP_LEN = 0x11U;                   \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn551_fw", "libpn551_fw_platform",                \
+                    "libpn551_fw_pku")                                      \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            nfcFL.nfcMwFL._FW_MOBILE_MAJOR_NUMBER =                         \
+            FW_MOBILE_MAJOR_NUMBER_PN551;                                   \
+            \
+            \
+        }                                                                   \
+        else if (chipType == pn548C2)                                       \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = true;           \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = true;         \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = true;               \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.eseFL._ESE_FORCE_ENABLE = true;                           \
+            nfcFL.eseFL._ESE_ETSI12_PROP_INIT = true;                       \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x82;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x83;                 \
+            \
+            \
+            SRTCPY_FW("libpn548ad_fw", "libpn548ad_fw_platform",            \
+                    "libpn548ad_fw_pku")                                    \
+            \
+            \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_OFFSET = 0x02BCU;      \
+            nfcFL.nfcMwFL._PHDNLDNFC_USERDATA_EEPROM_LEN = 0x0C00U;         \
+            \
+            \
+        }                                                                   \
+        else if(chipType == pn547C2)                                        \
+        {                                                                   \
+            nfcFL.nfccFL._NFCC_I2C_READ_WRITE_IMPROVEMENT = false;          \
+            nfcFL.nfccFL._NFCC_MIFARE_TIANJIN = true;                       \
+            nfcFL.nfccFL._NFCC_MW_RCVRY_BLK_FW_DNLD = false;                \
+            nfcFL.nfccFL._NFCC_DYNAMIC_DUAL_UICC = false;                   \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_EXT_SWITCH = false;        \
+            nfcFL.nfccFL._NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH = false;     \
+            nfcFL.nfccFL._NFCC_FW_WA = false;                               \
+            nfcFL.nfccFL._NFCC_FORCE_NCI1_0_INIT = false;                   \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT = false;                   \
+            nfcFL.nfccFL._NFCC_SPI_FW_DOWNLOAD_SYNC = false;                \
+            nfcFL.nfccFL._HW_ANTENNA_LOOP4_SELF_TEST = true;                \
+            nfcFL.nfccFL._NFCEE_REMOVED_NTF_RECOVERY = true;                \
+            nfcFL.nfccFL._NFCC_FORCE_FW_DOWNLOAD = false;                   \
+            nfcFL.nfccFL._UICC_CREATE_CONNECTIVITY_PIPE = false;            \
+            nfcFL.nfccFL._NFCC_AID_MATCHING_PLATFORM_CONFIG = true;         \
+            nfcFL.nfccFL._NFCC_ROUTING_BLOCK_BIT_PROP = false;              \
+            nfcFL.nfccFL._NFA_EE_MAX_EE_SUPPORTED = 2;                      \
+            \
+            \
+            nfcFL.nfcMwFL._NCI_INTERFACE_UICC_DIRECT = 0x81;                \
+            nfcFL.nfcMwFL._NCI_INTERFACE_ESE_DIRECT = 0x82;                 \
+            \
+            \
+            SRTCPY_FW("libpn547_fw", "libpn547_fw_platform",                \
+                    "libpn547_fw_pku")                                      \
+            \
+            \
+        }                                                                   \
+}
+#ifdef __cplusplus
+#define SRTCPY_FW(str1,str2,str3)
+#else
+#define SRTCPY_FW(str1, str2,str3)                                                      \
+        snprintf(nfcFL.nfcMwFL._FW_LIB_PATH, STRMAX_2, "%s%s%s",                        \
+                FW_DLL_ROOT_DIR, str1, FW_DLL_EXTENSION);                               \
+                snprintf(nfcFL.nfcMwFL._PLATFORM_LIB_PATH, STRMAX_2, "%s%s%s",          \
+                        FW_DLL_ROOT_DIR, str2, FW_DLL_EXTENSION);                       \
+                        snprintf(nfcFL.nfcMwFL._PKU_LIB_PATH, STRMAX_2, "%s%s%s",       \
+                                FW_DLL_ROOT_DIR, str3, FW_DLL_EXTENSION);
+#endif
+#endif
diff --git a/src/hal/include/gki_hal_target.h b/src/hal/include/gki_hal_target.h
old mode 100755
new mode 100644
diff --git a/src/hal/include/nfc_hal_api.h b/src/hal/include/nfc_hal_api.h
old mode 100755
new mode 100644
index 40db8fb..ac873c8
--- a/src/hal/include/nfc_hal_api.h
+++ b/src/hal/include/nfc_hal_api.h
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2012-2014 Broadcom Corporation
  *
@@ -45,7 +50,16 @@
 #include <hardware/nfc.h>
 #include "data_types.h"
 #include "nfc_hal_target.h"
-#include "hal_nxpnfc.h"
+
+/*******************************************************************************
+** tHAL_STATUS Definitions
+*******************************************************************************/
+#define HAL_NFC_STATUS_OK               0
+#define HAL_NFC_STATUS_FAILED           1
+#define HAL_NFC_STATUS_ERR_TRANSPORT    2
+#define HAL_NFC_STATUS_ERR_CMD_TIMEOUT  3
+#define HAL_NFC_STATUS_REFUSED          4
+
 /*******************************************************************************
 ** tHAL_HCI_NETWK_CMD Definitions
 *******************************************************************************/
@@ -54,6 +68,132 @@
 #define HAL_NFC_HCI_UICC1_HOST 0x02
 #define HAL_NFC_HCI_UICC2_HOST 0x04
 
+#define MAX_IOCTL_TRANSCEIVE_CMD_LEN  256
+#define MAX_IOCTL_TRANSCEIVE_RESP_LEN 256
+#define MAX_ATR_INFO_LEN              128
+
+/*
+ * Data structures provided below are used of Hal Ioctl calls
+ */
+/*
+ * nfc_nci_ExtnCmd_t shall contain data for commands used for transceive command in ioctl
+ */
+typedef struct
+{
+    uint16_t cmd_len;
+    uint8_t  p_cmd[MAX_IOCTL_TRANSCEIVE_CMD_LEN];
+} nfc_nci_ExtnCmd_t;
+
+/*
+ * nfc_nci_ExtnRsp_t shall contain response for command sent in transceive command
+ */
+typedef struct
+{
+    uint16_t rsp_len;
+    uint8_t  p_rsp[MAX_IOCTL_TRANSCEIVE_RESP_LEN];
+} nfc_nci_ExtnRsp_t;
+/*
+ * InputData_t :ioctl has multiple subcommands
+ * Each command has corresponding input data which needs to be populated in this
+ */
+typedef union {
+    uint16_t          bootMode;
+    uint8_t           halType;
+    nfc_nci_ExtnCmd_t nciCmd;
+    uint32_t          timeoutMilliSec;
+    long              nfcServicePid;
+}InputData_t;
+/*
+ * nfc_nci_ExtnInputData_t :Apart from InputData_t, there are context data
+ * which is required during callback from stub to proxy.
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, context data
+ * is exposed to libnfc (Not encapsulated).
+ */
+typedef struct {
+    /*
+     * context to be used/updated only by users of proxy & stub of Nfc.hal
+     * i.e, NfcAdaptation & Nfc hidl
+     */
+    void*       context;
+    InputData_t data;
+}nfc_nci_ExtnInputData_t;
+
+
+/*
+ * outputData_t :ioctl has multiple commands/responses
+ * This contains the output types for each ioctl.
+ */
+typedef union{
+    uint32_t            status;
+    nfc_nci_ExtnRsp_t   nciRsp;
+    uint8_t             nxpNciAtrInfo[MAX_ATR_INFO_LEN];
+    uint32_t            p61CurrentState;
+    uint16_t            fwUpdateInf;
+    uint16_t            fwDwnldStatus;
+    uint16_t            fwMwVerStatus;
+    uint8_t             chipType;
+}outputData_t;
+
+/*
+ * nfc_nci_ExtnOutputData_t :Apart from outputData_t, there are other information
+ * which is required during callback from stub to proxy.
+ * For ex (context, result of the operation , type of ioctl which was completed).
+ * To avoid additional copy of data while propagating from libnfc to Adaptation
+ * and Nfcstub to ncihal, common structure is used. As a sideeffect, these data
+ * is exposed(Not encapsulated).
+ */
+typedef struct {
+    /*
+     * ioctlType, result & context to be used/updated only by users of
+     * proxy & stub of Nfc.hal.
+     * i.e, NfcAdaptation & Nfc hidl
+     * These fields shall not be used by libnfc or halimplementation
+     */
+    uint64_t     ioctlType;
+    uint32_t     result;
+    void*        context;
+    outputData_t data;
+}nfc_nci_ExtnOutputData_t;
+
+/*
+ * nfc_nci_IoctlInOutData_t :data structure for input & output
+ * to be sent for ioctl command. input is populated by client/proxy side
+ * output is provided from server/stub to client/proxy
+ */
+typedef struct {
+    nfc_nci_ExtnInputData_t  inp;
+    nfc_nci_ExtnOutputData_t out;
+}nfc_nci_IoctlInOutData_t;
+
+enum {
+    HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT = 0x07,
+    HAL_NFC_POST_MIN_INIT_CPLT_EVT  = 0x08
+};
+
+enum {
+    HAL_NFC_IOCTL_P61_IDLE_MODE = 0,
+    HAL_NFC_IOCTL_P61_WIRED_MODE,
+    HAL_NFC_IOCTL_P61_PWR_MODE,
+    HAL_NFC_IOCTL_P61_DISABLE_MODE,
+    HAL_NFC_IOCTL_P61_ENABLE_MODE,
+    HAL_NFC_IOCTL_SET_BOOT_MODE,
+    HAL_NFC_IOCTL_GET_CONFIG_INFO,
+    HAL_NFC_IOCTL_CHECK_FLASH_REQ,
+    HAL_NFC_IOCTL_FW_DWNLD,
+    HAL_NFC_IOCTL_FW_MW_VER_CHECK,
+    HAL_NFC_IOCTL_DISABLE_HAL_LOG,
+    HAL_NFC_IOCTL_NCI_TRANSCEIVE,
+    HAL_NFC_IOCTL_P61_GET_ACCESS,
+    HAL_NFC_IOCTL_P61_REL_ACCESS,
+    HAL_NFC_IOCTL_ESE_CHIP_RST,
+    HAL_NFC_IOCTL_REL_SVDD_WAIT,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_ENABLE,
+    HAL_NFC_IOCTL_SET_JCP_DWNLD_DISABLE,
+    HAL_NFC_IOCTL_SET_NFC_SERVICE_PID,
+    HAL_NFC_IOCTL_GET_FEATURE_LIST
+};
+
 typedef uint8_t tHAL_NFC_STATUS;
 typedef void(tHAL_NFC_STATUS_CBACK)(tHAL_NFC_STATUS status);
 typedef void(tHAL_NFC_CBACK)(uint8_t event, tHAL_NFC_STATUS status);
diff --git a/src/hal/include/nfc_hal_target.h b/src/hal/include/nfc_hal_target.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_brcm_defs.h b/src/hal/int/nfc_brcm_defs.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_int.h b/src/hal/int/nfc_hal_int.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_int_api.h b/src/hal/int/nfc_hal_int_api.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_nv_ci.h b/src/hal/int/nfc_hal_nv_ci.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_nv_co.h b/src/hal/int/nfc_hal_nv_co.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_post_reset.h b/src/hal/int/nfc_hal_post_reset.h
old mode 100755
new mode 100644
diff --git a/src/include/CrcChecksum.h b/src/include/CrcChecksum.h
old mode 100755
new mode 100644
diff --git a/src/include/NfcAdaptation.h b/src/include/NfcAdaptation.h
index 1bbf2b9..60aa1f8 100644
--- a/src/include/NfcAdaptation.h
+++ b/src/include/NfcAdaptation.h
@@ -40,34 +40,35 @@
 #include "nfc_target.h"
 #include "nfc_hal_api.h"
 #include <hardware/nfc.h>
+
 #include <utils/RefBase.h>
-#include <android/hardware/nfc/1.0/INfc.h>
-#include <android/hardware/nfc/1.0/INfcClientCallback.h>
-#include <android/hardware/nfc/1.0/types.h>
-#include <vendor/nxp/nxpnfc/1.0/INxpNfc.h>
-using vendor::nxp::nxpnfc::V1_0::INxpNfc;
 
 namespace android {
 namespace hardware {
 namespace nfc {
 namespace V1_0 {
-struct INfc;
-struct INfcClientCallback;
-}
-}
-}
-}
+    struct INfc;
+    struct INfcClientCallback;
+} } } }
 
-class ThreadMutex {
- public:
-  ThreadMutex();
-  virtual ~ThreadMutex();
-  void lock();
-  void unlock();
-  operator pthread_mutex_t*() { return &mMutex; }
+namespace vendor {
+namespace nxp {
+namespace hardware {
+namespace nfc {
+namespace V1_0 {
+struct INqNfc;
+} } } } }
 
- private:
-  pthread_mutex_t mMutex;
+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 {
@@ -110,28 +111,28 @@
   nfc_nci_IoctlInOutData_t* mCurrentIoctlData;
 #endif
 
- private:
-  NfcAdaptation();
-  void signal();
-  static NfcAdaptation* mpInstance;
-  static ThreadMutex sLock;
-  static ThreadMutex sIoctlLock;
-  ThreadCondVar mCondVar;
-  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 ThreadCondVar mHalOpenCompletedEvent;
-  static ThreadCondVar mHalCloseCompletedEvent;
-  static ThreadCondVar mHalIoctlEvent;
-  static android::sp<android::hardware::nfc::V1_0::INfc> mHal;
-  static android::sp<vendor::nxp::nxpnfc::V1_0::INxpNfc> mHalNxpNfc;
-  static android::hardware::nfc::V1_0::INfcClientCallback* mCallback;
-#if (NXP_EXTNS == TRUE)
-  pthread_t mThreadId;
-  static ThreadCondVar mHalCoreResetCompletedEvent;
-  static ThreadCondVar mHalCoreInitCompletedEvent;
-  static ThreadCondVar mHalInitCompletedEvent;
+private:
+    NfcAdaptation();
+    void    signal();
+    static  NfcAdaptation* mpInstance;
+    static  ThreadMutex sLock;
+    static ThreadMutex sIoctlLock;
+    ThreadCondVar    mCondVar;
+    tHAL_NFC_ENTRY   mHalEntryFuncs; // function pointers for HAL entry points
+    static nfc_nci_device_t* mHalDeviceContext;
+    static android::sp<android::hardware::nfc::V1_0::INfc> mHal;
+    static android::sp<vendor::nxp::hardware::nfc::V1_0::INqNfc> mNqHal;
+    static android::hardware::nfc::V1_0::INfcClientCallback* mCallback;
+    static tHAL_NFC_CBACK* mHalCallback;
+    static tHAL_NFC_DATA_CBACK* mHalDataCallback;
+    static ThreadCondVar mHalOpenCompletedEvent;
+    static ThreadCondVar mHalCloseCompletedEvent;
+    static ThreadCondVar mHalIoctlEvent;
+#if(NXP_EXTNS == TRUE)
+    pthread_t mThreadId;
+    static ThreadCondVar mHalCoreResetCompletedEvent;
+    static ThreadCondVar mHalCoreInitCompletedEvent;
+    static ThreadCondVar mHalInitCompletedEvent;
 #endif
   static uint32_t NFCA_TASK(uint32_t arg);
   static uint32_t Thread(uint32_t arg);
diff --git a/src/nfa/ce/nfa_ce_act.c b/src/nfa/ce/nfa_ce_act.c
index a487629..7735e33 100644
--- a/src/nfa/ce/nfa_ce_act.c
+++ b/src/nfa/ce/nfa_ce_act.c
@@ -411,7 +411,6 @@
   if(NFC_GetNCIVersion() != NCI_VERSION_2_0) {
     UINT8_TO_STREAM (p_params, NCI_PARAM_ID_LF_T3T_PMM);      /* type */
     UINT8_TO_STREAM (p_params, NCI_PARAM_LEN_LF_T3T_PMM);     /* length */
-    ARRAY_TO_BE_STREAM(p_params,t3tPMM, NCI_T3T_PMM_LEN);
   }
 #else
   /* Mask of IDs to disable listening */
diff --git a/src/nfa/ce/nfa_ce_api.c b/src/nfa/ce/nfa_ce_api.c
old mode 100755
new mode 100644
index 9577380..e516d81
--- a/src/nfa/ce/nfa_ce_api.c
+++ b/src/nfa/ce/nfa_ce_api.c
@@ -331,7 +331,6 @@
 *******************************************************************************/
 tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(uint16_t system_code,
                                                uint8_t nfcid2[NCI_RF_F_UID_LEN],
-                                               uint8_t t3tPmm[NCI_T3T_PMM_LEN],
                                                tNFA_CONN_CBACK* p_conn_cback) {
   tNFA_CE_MSG* p_msg;
 
@@ -348,7 +347,6 @@
 
     /* Listen info */
     memcpy(p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN);
-    memcpy(p_msg->reg_listen.t3tPmm, t3tPmm, NCI_T3T_PMM_LEN);
     p_msg->reg_listen.system_code = system_code;
 
     nfa_sys_sendmsg(p_msg);
diff --git a/src/nfa/ce/nfa_ce_main.c b/src/nfa/ce/nfa_ce_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_ndef.c b/src/nfa/dm/nfa_dm_ndef.c
old mode 100755
new mode 100644
index 3f9673f..eeba9e8
--- a/src/nfa/dm/nfa_dm_ndef.c
+++ b/src/nfa/dm/nfa_dm_ndef.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
index 88d04c1..6ebe4f6 100644
--- a/src/nfa/ee/nfa_ee_act.c
+++ b/src/nfa/ee/nfa_ee_act.c
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -15,25 +20,6 @@
  *  limitations under the License.
  *
  ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
 
 /******************************************************************************
  *
@@ -163,7 +149,7 @@
     len = NFA_MAX_AID_LEN;
   }
   for (xx = 0; xx < len; xx++) {
-    yy += sprintf(&buff[yy], "%02x ", *p);
+    yy += snprintf(&buff[yy], 100, "%02x ", *p);
     p++;
   }
   NFA_TRACE_DEBUG4("%s id:0x%x len=%d aid:%s", p_str, id, aid_len, buff);
@@ -201,14 +187,14 @@
 
   p =  p_apdu->p_apdu;
   for (xx = 0; xx < apdu_len; xx++) {
-    yy += sprintf(&apdu[yy], "%02x ", *p);
+    yy += snprintf(&apdu[yy], 125, "%02x ", *p);
     p++;
   }
 
   p =  p_apdu->p_mask;
   yy = 0;
   for (xx = 0; xx < mask_len; xx++) {
-    yy += sprintf(&mask[yy], "%02x ", *p);
+    yy += snprintf(&mask[yy], 125, "%02x ", *p);
     p++;
   }
   NFA_TRACE_DEBUG6("%s id:0x%x apdu_len=%d apdu:%s mask_len=%d mask:%s", p_str, p_apdu->nfcee_id, apdu_len, apdu,mask_len,mask);
diff --git a/src/nfa/hci/nfa_hci_act.c b/src/nfa/hci/nfa_hci_act.c
old mode 100755
new mode 100644
index 3348c8b..8dc672a
--- a/src/nfa/hci/nfa_hci_act.c
+++ b/src/nfa/hci/nfa_hci_act.c
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -17,25 +22,6 @@
  ******************************************************************************/
 /******************************************************************************
  *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
  *
  ******************************************************************************/
@@ -316,7 +302,7 @@
       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]));
-        strncpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
+        NQ_STRLCPY_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,
diff --git a/src/nfa/hci/nfa_hci_api.c b/src/nfa/hci/nfa_hci_api.c
index 07ac31b..0c499c7 100644
--- a/src/nfa/hci/nfa_hci_api.c
+++ b/src/nfa/hci/nfa_hci_api.c
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -17,25 +22,6 @@
  ******************************************************************************/
 /******************************************************************************
  *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
  *
  ******************************************************************************/
@@ -93,11 +79,11 @@
             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));
-    strncpy(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;
+        /* Save application name and callback */
+        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+        NQ_STRLCPY_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);
@@ -198,8 +184,8 @@
             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));
-    strncpy(p_msg->app_name, p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
+        memset (p_msg->app_name, 0, sizeof (p_msg->app_name));
+        NQ_STRLCPY_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);
diff --git a/src/nfa/hci/nfa_hci_ci.c b/src/nfa/hci/nfa_hci_ci.c
old mode 100755
new mode 100644
diff --git a/src/nfa/hci/nfa_hci_main.c b/src/nfa/hci/nfa_hci_main.c
index 211b747..35debff 100644
--- a/src/nfa/hci/nfa_hci_main.c
+++ b/src/nfa/hci/nfa_hci_main.c
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -15,25 +20,6 @@
  *  limitations under the License.
  *
  ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
 
 /******************************************************************************
  *
@@ -984,7 +970,7 @@
   uint8_t pipe;
   uint16_t pkt_len;
 #if (BT_TRACE_VERBOSE == true)
-  char buff[100];
+  char buff[VERBOSE_BUFF_SIZE];
   static bool is_first_chain_pkt = true;
 #endif
 #if (NXP_EXTNS == TRUE)
diff --git a/src/nfa/hci/nfa_hci_utils.c b/src/nfa/hci/nfa_hci_utils.c
old mode 100755
new mode 100644
index 8cd91fc..3cede30
--- a/src/nfa/hci/nfa_hci_utils.c
+++ b/src/nfa/hci/nfa_hci_utils.c
@@ -1,25 +1,12 @@
 /******************************************************************************
  *
- *  Copyright (C) 2010-2014 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -326,7 +313,7 @@
   nfa_hci_cb.IsChainedPacket = false;
 #endif
 #if (BT_TRACE_VERBOSE == true)
-  char buff[100];
+  char buff[VERBOSE_BUFF_SIZE];
 
   NFA_TRACE_DEBUG3(
       "nfa_hciu_send_msg pipe_id:%d   %s  len:%d", pipe_id,
@@ -1548,23 +1535,23 @@
                                    char* p_buff) {
   int xx;
 
-  xx = sprintf(p_buff, "Type: %s [0x%02x] ", nfa_hciu_type_2_str(type), type);
+  xx = snprintf(p_buff, VERBOSE_BUFF_SIZE, "Type: %s [0x%02x] ", nfa_hciu_type_2_str(type), type);
 
   switch (type) {
     case NFA_HCI_COMMAND_TYPE:
-      sprintf(&p_buff[xx], "Inst: %s [0x%02x] ", nfa_hciu_instr_2_str(inst),
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Inst: %s [0x%02x] ", nfa_hciu_instr_2_str(inst),
               inst);
       break;
     case NFA_HCI_EVENT_TYPE:
-      sprintf(&p_buff[xx], "Evt: %s [0x%02x] ", nfa_hciu_evt_2_str(pipe, inst),
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Evt: %s [0x%02x] ", nfa_hciu_evt_2_str(pipe, inst),
               inst);
       break;
     case NFA_HCI_RESPONSE_TYPE:
-      sprintf(&p_buff[xx], "Resp: %s [0x%02x] ",
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Resp: %s [0x%02x] ",
               nfa_hciu_get_response_name(inst), inst);
       break;
     default:
-      sprintf(&p_buff[xx], "Inst: %u ", inst);
+      snprintf(&p_buff[xx], VERBOSE_BUFF_SIZE, "Inst: %u ", inst);
       break;
   }
   return (p_buff);
diff --git a/src/nfa/include/nfa_ce_api.h b/src/nfa/include/nfa_ce_api.h
old mode 100755
new mode 100644
index b4f1da8..28a5708
--- a/src/nfa/include/nfa_ce_api.h
+++ b/src/nfa/include/nfa_ce_api.h
@@ -182,7 +182,6 @@
 *******************************************************************************/
 extern tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(
     uint16_t system_code, uint8_t nfcid2[NCI_RF_F_UID_LEN],
-    uint8_t t3tPmm[NCI_T3T_PMM_LEN],
     tNFA_CONN_CBACK* p_conn_cback);
 
 /*******************************************************************************
diff --git a/src/nfa/include/nfa_mem_co.h b/src/nfa/include/nfa_mem_co.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_nv_ci.h b/src/nfa/include/nfa_nv_ci.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_nv_co.h b/src/nfa/include/nfa_nv_co.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_p2p_api.h b/src/nfa/include/nfa_p2p_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_rw_api.h b/src/nfa/include/nfa_rw_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_snep_api.h b/src/nfa/include/nfa_snep_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_ce_int.h b/src/nfa/int/nfa_ce_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_dta_int.h b/src/nfa/int/nfa_dta_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_hci_int.h b/src/nfa/int/nfa_hci_int.h
index 3a3cbc6..66f3cb3 100644
--- a/src/nfa/int/nfa_hci_int.h
+++ b/src/nfa/int/nfa_hci_int.h
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -15,25 +20,6 @@
  *  limitations under the License.
  *
  ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
 
 /******************************************************************************
  *
@@ -717,6 +703,7 @@
 extern char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type,
                                           uint8_t inst, char* p_buff);
 extern char* nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt);
+#define VERBOSE_BUFF_SIZE 100
 #endif
 
 #endif /* NFA_HCI_INT_H */
diff --git a/src/nfa/int/nfa_p2p_int.h b/src/nfa/int/nfa_p2p_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_rw_int.h b/src/nfa/int/nfa_rw_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_snep_int.h b/src/nfa/int/nfa_snep_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_sys.h b/src/nfa/int/nfa_sys.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_sys_int.h b/src/nfa/int/nfa_sys_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_sys_ptim.h b/src/nfa/int/nfa_sys_ptim.h
old mode 100755
new mode 100644
diff --git a/src/nfa/p2p/nfa_p2p_act.c b/src/nfa/p2p/nfa_p2p_act.c
old mode 100755
new mode 100644
index ba9cebd..f0dfa9a
--- a/src/nfa/p2p/nfa_p2p_act.c
+++ b/src/nfa/p2p/nfa_p2p_act.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -621,12 +623,13 @@
       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;
-    strncpy(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;
+    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;
+        NQ_STRLCPY_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);
 
@@ -643,11 +646,11 @@
   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;
-  strncpy(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;
+    evt_data.reg_server.server_handle = (NFA_HANDLE_GROUP_P2P | server_sap);
+    evt_data.reg_server.server_sap    = server_sap;
+    NQ_STRLCPY_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);
@@ -897,15 +900,18 @@
   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 {
-    strncpy(conn_params.sn, p_msg->api_connect.service_name, LLCP_MAX_SN_LEN);
-    conn_params.sn[LLCP_MAX_SN_LEN] = 0;
+    /* 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
+    {
+        NQ_STRLCPY_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);
   }
diff --git a/src/nfa/p2p/nfa_p2p_api.c b/src/nfa/p2p/nfa_p2p_api.c
old mode 100755
new mode 100644
index 5aabf9b..fb98795
--- a/src/nfa/p2p/nfa_p2p_api.c
+++ b/src/nfa/p2p/nfa_p2p_api.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -91,8 +93,8 @@
     p_msg->server_sap = server_sap;
     p_msg->link_type = link_type;
 
-    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
-    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+        NQ_STRLCPY_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;
 
@@ -390,8 +392,8 @@
                   sizeof(tNFA_P2P_API_CONNECT))) != NULL) {
     p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT;
 
-    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
-    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+        NQ_STRLCPY_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;
@@ -934,8 +936,8 @@
 
     p_msg->handle = handle;
 
-    strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN);
-    p_msg->service_name[LLCP_MAX_SN_LEN] = 0;
+        NQ_STRLCPY_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);
 
diff --git a/src/nfa/rw/nfa_rw_api.c b/src/nfa/rw/nfa_rw_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/rw/nfa_rw_main.c b/src/nfa/rw/nfa_rw_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_cback.c b/src/nfa/sys/nfa_sys_cback.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_cfg.c b/src/nfa/sys/nfa_sys_cfg.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_ptim.c b/src/nfa/sys/nfa_sys_ptim.c
old mode 100755
new mode 100644
diff --git a/src/nfc/include/ce_api.h b/src/nfc/include/ce_api.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/ndef_utils.h b/src/nfc/include/ndef_utils.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/rw_api.h b/src/nfc/include/rw_api.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/ce_int.h b/src/nfc/int/ce_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/llcp_int.h b/src/nfc/int/llcp_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/rw_int.h b/src/nfc/int/rw_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/tags_int.h b/src/nfc/int/tags_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_api.c b/src/nfc/llcp/llcp_api.c
index 4ba6754..7cca07a 100644
--- a/src/nfc/llcp/llcp_api.c
+++ b/src/nfc/llcp/llcp_api.c
@@ -1,4 +1,9 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
+ *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
  *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
@@ -18,26 +23,6 @@
 
 /******************************************************************************
  *
- *  The original Work has been changed by NXP Semiconductors.
- *
- *  Copyright (C) 2015 NXP Semiconductors
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
  *
  ******************************************************************************/
@@ -463,14 +448,15 @@
       return LLCP_INVALID_SAP;
     }
 
-    p_app_cb->p_service_name = (uint8_t*)GKI_getbuf((uint16_t)(length + 1));
-    if (p_app_cb->p_service_name == NULL) {
-      LLCP_TRACE_ERROR0("LLCP_RegisterServer (): Out of resource");
-      return LLCP_INVALID_SAP;
-    }
+        p_app_cb->p_service_name = (uint8_t*) GKI_getbuf ((uint16_t) (length + 1));
+        if (p_app_cb->p_service_name == NULL)
+        {
+            LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
+            return LLCP_INVALID_SAP;
+        }
 
-    strncpy((char*)p_app_cb->p_service_name, (char*)p_service_name, length + 1);
-    p_app_cb->p_service_name[length] = 0;
+        NQ_STRLCPY_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;
 
diff --git a/src/nfc/llcp/llcp_dlc.c b/src/nfc/llcp/llcp_dlc.c
old mode 100755
new mode 100644
index 94d0bfc..73e5003
--- a/src/nfc/llcp/llcp_dlc.c
+++ b/src/nfc/llcp/llcp_dlc.c
@@ -1,25 +1,12 @@
 /******************************************************************************
  *
- *  Copyright (C) 2010-2014 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -1341,16 +1328,19 @@
   uint8_t 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 = (NFC_HDR*)GKI_dequeue(&p_dlcb->i_xmit_q);
-    llcp_cb.total_tx_i_pdu--;
-    if (p_msg) {
-      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);
+    /* 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 = (NFC_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
+        llcp_cb.total_tx_i_pdu--;
+        if(p_msg)
+        {
+            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;
 
diff --git a/src/nfc/llcp/llcp_link.c b/src/nfc/llcp/llcp_link.c
old mode 100755
new mode 100644
index 6aaaf15..e19e630
--- a/src/nfc/llcp/llcp_link.c
+++ b/src/nfc/llcp/llcp_link.c
@@ -1,25 +1,12 @@
 /******************************************************************************
  *
- *  Copyright (C) 2010-2014 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -1029,8 +1016,8 @@
         /* 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);
+                /* 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;
 
@@ -1040,13 +1027,15 @@
       }
     }
 
-    /* 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);
+        /* 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;
diff --git a/src/nfc/llcp/llcp_main.c b/src/nfc/llcp/llcp_main.c
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_sdp.c b/src/nfc/llcp/llcp_sdp.c
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_util.c b/src/nfc/llcp/llcp_util.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nci/nci_hmsgs.c b/src/nfc/nci/nci_hmsgs.c
index c965329..913fe15 100644
--- a/src/nfc/nci/nci_hmsgs.c
+++ b/src/nfc/nci/nci_hmsgs.c
@@ -805,7 +805,9 @@
     pp                  = (uint8_t *) (p + 1) + p->offset;
 
     NCI_MSG_BLD_HDR0 (pp, NCI_MT_CMD, NCI_GID_EE_MANAGE);
+#if (NXP_EXTNS == TRUE) && (NXP_WIRED_MODE_STANDBY == true)
     NCI_MSG_BLD_HDR1 (pp, NCI_MSG_NFCEE_POWER_LINK_CTRL);
+#endif
     UINT8_TO_STREAM (pp, NCI_CORE_PARAM_SIZE_NFCEE_PL_CTRL);
     UINT8_TO_STREAM (pp, nfcee_id);
     UINT8_TO_STREAM (pp, pl_config);
diff --git a/src/nfc/ndef/ndef_utils.c b/src/nfc/ndef/ndef_utils.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_main.c b/src/nfc/nfc/nfc_main.c
index 20bbacb..3acdaab 100644
--- a/src/nfc/nfc/nfc_main.c
+++ b/src/nfc/nfc/nfc_main.c
@@ -1,25 +1,12 @@
 /******************************************************************************
  *
- *  Copyright (C) 2010-2014 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
index cbf54fc..1e183df 100644
--- a/src/nfc/nfc/nfc_ncif.c
+++ b/src/nfc/nfc/nfc_ncif.c
@@ -1,25 +1,12 @@
 /******************************************************************************
  *
- *  Copyright (C) 1999-2014 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 1999-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
diff --git a/src/nfc/nfc/nfc_test.c b/src/nfc/nfc/nfc_test.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_vs.c b/src/nfc/nfc/nfc_vs.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/ce_main.c b/src/nfc/tags/ce_main.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/ce_t3t.c b/src/nfc/tags/ce_t3t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_main.c b/src/nfc/tags/rw_main.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t1t.c b/src/nfc/tags/rw_t1t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t1t_ndef.c b/src/nfc/tags/rw_t1t_ndef.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t2t_ndef.c b/src/nfc/tags/rw_t2t_ndef.c
index 9afacca..3741755 100644
--- a/src/nfc/tags/rw_t2t_ndef.c
+++ b/src/nfc/tags/rw_t2t_ndef.c
@@ -1,25 +1,12 @@
 /******************************************************************************
  *
- *  Copyright (C) 2010-2014 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.
- *
- ******************************************************************************/
-/******************************************************************************
- *
- *  The original Work has been changed by NXP Semiconductors.
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2015 NXP Semiconductors
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2010-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
diff --git a/src/nfc/tags/tags_int.c b/src/nfc/tags/tags_int.c
old mode 100755
new mode 100644
diff --git a/src/static-lib-adapt/ProtoDispBluetoothHci.c b/src/static-lib-adapt/ProtoDispBluetoothHci.c
index 9a5ab98..449a5ae 100644
--- a/src/static-lib-adapt/ProtoDispBluetoothHci.c
+++ b/src/static-lib-adapt/ProtoDispBluetoothHci.c
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
  *
  *  Copyright (C) 2011-2012 Broadcom Corporation
  *
@@ -38,14 +40,14 @@
 ///////////////////////////////////////////
 
 uint8_t* HCIDisp1Ext(char* p_descr, uint8_t* p_data, char* p_ext) {
-  if (p_data == p_end_hci) return p_data;
+    if (p_data == p_end_hci) return p_data;
 
-  char buff[200];
+    char buff[200];
 
-  sprintf(buff, "%40s : %u (0x%02x): %s", p_descr, *p_data, *p_data, p_ext);
+    snprintf (buff, 200, "%40s : %u (0x%02x): %s", p_descr, *p_data, *p_data, p_ext);
 
-  ScrLog(HCI_GEN_TRACE, "%s", buff);
-  return (p_data + 1);
+    ScrLog (HCI_GEN_TRACE, "%s", buff);
+    return (p_data + 1);
 }
 
 /*******************************************************************************