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

* caf/nxpnfc-project/br_android_ncihalx_o: (92 commits)
  NFC_NCIHALx_AR1800.8.0.9_O_OpnSrc
  MW version updated to 8.0.9
  ESE-and-UICC-AID-getting-routed-to-HOST
  MW versio updated to 8.0.8
  APDU-pattern-based-routing
  Fix-for-Power-state-getting-wrongly-update
  MW-version-updated-to-8.0.7
  AID-matching-requirements-added-for-prefi
  Implementation-of-CON_DISCOVERY_PARAM
  NFC_NCIHALx_AR1800.8.0.6_OpnSrc
  Update README.md
  artf248924-MW-version-udpated-to-7.5.0
  artf247527-DTA-Adding-Certification-Release-versioni
  artf238919-NFC-crashed-while-reading-type-1-2-3-4-tat
  artf238919-NFC-crashed-while-reading-type-1-2-3-4-ta
  artf247105-ChipType-Compilation-Issue-NFC-Chip-type
  PT_artf182142-EE-CONFIG-UICC-technology-informations
  -MW-version-updated-to-7.4.9
  artf243863-Deadloack-Issue-Fix-Jcop-Download-is-fail
  artf241444-CMA-BYPASS-Mode-CMA-BYPASS-Mode-to-be-han
  ...

Change-Id: I6a4d9d57f1273196c6f213f9b2c72e3d8c25bede
diff --git a/Android.mk b/Android.mk
index 28c22be..3f639ae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,4 @@
-
-
+ifeq ($(strip $(TARGET_USES_NQ_NFC)),true)
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 NFA := src/nfa
@@ -13,6 +12,7 @@
 
 #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
@@ -57,7 +57,11 @@
 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
@@ -69,6 +73,9 @@
 D_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN553
 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
@@ -86,7 +93,9 @@
 else
 LOCAL_MULTILIB := 32
 endif
-LOCAL_MODULE := libnfc-nci
+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 \
@@ -98,7 +107,11 @@
     $(LOCAL_PATH)/$(NFC)/int \
     $(LOCAL_PATH)/src/hal/include \
     $(LOCAL_PATH)/src/hal/int \
-    $(LOCAL_PATH)/$(HALIMPL)/include
+    $(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) \
@@ -112,3 +125,4 @@
 
 ######################################
 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 3fe293b..4d2c3f7 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 b/halimpl/pn54x/Android.mk
index e47bde8..d91f4e5 100644
--- a/halimpl/pn54x/Android.mk
+++ b/halimpl/pn54x/Android.mk
@@ -50,7 +50,11 @@
 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
@@ -67,11 +71,11 @@
 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
 endif
 ifeq (true,$(TARGET_IS_64_BIT))
 LOCAL_MULTILIB := 64
@@ -79,8 +83,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 +128,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 03c71d0..d71b9e6 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
@@ -33,7 +32,8 @@
 #include <phDal4Nfc_messageQueueLib.h>
 #include <phNfcCompId.h>
 
-#define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+
+#define FW_DLL_ROOT_DIR "/vendor/firmware/"
 #define FW_DLL_EXTENSION ".so"
 
 #if (NFC_NXP_CHIP_TYPE == PN548C2)
diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c
index b97c747..1b9a51c 100644
--- a/halimpl/pn54x/dnld/phDnldNfc.c
+++ b/halimpl/pn54x/dnld/phDnldNfc.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");
@@ -24,6 +27,7 @@
 #include <phNxpLog.h>
 #include <dlfcn.h>
 #include <phNxpConfig.h>
+#include <cutils/properties.h>
 
 static void*
     pFwLibHandle;    /* Global firmware lib handle used in this file only */
@@ -240,6 +244,8 @@
 NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData,
                                    pphDnldNfc_RspCb_t pNotify, void* pContext) {
   NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+  int rc;
+  char nq_chipid[PROPERTY_VALUE_MAX] = {0};
 
   if ((NULL == pNotify) || (NULL == pContext)) {
     NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
@@ -249,17 +255,19 @@
       NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
       wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
     } else {
-      if ((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) ||
-          (PHDNLDNFC_HWVER_MRA2_2 == bChipVer)
-#if (NFC_NXP_CHIP_TYPE == PN551)
-          || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer) ||
-          (PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer)
-#elif(NFC_NXP_CHIP_TYPE == PN548C2)
-          || (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bChipVer)
-#elif(NFC_NXP_CHIP_TYPE == PN553 || NFC_NXP_CHIP_TYPE == PN557)
-          || (PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer) ||
-          (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer) ||
-	  (PHDNLDNFC_HWVER_PN557_MRA1_0 ==  bChipVer)
+          rc = __system_property_get("sys.nfc.nq.chipid", nq_chipid);
+          if (rc <= 0)
+              ALOGE("get sys.nfc.nq.chipid fail, rc = %d\n", rc);
+          else
+              ALOGD("sys.nfc.nq.chipid = %s\n", nq_chipid);
+          if((PHDNLDNFC_HWVER_MRA2_1 == bChipVer) || (PHDNLDNFC_HWVER_MRA2_2 == bChipVer)
+#if(NFC_NXP_CHIP_TYPE == PN551)
+              || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bChipVer)  || (PHDNLDNFC_HWVER_PN553_MRA1_0 == bChipVer)
+#else
+              || (((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX)))
+              && (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bChipVer))
+              || (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & bChipVer)
+              || (PHDNLDNFC_HWVER_PN557_MRA1_0 ==  bChipVer)
 #endif
               ) {
         (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg;
@@ -755,8 +763,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;
   }
 
@@ -973,15 +981,15 @@
   void* pImageInfoLen = NULL;
   if (pathName == NULL) {
 #if (NFC_NXP_CHIP_TYPE == PN548C2)
-    pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+    pathName = "/vendor/firmware/libpn548ad_fw.so";
 #elif(NFC_NXP_CHIP_TYPE == PN551)
-    pathName = "/system/vendor/firmware/libpn551_fw.so";
+    pathName = "/vendor/firmware/libpn551_fw.so";
 #elif(NFC_NXP_CHIP_TYPE == PN553)
-    pathName = "/system/vendor/firmware/libpn553_fw.so";
+    pathName = "/vendor/firmware/libpn553_fw.so";
 #elif(NFC_NXP_CHIP_TYPE == 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";
 #endif
   }
 
@@ -1048,15 +1056,15 @@
   /* check for path name */
   if (pathName == NULL) {
 #if (NFC_NXP_CHIP_TYPE == PN548C2)
-    pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+    pathName = "/vendor/firmware/libpn548ad_fw.so";
 #elif(NFC_NXP_CHIP_TYPE == PN551)
-    pathName = "/system/vendor/firmware/libpn551_fw.so";
+    pathName = "/vendor/firmware/libpn551_fw.so";
 #elif(NFC_NXP_CHIP_TYPE == PN553)
-    pathName = "/system/vendor/firmware/libpn553_fw.so";
+    pathName = "/vendor/firmware/libpn553_fw.so";
 #elif(NFC_NXP_CHIP_TYPE == 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";
 #endif
   }
   /* 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 a989832..4ae666c 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 c6654da..19fdaba 100644
--- a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -20,6 +20,7 @@
 #include <phNxpNciHal_utils.h>
 #include <phNxpLog.h>
 #include <phNxpConfig.h>
+#include <cutils/properties.h>
 
 /* Macro */
 #define PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS 3
@@ -521,6 +522,8 @@
   uint8_t bExpectedLen = 0;
   uint8_t bNewVer[2];
   uint8_t bCurrVer[2];
+  int rc;
+  char nq_chipid[PROPERTY_VALUE_MAX] = {0};
 
   if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo)) {
     NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_version_cb - Request Successful");
@@ -531,25 +534,29 @@
       bHwVer = (pRespBuff->pBuff[0]);
       bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */
 
+      rc = __system_property_get("sys.nfc.nq.chipid", nq_chipid);
+      if (rc <= 0)
+          ALOGE("get sys.nfc.nq.chipid fail, rc = %d\n", rc);
+      else
+          ALOGD("sys.nfc.nq.chipid = %s\n", nq_chipid);
       if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) ||
           (PHDNLDNFC_HWVER_MRA2_2 == bHwVer)
-#if (NFC_NXP_CHIP_TYPE == PN551)
-          || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bHwVer) ||
-          (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer)
-#elif(NFC_NXP_CHIP_TYPE == PN548C2)
-          || (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer)
-#elif(NFC_NXP_CHIP_TYPE == PN553 || NFC_NXP_CHIP_TYPE == PN557)
-          || (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer ||
-              PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0])
+#if(NFC_NXP_CHIP_TYPE == PN551)
+              || (PHDNLDNFC_HWVER_PN551_MRA1_0 == bHwVer)|| (PHDNLDNFC_HWVER_PN553_MRA1_0 == bHwVer)
+#else
+              || (((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX)))
+              && (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer))
+              || (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0])
 #endif
               ) {
         bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1;
         (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
-#if (NFC_NXP_CHIP_TYPE == PN553)
-        if (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) {
-          (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0];
+        if ((strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) && (strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX)))
+        {
+            if (PHDNLDNFC_HWVER_PN553_MRA1_0_UPDATED & pRespBuff->pBuff[0]) {
+                (gphNxpNciHal_fw_IoctlCtx.bChipVer) = pRespBuff->pBuff[0];
+            }
         }
-#endif
 
       } else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) &&
                  (bHwVer <= PHDNLDNFC_HWVER_MRA2_0)) {
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
index 1271540..0b85bb2 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.c
+++ b/halimpl/pn54x/hal/phNxpNciHal.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");
@@ -27,6 +30,7 @@
 #include <phNxpNciHal_NfcDepSWPrio.h>
 #include <phNxpNciHal_Kovio.h>
 #include <phTmlNfc_i2c.h>
+#include <cutils/properties.h>
 /*********************** Global Variables *************************************/
 #define PN547C2_CLOCK_SETTING
 #undef PN547C2_FACTORY_RESET_DEBUG
@@ -570,8 +574,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;
@@ -733,8 +737,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(nfc_dev_node, "/dev/nq-nci", max_len);
   }
 
   /* Configure hardware link */
@@ -1808,9 +1812,18 @@
     uint8_t swp_info_buff[2];
     uint8_t swp_intf_status = 0x00;
     uint8_t swp1A_intf_status = 0x00;
+    char nq_chipid[PROPERTY_VALUE_MAX] = {0};
+    int rc = 0;
     NFCSTATUS status = NFCSTATUS_FAILED;
     phNxpNci_EEPROM_info_t swp_intf_info;
 
+    rc = __system_property_get("sys.nfc.nq.chipid", nq_chipid);
+    if (rc <= 0) {
+        NXPLOG_NCIHAL_E("get sys.nfc.nq.chipid fail, rc = %d\n", rc);
+    }
+    else {
+        NXPLOG_NCIHAL_D("sys.nfc.nq.chipid = %s\n", nq_chipid);
+    }
     memset(swp_info_buff, 0, sizeof(swp_info_buff));
     /*Read SWP1 data*/
     memset(&swp_intf_info, 0, sizeof(swp_intf_info));
@@ -1827,20 +1840,22 @@
       goto retry_core_init;
     }
 #if (NFC_NXP_STAT_DUAL_UICC_WO_EXT_SWITCH == true)
-    /*Read SWP1A data*/
-    memset(&swp_intf_info, 0, sizeof(swp_intf_info));
-    swp_intf_info.request_mode = GET_EEPROM_DATA;
-    swp_intf_info.request_type = EEPROM_SWP1A_INTF;
-    swp_intf_info.buffer = &swp1A_intf_status;
-    swp_intf_info.bufflen = sizeof(uint8_t);
-    status = request_EEPROM(&swp_intf_info);
-    if (status == NFCSTATUS_OK)
-      swp_info_buff[1] = swp1A_intf_status;
-    else {
-      NXPLOG_NCIHAL_E("request_EEPROM error occured %d", status);
-      retry_core_init_cnt++;
-      goto retry_core_init;
-    }
+     if ((rc > 0) && (strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX) != 0) && (strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX) != 0)) {
+        /*Read SWP1A data*/
+        memset(&swp_intf_info, 0, sizeof(swp_intf_info));
+        swp_intf_info.request_mode = GET_EEPROM_DATA;
+        swp_intf_info.request_type = EEPROM_SWP1A_INTF;
+        swp_intf_info.buffer = &swp1A_intf_status;
+        swp_intf_info.bufflen = sizeof(uint8_t);
+        status = request_EEPROM(&swp_intf_info);
+        if (status == NFCSTATUS_OK)
+            swp_info_buff[1] = swp1A_intf_status;
+        else {
+            NXPLOG_NCIHAL_E("request_EEPROM error occured %d", status);
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+	}
 #endif
     phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
     mEEPROM_info.buffer = swp_info_buff;
diff --git a/halimpl/pn54x/hal/phNxpNciHal.h b/halimpl/pn54x/hal/phNxpNciHal.h
index 7f1dc30..fe6d183 100644
--- a/halimpl/pn54x/hal/phNxpNciHal.h
+++ b/halimpl/pn54x/hal/phNxpNciHal.h
@@ -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");
@@ -22,7 +25,6 @@
 #ifndef NXP_NFCC_FEATURES_H
 #include <NXP_NFCC_Features.h>
 #endif
-#include "nfc_hal_api.h"
 
 /********************* Definitions and structures *****************************/
 #define MAX_RETRY_COUNT 5
diff --git a/halimpl/pn54x/hal/phNxpNciHal_ext.c b/halimpl/pn54x/hal/phNxpNciHal_ext.c
index 3f43a98..0bc9879 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");
diff --git a/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
index 5a18233..6fb24c3 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,112 @@
 #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;
+}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;
+}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 94f8781..26be34d 100644
--- a/halimpl/pn54x/libnfc-brcm.conf
+++ b/halimpl/pn54x/libnfc-brcm.conf
@@ -354,7 +354,7 @@
 
 ###############################################################################
 # 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
@@ -393,4 +393,4 @@
 ############################################################################## #
 #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
+    DEVICE_HOST_WHITE_LIST={80 : 81 : C0}
diff --git a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
index ac79e7d..8e0e3d9 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
@@ -75,7 +75,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 a58084e..6e309b1 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
@@ -92,10 +92,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
@@ -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,
@@ -254,4 +333,4 @@
 # Enable            0x01
 NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
 
-###############################################################################
+###############################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/libnfc-nxp-PN551_example.conf b/halimpl/pn54x/libnfc-nxp-PN551_example.conf
index 7e060c6..b32791b 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
@@ -92,12 +92,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 }
 
@@ -106,6 +166,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,
@@ -261,4 +340,4 @@
 # Blacklist disable  0x00
 NXP_PROP_BLACKLIST_ROUTING=0x00
 
-###############################################################################
+###############################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/libnfc-nxp-PN553_example.conf b/halimpl/pn54x/libnfc-nxp-PN553_example.conf
index b02b438..5721e91 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
@@ -86,12 +86,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 }
@@ -102,6 +191,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,
@@ -354,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 0269783..5f37cf5 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
@@ -110,7 +110,7 @@
 ## Set configuration optimization decision setting
 ## Enable    = 0x01
 ## Disable   = 0x00
-NXP_SET_CONFIG_ALWAYS=0x00
+NXP_SET_CONFIG_ALWAYS=0x01
 
 ###############################################################################
 # Core configuration extensions
@@ -309,4 +309,4 @@
 #0 = disabling adding aid to NFCC routing table.
 NXP_ENABLE_ADD_AID=0x01
 
-###############################################################################
\ No newline at end of file
+###############################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN66T_example.conf b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
index 5798474..30a6590 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
@@ -92,10 +92,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
@@ -108,6 +173,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,
@@ -335,4 +419,4 @@
 #Disable  0x00
 NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE=0x01
 
-###############################################################################
+###############################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/libnfc-nxp-PN67T_example.conf b/halimpl/pn54x/libnfc-nxp-PN67T_example.conf
index 22499ad..039fb2e 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
@@ -92,12 +92,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 }
@@ -108,6 +173,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,
@@ -346,4 +430,4 @@
 # Blacklist disable  0x00
 NXP_PROP_BLACKLIST_ROUTING=0x00
 
-###############################################################################
+###############################################################################
\ No newline at end of file
diff --git a/halimpl/pn54x/libnfc-nxp-PN80T_example.conf b/halimpl/pn54x/libnfc-nxp-PN80T_example.conf
index e620747..1997e05 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
@@ -85,6 +85,59 @@
 #monitoring 5V from DCDC, 3.3V for both RM and CM, DCDCWaitTime=4.2ms
 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
@@ -93,6 +146,44 @@
 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 +194,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,
@@ -118,12 +228,6 @@
 NXP_DEFAULT_SE=0x07
 
 ###############################################################################
-#set autonomous mode
-# disable autonomous 0x00
-# enable autonomous  0x01
-NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
-
-###############################################################################
 #Enable SWP full power mode when phone is power off
 NXP_SWP_FULL_PWR_ON=0x00
 
@@ -343,11 +447,6 @@
 NXP_CHECK_DEFAULT_PROTO_SE_ID=0x01
 
 ###############################################################################
-# SVDD sync off Delay in ms it can be max 20 ms
-# If out of range timeout used, default delay of 10ms will be set
-NXP_SVDD_SYNC_OFF_DELAY=10
-
-###############################################################################
 #NXP_CN_TRANSIT_BLK_NUM_CHECK_ENABLE
 #Enable/Disable block number checks for china transit use case
 #Enable  0x01
@@ -403,4 +502,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/nfc_nci.c b/halimpl/pn54x/nfc_nci.c
index ed9a2ba..1f389a8 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 43b4920..829620a 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");
@@ -1314,8 +1317,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 8f994d6..180d8a9 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 b7a7533..7a4bc30 100644
--- a/halimpl/pn54x/tml/phTmlNfc_i2c.h
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.h
@@ -42,7 +42,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)
 
 #if (NFC_NXP_ESE == TRUE)
 NFCSTATUS phTmlNfc_i2c_get_p61_power_state(void* pDevHandle);
@@ -60,19 +60,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 7daca6b..9d05904 100644
--- a/halimpl/pn54x/utils/phNxpConfig.cpp
+++ b/halimpl/pn54x/utils/phNxpConfig.cpp
@@ -1,4 +1,6 @@
 /******************************************************************************
+ *  Copyright (c) 2016, 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,270 @@
   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};
+    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, rc = %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, rc = %d\n", rc);
+    else
+        ALOGD("sys.nfc.nq.fwver = %s\n", nq_fw_ver);
+
+    // 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:
+        case TARGET_MSM8909:
+            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:
+            if ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) {
+                // 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 ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) {
+                // 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:
+            if ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) {
+                // 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 ((!strncmp(nq_chipid, NQ220, PROPERTY_VALUE_MAX)) || (!strncmp(nq_chipid, NQ210, PROPERTY_VALUE_MAX))) {
+                // 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 +576,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 +747,7 @@
 *******************************************************************************/
 CNfcConfig::CNfcConfig()
     : mValidFile(true),
+      mDynamConfig(true),
       m_timeStamp(0),
       m_timeStampRF(0),
       m_timeStampTransit(0),
@@ -444,6 +764,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 +791,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;
 }
 
 /*******************************************************************************
@@ -798,6 +1157,7 @@
   }
   return ret;
 }
+
 /*******************************************************************************
 **
 ** Function:    CNfcConfig::updateTimestamp()
diff --git a/halimpl/pn54x/utils/phNxpConfig.h b/halimpl/pn54x/utils/phNxpConfig.h
index d8c34a1..6a8b22e 100644
--- a/halimpl/pn54x/utils/phNxpConfig.h
+++ b/halimpl/pn54x/utils/phNxpConfig.h
@@ -115,6 +115,78 @@
 #if (NXP_ESE_SVDD_SYNC == true)
 #define NAME_NXP_SVDD_SYNC_OFF_DELAY "NXP_SVDD_SYNC_OFF_DELAY"
 #endif
+
+/**
+ *  @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"
 
diff --git a/p61-jcop-kit/Android.mk b/p61-jcop-kit/Android.mk
new file mode 100644
index 0000000..0800002
--- /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 := libp61-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..28af14b
--- /dev/null
+++ b/p61-jcop-kit/README.md
@@ -0,0 +1,21 @@
+# 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 |
diff --git a/p61-jcop-kit/inc/Ala.h b/p61-jcop-kit/inc/Ala.h
new file mode 100644
index 0000000..9ef132e
--- /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 channel_id;
+    bool  isOpend;
+}Ala_ChannelInfo_t;
+
+typedef struct Ala_TranscieveInfo
+{
+    INT32 timeout;
+    UINT8 sRecvData[1024];
+    UINT8 sSendData[1024];
+    INT32 sSendlength;
+    int   sRecvlength;
+    UINT8 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                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                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 OpenChannel[] = {0x00, 0x70, 0x00, 0x00, 0x01};
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+static UINT8 GetData[] = {0x80, 0xCA, 0x00, 0x46, 0x00};
+#ifndef NXP_LS_AID
+static UINT8 SelectAla[] = {0x00, 0xA4, 0x04, 0x00, 0x0D, 0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C, 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
+#else
+static UINT8 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 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 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 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/nfc/AID_MEM.txt"
+#define LS_STATUS_PATH     "/data/nfc/LS_Status.txt"
+#define LS_SRC_BACKUP      "/data/nfc/LS_Src_Backup.txt"
+#define LS_DST_BACKUP      "/data/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.
+**
+*******************************************************************************/
+BOOLEAN 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 *pdata, UINT16 len, UINT8 *respSW);
+#else
+tJBL_STATUS Perform_ALA(const char *path, const UINT8 *pdata, UINT16 len);
+#endif
+tJBL_STATUS GetJsbl_Certificate_Refkey(UINT8 *pkey, INT32 *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 *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* RecvData, INT32 recvlen, Ls_TagType tType);
+
+tJBL_STATUS Check_Certificate_Tag(UINT8 *read_buf, UINT16 *offset1);
+
+tJBL_STATUS Check_SerialNo_Tag(UINT8 *read_buf, UINT16 *offset1);
+
+tJBL_STATUS Check_LSRootID_Tag(UINT8 *read_buf, UINT16 *offset1);
+
+tJBL_STATUS Check_CertHoldID_Tag(UINT8 *read_buf, UINT16 *offset1);
+
+tJBL_STATUS Check_Date_Tag(UINT8 *read_buf, UINT16 *offset1);
+
+tJBL_STATUS Check_45_Tag(UINT8 *read_buf, UINT16 *offset1, UINT8 *tag45Len);
+
+tJBL_STATUS Certificate_Verification(Ala_ImageInfo_t *Os_info, Ala_TranscieveInfo_t
+*pTranscv_Info, UINT8 *read_buf, UINT16 *offset1, UINT8 *tag45Len);
+
+tJBL_STATUS Check_Complete_7F21_Tag(Ala_ImageInfo_t *Os_info,
+       Ala_TranscieveInfo_t *pTranscv_Info, UINT8 *read_buf, UINT16 *offset);
+BOOLEAN ALA_UpdateExeStatus(UINT16 status);
+tJBL_STATUS ALA_getAppletLsStatus(Ala_ImageInfo_t *Os_info, tJBL_STATUS status, Ala_TranscieveInfo_t *pTranscv_Info);
+tJBL_STATUS Get_LsStatus(UINT8 *pVersion);
+tJBL_STATUS Get_LsAppletStatus(UINT8 *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 recvlen, Ala_TranscieveInfo_t *trans_info, Ls_TagType tType);
+#else
+tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, INT32 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* temp_buf, tJBL_STATUS flag,
+   INT32 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 *read_buf);
+
+tJBL_STATUS Process_EseResponse(Ala_TranscieveInfo_t *pTranscv_Info, INT32 recv_len, Ala_ImageInfo_t *Os_info);
+
+tJBL_STATUS Process_SelectRsp(UINT8* Recv_data, INT32 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 Numof_lengthbytes(UINT8 *read_buf, INT32 *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..1db86a1
--- /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 timeout;
+    UINT8 sRecvData[1024];
+    UINT8 *sSendData;
+    INT32 sSendlength;
+    int sRecvlength;
+}JcopOs_TranscieveInfo_t;
+
+typedef struct JcopOs_Version_Info
+{
+    UINT8 osid;
+    UINT8 ver1;
+    UINT8 ver0;
+    UINT8 OtherValid;
+    UINT8 ver_status;
+}JcopOs_Version_Info_t;
+typedef struct JcopOs_ImageInfo
+{
+    FILE *fp;
+    int   fls_size;
+    char  fls_path[256];
+    int   index;
+    UINT8 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 Trigger_APDU[] = {0x4F, 0x70, 0x80, 0x13, 0x04, 0xDE, 0xAD, 0xBE, 0xEF, 0x00};
+static UINT8 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 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/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 *counter);
+tJBL_STATUS SetJcopOsState(JcopOs_ImageInfo_t *Os_info, UINT8 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..f9c29f1
--- /dev/null
+++ b/p61-jcop-kit/inc/data_types.h
@@ -0,0 +1,55 @@
+ /*
+  * 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
+
+#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;
+
+#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 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..fdb047a
--- /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 *pdata, UINT16 len, UINT8 *respSW);
+#else
+unsigned char ALA_Start(const char *name, UINT8 *pdata, UINT16 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 *pVersion);
+unsigned char ALA_lsGetStatus(UINT8 *pVersion);
+unsigned char ALA_lsGetAppletStatus(UINT8 *pVersion);
+#else
+void ALA_GetlistofApplets(char *list[], UINT8* num);
+
+unsigned char ALA_GetCertificateKey(UINT8 *pKey, INT32 *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..7ef6c55
--- /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 (*open)();
+/*******************************************************************************
+**
+** Function:        close
+**
+** Description:     Close the channel.
+**
+** Returns:         True if ok.
+**
+*******************************************************************************/
+bool (*close)(INT16 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* xmitBuffer, INT32 xmitBufferSize, UINT8* recvBuffer,
+                     INT32 recvBufferMaxSize, INT32& recvBufferActualSize, INT32 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..21593a7
--- /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..2a38579
--- /dev/null
+++ b/p61-jcop-kit/src/Ala.cpp
@@ -0,0 +1,3072 @@
+ /*
+  * 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 gTransceiveTimeout;
+#ifdef JCOP3_WR
+UINT8 Cmd_Buffer[64*1024];
+static INT32 cmd_count = 0;
+bool islastcmdLoad;
+bool SendBack_cmds = false;
+UINT8 *pBuffer;
+#endif
+BOOLEAN mIsInit;
+UINT8 Select_Rsp[1024];
+UINT8 Jsbl_RefKey[256];
+UINT8 Jsbl_keylen;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+UINT8 StoreData[22];
+#else
+UINT8 StoreData[34];
+#endif
+int Select_Rsp_Len;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+UINT8 lsVersionArr[2];
+UINT8 tag42Arr[17];
+UINT8 tag45Arr[9];
+UINT8 lsExecuteResp[4];
+UINT8 AID_ARRAY[22];
+INT32 resp_len = 0;
+FILE *fAID_MEM = NULL;
+FILE *fLS_STATUS = NULL;
+UINT8 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.
+**
+*******************************************************************************/
+BOOLEAN 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)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 aidLen = 0x00;
+        INT32 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 *pdata,
+UINT16 len, UINT8 *respSW)
+#else
+tJBL_STATUS Perform_ALA(const char *name, const UINT8 *pdata, UINT16 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 *pKey, INT32 *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)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 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 *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 *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 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 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 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 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);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        Os_info->channel_cnt = 0x00;
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (INT32)sizeof(OpenChannel);
+        pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
+        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 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 recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    UINT8 selectCnt = 3;
+#endif
+    ALOGD("%s: enter", fn);
+
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGD("%s: Invalid parameter", fn);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        pTranscv_Info->sSendData[0] = Os_info->Channel_Info[0].channel_id;
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (INT32)sizeof(SelectAla);
+        pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
+
+#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)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 totalLen = ArrayOfAIDs[selectCnt][0];
+               UINT8 cnt  = 0;
+               INT32 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 recvBufferActualSize = 0;
+    INT32 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);
+        status = STATUS_FAILED;
+    }
+    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)(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";
+    BOOLEAN stat = FALSE;
+    int wResult, size =0;
+    INT32 wIndex,wCount=0;
+    INT32 wLen = 0;
+    INT32 recvBufferActualSize = 0;
+    UINT8 temp_buf[1024];
+    UINT8 len_byte=0, offset =0;
+    ALOGD("%s: enter", fn);
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGE("%s: invalid parameter", fn);
+        return status;
+    }
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    Os_info->bytes_read = 0;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    BOOLEAN 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* temp_buf, tJBL_STATUS flag,
+   INT32 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 offset = 0x00, len_byte=0;
+#else
+    UINT8 offset = 0x00, len_byte=0;
+#endif
+    tJBL_STATUS key_found = STATUS_FAILED;
+    status = STATUS_FAILED;
+    UINT8 read_buf[1024];
+    bool stat = false;
+    INT32 wLen, recvBufferActualSize=0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+#if(NXP_LDR_SVC_VER_2 == TRUE)
+    UINT8 certf_found = STATUS_FAILED;
+    UINT8 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 *read_buf)
+{
+    static const char fn[]="ALA_ReadScript";
+    INT32 wCount, wLen, wIndex = 0;
+    UINT8 len_byte = 0;
+    int wResult = 0;
+    tJBL_STATUS status = STATUS_FAILED;
+    INT32 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 xx=0;
+    status = STATUS_FAILED;
+    INT32 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 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 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 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 xx =0;
+    INT32 recvBufferActualSize = 0;
+    IChannel_t *mchannel = gpAla_Dwnld_Context->mchannel;
+    UINT8 cnt = 0;
+    ALOGD("%s: enter",fn);
+
+    if(Os_info == NULL ||
+       pTranscv_Info == NULL)
+    {
+        ALOGE("Invalid parameter");
+        status = STATUS_FAILED;
+    }
+    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 recvlen, Ala_TranscieveInfo_t *trans_info, Ls_TagType tType)
+#else
+tJBL_STATUS ALA_ProcessResp(Ala_ImageInfo_t *image_info, INT32 recvlen, Ala_TranscieveInfo_t *trans_info)
+#endif
+{
+    static const char fn [] = "ALA_ProcessResp";
+    tJBL_STATUS status = STATUS_FAILED;
+    static INT32 temp_len = 0;
+    UINT8* RecvData = trans_info->sRecvData;
+    UINT8 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 respLen = 0;
+        INT32 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 recv_len, Ala_ImageInfo_t *Os_info)
+{
+    static const char fn[] = "Process_EseResponse";
+    tJBL_STATUS status = STATUS_OK;
+    UINT8 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)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* Recv_data, INT32 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 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 rootEntityLen = 0;
+                    i = i+1;
+                    rootEntityLen = Recv_data[i];
+
+                    i = i+1;
+                    if(Recv_data[i] == TAG_LSRE_ID)
+                    {
+                        UINT8 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 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 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 xx=0;
+    status = STATUS_FAILED;
+    INT32 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 Numof_lengthbytes(UINT8 *read_buf, INT32 *pLen)
+{
+    static const char fn[]= "Numof_lengthbytes";
+    UINT8 len_byte=0, i=0;
+    INT32 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* RecvData,
+    INT32 recvlen, Ls_TagType tType)
+{
+    INT32 respLen       = 0;
+    tJBL_STATUS wStatus = STATUS_FAILED;
+    static const char fn [] = "Write_Response_to_OutFile";
+    INT32 status = 0;
+    UINT8 tagBuffer[12] = {0x61,0,0,0,0,0,0,0,0,0,0,0};
+    INT32 tag44Len = 0;
+    INT32 tag61Len = 0;
+    UINT8 tag43Len = 1;
+    UINT8 tag43off = 0;
+    UINT8 tag44off = 0;
+    UINT8 ucTag44[3] = {0x00,0x00,0x00};
+    UINT8 tagLen = 0;
+    UINT8 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;
+    }
+    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 *read_buf, UINT16 *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT16 len_byte = 0;
+    INT32 wLen, recvBufferActualSize=0;
+    UINT16 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 *read_buf, UINT16 *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT16 offset = *offset1;
+    static const char fn[] = "Check_SerialNo_Tag";
+
+    if((read_buf[offset] == TAG_SERIAL_NO))
+    {
+        ALOGD("TAGID: TAG_SERIAL_NO");
+        UINT8 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 *read_buf, UINT16 *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT16 offset      = *offset1;
+
+    if(read_buf[offset] == TAG_LSRE_ID)
+    {
+        ALOGD("TAGID: TAG_LSROOT_ENTITY");
+        if(tag42Arr[0] == read_buf[offset+1])
+        {
+            UINT8 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 *read_buf, UINT16 *offset1)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT16 offset      = *offset1;
+
+    if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_CERTFHOLD_ID)
+    {
+        UINT8 certfHoldIDLen = 0;
+        ALOGD("TAGID: TAG_CERTFHOLD_ID");
+        certfHoldIDLen = read_buf[offset+2];
+        offset = offset+certfHoldIDLen+3;
+        if(read_buf[offset] == TAG_KEY_USAGE)
+        {
+            UINT8 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 *read_buf, UINT16 *offset1)
+{
+    tJBL_STATUS status = STATUS_OK;
+    UINT16 offset      = *offset1;
+
+    if((read_buf[offset]<<8|read_buf[offset+1]) == TAG_EFF_DATE)
+    {
+        UINT8 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 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 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 *read_buf, UINT16 *offset1, UINT8 *tag45Len)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT16 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 *read_buf, UINT16 *offset1,
+UINT8 *tag45Len)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT16 offset      = *offset1;
+    INT32 wCertfLen = (read_buf[2]<<8|read_buf[3]);
+    tJBL_STATUS certf_found = STATUS_FAILED;
+    static const char fn[] = "Certificate_Verification";
+    UINT8 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 tag7f49Off = 0;
+        UINT8 u7f49Len = 0;
+        UINT8 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 tag53Len = 0;
+            UINT8 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)(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)(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 tag7f49Off = 0;
+        UINT8 u7f49Len = 0;
+        UINT8 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 tag53Len = 0;
+            UINT8 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)(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)(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* 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 *read_buf, UINT16 *offset)
+{
+    static const char fn[] = "Check_Complete_7F21_Tag";
+    UINT8 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 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;
+}
+
+BOOLEAN ALA_UpdateExeStatus(UINT16 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 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);
+        status = STATUS_FAILED;
+    }
+    else
+    {
+        pTranscv_Info->sSendData[0] = STORE_DATA_CLA | Os_info->Channel_Info[0].channel_id;
+        pTranscv_Info->timeout = gTransceiveTimeout;
+        pTranscv_Info->sSendlength = (INT32)sizeof(GetData);
+        pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
+
+
+        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 *pStatus)
+{
+    tJBL_STATUS status = STATUS_FAILED;
+    UINT8 lsStatus[2]    = {0x63,0x40};
+    UINT8 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..6132889
--- /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 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";
+    BOOLEAN 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 *pdata, UINT16 len, UINT8 *respSW)
+#else
+tJBL_STATUS ALA_Start(const char *name, UINT8 *pdata, UINT16 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";
+    BOOLEAN 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* num)
+{
+  static const char dir[] = "/data/ala/";
+  struct dirent *dp;
+  UINT8 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", __FUNCTION__, *num);
+  closedir(fd);
+}
+
+/*******************************************************************************
+**
+** Function:        ALA_GetCertificateKey
+**
+** Description:     Get the JSBL reference key
+**
+** Returns:         TRUE if ok.
+**
+*******************************************************************************/
+tJBL_STATUS ALA_GetCertificateKey(UINT8 *pKey, INT32 *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 *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 *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 *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..32574fe
--- /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 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";
+    BOOLEAN 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;
+    BOOLEAN 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";
+    BOOLEAN 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..4a2035e
--- /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 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/nfc/JcopOs_Update1.apdu",
+                             "/data/nfc/JcopOs_Update2.apdu",
+                             "/data/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)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*)malloc(sizeof(UINT8)*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 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 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 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)sizeof(Trigger_APDU);
+        pTranscv_Info->sRecvlength = 1024;//(INT32)sizeof(INT32);
+        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 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)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 wIndex,wCount=0;
+    INT32 wLen;
+
+    IChannel_t *mchannel = gpJcopOs_Dwnld_Context->channel;
+    INT32 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 *counter)
+{
+    static const char fn [] = "JcopOsDwnld::GetJcopOsState";
+    tJBL_STATUS status = STATUS_SUCCESS;
+    FILE *fp;
+    UINT8 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 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 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/adaptation/NfcAdaptation.cpp b/src/adaptation/NfcAdaptation.cpp
index c202879..9dd148d 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();
@@ -74,9 +63,10 @@
 
 NfcAdaptation* NfcAdaptation::mpInstance = NULL;
 ThreadMutex NfcAdaptation::sLock;
-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;
@@ -398,32 +388,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);
 }
 
 /*******************************************************************************
@@ -539,6 +526,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
@@ -585,7 +580,7 @@
   pInpOutData->inp.context = &NfcAdaptation::GetInstance();
   NfcAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
   data.setToExternal((uint8_t*)pInpOutData, sizeof(nfc_nci_IoctlInOutData_t));
-  mHalNxpNfc->ioctl(arg, data, IoctlCallback);
+  mNqHal->ioctl(arg, data, IoctlCallback);
   ALOGD("%s Ioctl Completed for Type=%llu", func, pInpOutData->out.ioctlType);
   return (pInpOutData->out.result);
 }
@@ -719,6 +714,7 @@
   return nfa_ee_max_ee_cfg;
 }
 
+
 /*******************************************************************************
 **
 ** Function:    NfcAdaptation::DownloadFirmware
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 6fe5edc..174296d 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
  *
@@ -445,7 +447,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
@@ -555,7 +557,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 809e0a3..f941354 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/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..e34e042
--- 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,130 @@
 #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;
+}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
+};
+
 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/include/nfc_types.h b/src/hal/include/nfc_types.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 7d17854..5dad245 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,26 +111,26 @@
   nfc_nci_IoctlInOutData_t* mCurrentIoctlData;
 #endif
 
- private:
-  NfcAdaptation();
-  void signal();
-  static NfcAdaptation* mpInstance;
-  static ThreadMutex sLock;
-  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 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;
+    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;
+#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_api.c b/src/nfa/ce/nfa_ce_api.c
old mode 100755
new mode 100644
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_act.c b/src/nfa/dm/nfa_dm_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_api.c b/src/nfa/dm/nfa_dm_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_cfg.c b/src/nfa/dm/nfa_dm_cfg.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_discover.c b/src/nfa/dm/nfa_dm_discover.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_main.c b/src/nfa/dm/nfa_dm_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 cc730a1..9b2b730 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.
- *
- ******************************************************************************/
 
 /******************************************************************************
  *
@@ -137,16 +123,19 @@
   int xx, yy = 0;
   char buff[100];
 
-  buff[0] = 0;
-  if (aid_len > NFA_MAX_AID_LEN) {
-    NFA_TRACE_ERROR2("aid_len: %d exceeds max(%d)", aid_len, NFA_MAX_AID_LEN);
-    len = NFA_MAX_AID_LEN;
-  }
-  for (xx = 0; xx < len; xx++) {
-    yy += sprintf(&buff[yy], "%02x ", *p);
-    p++;
-  }
-  NFA_TRACE_DEBUG4("%s id:0x%x len=%d aid:%s", p_str, id, aid_len, buff);
+    buff[0] = 0;
+    if (aid_len > NFA_MAX_AID_LEN)
+    {
+        NFA_TRACE_ERROR2 ("aid_len: %d exceeds max(%d)", aid_len, NFA_MAX_AID_LEN);
+        len = NFA_MAX_AID_LEN;
+    }
+    for (xx = 0; xx < len; xx++)
+    {
+        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);
+
 }
 
 /*******************************************************************************
@@ -181,14 +170,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);
@@ -1331,9 +1320,10 @@
         dh_ecb->apdu_rt_info[dh_ecb->apdu_pattern_entries] = NFA_EE_AE_ROUTE | (p_cb->nfcee_id << 8);
         p = dh_ecb->apdu_cfg + apdu_len;
 #else
-        p_cb->apdu_pwr_cfg[p_cb->apdu_pattern_entries] = p_add->power_state;
-        p_cb->apdu_rt_info[p_cb->apdu_pattern_entries] = NFA_EE_AE_ROUTE | (p_cb->nfcee_id << 8);
-        p = p_cb->apdu_cfg + apdu_len;
+            memset(&p_cb->aid_cfg[0],0x00, sizeof(p_cb->aid_cfg));
+            memset(&p_cb->aid_len[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+            memset(&p_cb->aid_pwr_cfg[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+            memset(&p_cb->aid_rt_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
 #endif
 
         p_start = p;
@@ -1347,7 +1337,10 @@
 #if (NXP_EXTNS == TRUE)
         dh_ecb->apdu_len[dh_ecb->apdu_pattern_entries++] = (uint8_t)(p - p_start);
 #else
-        p_cb->apdu_len[p_cb->apdu_pattern_entries++] = (uint8_t)(p - p_start);
+        memset(&p_ecb->aid_cfg[0],0x00, sizeof(p_ecb->aid_cfg));
+        memset(&p_ecb->aid_len[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_ecb->aid_pwr_cfg[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
+        memset(&p_ecb->aid_rt_info[0], 0x00, NFA_EE_MAX_AID_ENTRIES);
 #endif
     }
     else
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 14986e9..c426350
--- a/src/nfa/hci/nfa_hci_act.c
+++ b/src/nfa/hci/nfa_hci_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
  *
@@ -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.
  *
  ******************************************************************************/
@@ -314,7 +300,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
old mode 100755
new mode 100644
index beeb3d3..34f8c71
--- 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
old mode 100755
new mode 100644
index b01abde..4ab90d8
--- 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.
- *
- ******************************************************************************/
 
 /******************************************************************************
  *
@@ -917,7 +903,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
diff --git a/src/nfa/include/nfa_cho_api.h b/src/nfa/include/nfa_cho_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_hci_api.h b/src/nfa/include/nfa_hci_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_hci_defs.h b/src/nfa/include/nfa_hci_defs.h
old mode 100755
new mode 100644
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_cho_int.h b/src/nfa/int/nfa_cho_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_dm_int.h b/src/nfa/int/nfa_dm_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
old mode 100755
new mode 100644
index ce38a1f..0142dfc
--- 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_act.c b/src/nfa/rw/nfa_rw_act.c
old mode 100755
new mode 100644
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/nci_hmsgs.h b/src/nfc/include/nci_hmsgs.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
old mode 100755
new mode 100644
diff --git a/src/nfc/nci/nci_hrcv.c b/src/nfc/nci/nci_hrcv.c
old mode 100755
new mode 100644
diff --git a/src/nfc/ndef/ndef_cho_utils.c b/src/nfc/ndef/ndef_cho_utils.c
old mode 100755
new mode 100644
index de50e25..4acf1c8
--- a/src/nfc/ndef/ndef_cho_utils.c
+++ b/src/nfc/ndef/ndef_cho_utils.c
@@ -1,5 +1,8 @@
 /******************************************************************************
  *
+ *  Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *  Not a Contribution.
+ *
  *  Copyright (C) 2010-2014 Broadcom Corporation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
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_ee.c b/src/nfc/nfc/nfc_ee.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_main.c b/src/nfc/nfc/nfc_main.c
index 90b5fa9..141c337 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.
@@ -62,8 +49,9 @@
 #include "ce_int.h"
 #include "llcp_int.h"
 
-#if (NXP_EXTNS == TRUE)
-extern void nfa_dm_init_cfgs(phNxpNci_getCfg_info_t* mGetCfg_info_main);
+#if(NXP_EXTNS == TRUE)
+static phNxpNci_getCfg_info_t* mGetCfg_info_main = NULL;
+extern void nfa_dm_init_cfgs (phNxpNci_getCfg_info_t* mGetCfg_info_main);
 #endif
 
 /* NFC mandates support for at least one logical connection;
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
index f6abaed..c48ac36 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_task.c b/src/nfc/nfc/nfc_task.c
old mode 100755
new mode 100644
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_utils.c b/src/nfc/nfc/nfc_utils.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);
 }
 
 /*******************************************************************************