Merge "Adding NXP NCI Hal implementation"
diff --git a/halimpl/Android.mk b/halimpl/Android.mk
new file mode 100644
index 0000000..cfd03be
--- /dev/null
+++ b/halimpl/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH:= $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/halimpl/pn54x/Android.mk b/halimpl/pn54x/Android.mk
new file mode 100644
index 0000000..c923a46
--- /dev/null
+++ b/halimpl/pn54x/Android.mk
@@ -0,0 +1,63 @@
+# Copyright (C) 2012-2014 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.
+
+
+# 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_PRELINK_MODULE := false
+LOCAL_ARM_MODE := arm
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_MODULE := nfc_nci.$(TARGET_DEVICE)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := $(call all-c-files-under, .)  $(call all-cpp-files-under, .)
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware_legacy libdl libhardware
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES += \
+    $(LOCAL_PATH)/utils \
+    $(LOCAL_PATH)/inc \
+    $(LOCAL_PATH)/common \
+    $(LOCAL_PATH)/dnld \
+    $(LOCAL_PATH)/hal \
+    $(LOCAL_PATH)/log \
+    $(LOCAL_PATH)/tml \
+    $(LOCAL_PATH)/self-test
+
+#variables for NFC_NXP_CHIP_TYPE
+PN547C2 := 1
+PN548C2 := 2
+
+ifeq ($(PN547C2),1)
+LOCAL_CFLAGS += -DPN547C2=1
+endif
+ifeq ($(PN548C2),2)
+LOCAL_CFLAGS += -DPN548C2=2
+endif
+
+#### Select the CHIP ####
+LOCAL_CFLAGS += -DNFC_NXP_CHIP_TYPE=PN548C2
+
+LOCAL_CFLAGS += -DANDROID \
+        -DNXP_UICC_ENABLE -DNXP_HW_SELF_TEST
+LOCAL_CFLAGS += -DNFC_NXP_HFO_SETTINGS=FALSE
+#LOCAL_CFLAGS += -DFELICA_CLT_ENABLE
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/halimpl/pn54x/common/phNfcCommon.h b/halimpl/pn54x/common/phNfcCommon.h
new file mode 100644
index 0000000..8e040d4
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcCommon.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ *  OSAL header files related to memory, debug, random, semaphore and mutex functions.
+ */
+
+#ifndef PHNFCCOMMON_H
+#define PHNFCCOMMON_H
+
+/*
+************************* Include Files ****************************************
+*/
+
+#include <phNfcStatus.h>
+#include <semaphore.h>
+#include <phOsalNfc_Timer.h>
+#include <pthread.h>
+#include <phDal4Nfc_messageQueueLib.h>
+#include <phNfcCompId.h>
+
+
+#   define FW_DLL_ROOT_DIR "/system/vendor/firmware/"
+#   define FW_DLL_EXTENSION ".so"
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+
+/* Actual FW library name*/
+#define FW_LIB_PATH       FW_DLL_ROOT_DIR "libpn548ad_fw"          FW_DLL_EXTENSION
+/* Restore Currupted PLL Setttings/etc */
+#define PLATFORM_LIB_PATH FW_DLL_ROOT_DIR "libpn548ad_fw_platform" FW_DLL_EXTENSION
+/* Upgrade the public Key */
+#define PKU_LIB_PATH      FW_DLL_ROOT_DIR "libpn548ad_fw_pku"      FW_DLL_EXTENSION
+#else
+/* Actual FW library name*/
+#define FW_LIB_PATH       FW_DLL_ROOT_DIR "libpn547_fw"          FW_DLL_EXTENSION
+/* Restore Currupted PLL Setttings/etc */
+#define PLATFORM_LIB_PATH FW_DLL_ROOT_DIR "libpn547_fw_platform" FW_DLL_EXTENSION
+/* Upgrade the public Key */
+#define PKU_LIB_PATH      FW_DLL_ROOT_DIR "libpn547_fw_pku"      FW_DLL_EXTENSION
+#endif
+
+/* HAL Version number (Updated as per release) */
+#define NXP_MW_VERSION_MAJ  (1U)
+#define NXP_MW_VERSION_MIN  (0U)
+
+/*
+ *****************************************************************
+ ***********  System clock source selection configuration ********
+ *****************************************************************
+ */
+
+#define CLK_SRC_UNDEF      0
+#define CLK_SRC_XTAL       1
+#define CLK_SRC_PLL        2
+#define CLK_SRC_PADDIRECT  3
+
+/*Extern crystal clock source*/
+#define NXP_SYS_CLK_SRC_SEL         CLK_SRC_PLL  /* Use one of CLK_SRC_<value> */
+/*Direct clock*/
+
+/*
+ *****************************************************************
+ ***********  System clock frequency selection configuration ****************
+ * If Clk_Src is set to PLL, make sure to set the Clk_Freq also*
+ *****************************************************************
+ */
+#define CLK_FREQ_UNDEF         0
+#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
+
+#define NXP_SYS_CLK_FREQ_SEL  CLK_FREQ_19_2MHZ /* Set to one of CLK_FREQ_<value> */
+
+#define CLK_TO_CFG_DEF         1
+#define CLK_TO_CFG_MAX         26
+/*
+ *  information to configure OSAL
+ */
+typedef struct phOsalNfc_Config
+{
+    uint8_t *pLogFile; /* Log File Name*/
+    uintptr_t dwCallbackThreadId; /* Client ID to which message is posted */
+}phOsalNfc_Config_t, *pphOsalNfc_Config_t /* Pointer to #phOsalNfc_Config_t */;
+
+
+/*
+ * Deferred call declaration.
+ * This type of API is called from ClientApplication (main thread) to notify
+ * specific callback.
+ */
+typedef  void (*pphOsalNfc_DeferFuncPointer_t) (void*);
+
+
+/*
+ * Deferred message specific info declaration.
+ */
+typedef struct phOsalNfc_DeferedCallInfo
+{
+        pphOsalNfc_DeferFuncPointer_t   pDeferedCall;/* pointer to Deferred callback */
+        void                            *pParam;    /* contains timer message specific details*/
+}phOsalNfc_DeferedCallInfo_t;
+
+
+/*
+ * States in which a OSAL timer exist.
+ */
+typedef enum
+{
+    eTimerIdle = 0,         /* Indicates Initial state of timer */
+    eTimerRunning = 1,      /* Indicate timer state when started */
+    eTimerStopped = 2       /* Indicates timer state when stopped */
+}phOsalNfc_TimerStates_t;   /* Variable representing State of timer */
+
+/*
+ **Timer Handle structure containing details of a timer.
+ */
+typedef struct phOsalNfc_TimerHandle
+{
+    uint32_t TimerId;                                   /* ID of the timer */
+    timer_t hTimerHandle;                               /* Handle of the timer */
+    pphOsalNfc_TimerCallbck_t   Application_callback;   /* Timer callback function to be invoked */
+    void *pContext;                                     /* Parameter to be passed to the callback function */
+    phOsalNfc_TimerStates_t eState;                     /* Timer states */
+    phLibNfc_Message_t tOsalMessage;                    /* Osal Timer message posted on User Thread */
+    phOsalNfc_DeferedCallInfo_t tDeferedCallInfo;       /* Deferred Call structure to Invoke Callback function */
+}phOsalNfc_TimerHandle_t,*pphOsalNfc_TimerHandle_t;     /* Variables for Structure Instance and Structure Ptr */
+
+#endif /*  PHOSALNFC_H  */
diff --git a/halimpl/pn54x/common/phNfcCompId.h b/halimpl/pn54x/common/phNfcCompId.h
new file mode 100644
index 0000000..f88fbb4
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcCompId.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * NFC Component ID Values - Used for Function Return Codes
+ */
+
+#ifndef PHNFCCOMPID_H
+#define PHNFCCOMPID_H
+
+/*
+ *  Component IDs
+ *
+ *  IDs for all NFC components. Combined with the Status Code they build the value (status)
+ *  returned by each function.
+ *
+ *  ID Number Spaces:
+ *  - 01..1F: HAL
+ *  - 20..3F: NFC-MW (Local Device)
+ *  - 40..5F: NFC-MW (Remote Device)
+ *  .
+ *
+ *         The value CID_NFC_NONE does not exist for Component IDs. Do not use this value except
+ *         for NFCSTATUS_SUCCESS. The enumeration function uses CID_NFC_NONE
+ *         to mark unassigned "References".
+ */
+#define CID_NFC_NONE                    0x00    /* Unassigned or doesn't apply (see #NFCSTATUS_SUCCESS) */
+#define CID_NFC_TML                     0x01    /* Transport Mapping Layer */
+#define CID_NFC_LLC                     0x07    /* Logical Link Control Layer */
+#define CID_NFC_NCI                     0x08    /* NFC Controller(NFCC) Interface Layer */
+#define CID_NFC_DNLD                    0x09    /* Firmware Download Management Layer */
+#define CID_NFC_HAL                     0x10    /* Hardware Abstraction Layer */
+#define CID_NFC_OSAL                    CID_NFC_NONE  /* Operating System Abstraction Layer*/
+#define CID_FRI_NFC_OVR_HAL             0x20    /* NFC-Device, HAL-based */
+#define CID_FRI_NFC_NDEF_RECORD         0x22    /* NDEF Record Tools Library. */
+#define CID_FRI_NFC_NDEF_MAP            0x23    /* NDEF Mapping. */
+#define CID_FRI_NFC_NDEF_REGISTRY       0x24    /* NDEF_REGISTRY. */
+#define CID_FRI_NFC_AUTO_DEV_DIS        0x25    /* Automatic Device Discovery. */
+#define CID_FRI_NFC_NDEF_SMTCRDFMT      0x26    /* Smart Card Formatting */
+#define CID_NFC_LIB                     0x30    /* NFC Library Layer*/
+#define CID_MAX_VALUE                   0xF0    /* The maximum CID value that is defined. */
+#define CID_FRI_NFC_LLCP                0x40    /* Logical Link Control Protocol */
+#define CID_FRI_NFC_LLCP_TRANSPORT      0x50
+#define CID_FRI_NFC_LLCP_MAC            0x60
+
+#endif /* PHNFCCOMPID_H */
diff --git a/halimpl/pn54x/common/phNfcStatus.h b/halimpl/pn54x/common/phNfcStatus.h
new file mode 100644
index 0000000..fb1d818
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcStatus.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * NFC Status Values - Function Return Codes
+ */
+
+#ifndef PHNFCSTATUS_H
+#define PHNFCSTATUS_H
+
+#include <phNfcTypes.h>
+
+/* Internally required by PHNFCSTVAL. */
+#define PHNFCSTSHL8                          (8U)
+/* Required by PHNFCSTVAL. */
+#define PHNFCSTBLOWER                        ((NFCSTATUS)(0x00FFU))
+
+/*
+ *  NFC Status Composition Macro
+ *
+ *  This is the macro which must be used to compose status values.
+ *
+ *  phNfcCompID Component ID, as defined in phNfcCompId.h .
+ *  phNfcStatus Status values, as defined in phNfcStatus.h .
+ *
+ *  The macro is not required for the NFCSTATUS_SUCCESS value.
+ *  This is the only return value to be used directly.
+ *  For all other values it shall be used in assignment and conditional statements, e.g.:
+ *     NFCSTATUS status = PHNFCSTVAL(phNfcCompID, phNfcStatus); ...
+ *     if (status == PHNFCSTVAL(phNfcCompID, phNfcStatus)) ...
+ */
+#define PHNFCSTVAL(phNfcCompID, phNfcStatus)                                  \
+            ( ((phNfcStatus) == (NFCSTATUS_SUCCESS)) ? (NFCSTATUS_SUCCESS) :  \
+                ( (((NFCSTATUS)(phNfcStatus)) & (PHNFCSTBLOWER)) |            \
+                    (((uint16_t)(phNfcCompID)) << (PHNFCSTSHL8)) ) )
+
+/*
+ * PHNFCSTATUS
+ * Get grp_retval from Status Code
+ */
+#define PHNFCSTATUS(phNfcStatus)  ((phNfcStatus) & 0x00FFU)
+#define PHNFCCID(phNfcStatus)  (((phNfcStatus) & 0xFF00U)>>8)
+
+#define PHNFC_I2C_FRAGMENT_SIZE       512
+/*
+ *  Status Codes
+ *
+ *  Generic Status codes for the NFC components. Combined with the Component ID
+ *  they build the value (status) returned by each function.
+ *  Example:
+ *      grp_comp_id "Component ID" -  e.g. 0x10, plus
+ *      status code as listed in this file - e.g. 0x03
+ *      result in a status value of 0x0003.
+ */
+
+/*
+ * The function indicates successful completion
+ */
+#define NFCSTATUS_SUCCESS                                     (0x0000)
+
+/*
+ *  The function indicates successful completion
+ */
+#define NFCSTATUS_OK                                (NFCSTATUS_SUCCESS)
+
+/*
+ * At least one parameter could not be properly interpreted
+ */
+#define NFCSTATUS_INVALID_PARAMETER                           (0x0001)
+
+/*
+ * The buffer provided by the caller is too small
+ */
+#define NFCSTATUS_BUFFER_TOO_SMALL                            (0x0003)
+
+/*
+ * Device specifier/handle value is invalid for the operation
+ */
+#define NFCSTATUS_INVALID_DEVICE                              (0x0006)
+
+/*
+ * The function executed successfully but could have returned
+ * more information than space provided by the caller
+ */
+#define NFCSTATUS_MORE_INFORMATION                            (0x0008)
+
+/*
+ * No response from the remote device received: Time-out
+ */
+#define NFCSTATUS_RF_TIMEOUT                                  (0x0009)
+
+/*
+ * RF Error during data transaction with the remote device
+ */
+#define NFCSTATUS_RF_ERROR                                    (0x000A)
+
+/*
+ * Not enough resources Memory, Timer etc(e.g. allocation failed.)
+ */
+#define NFCSTATUS_INSUFFICIENT_RESOURCES                      (0x000C)
+
+/*
+ * A non-blocking function returns this immediately to indicate
+ * that an internal operation is in progress
+ */
+#define NFCSTATUS_PENDING                                     (0x000D)
+
+/*
+ * A board communication error occurred
+ * (e.g. Configuration went wrong)
+ */
+#define NFCSTATUS_BOARD_COMMUNICATION_ERROR                   (0x000F)
+
+/*
+ * Invalid State of the particular state machine
+ */
+#define NFCSTATUS_INVALID_STATE                               (0x0011)
+
+
+/*
+ * This Layer is Not initialized, hence initialization required.
+ */
+#define NFCSTATUS_NOT_INITIALISED                             (0x0031)
+
+
+/*
+ * The Layer is already initialized, hence initialization repeated.
+ */
+#define NFCSTATUS_ALREADY_INITIALISED                         (0x0032)
+
+
+/*
+ * Feature not supported
+ */
+#define NFCSTATUS_FEATURE_NOT_SUPPORTED                       (0x0033)
+
+/*  The Unregistration command has failed because the user wants to unregister on
+ * an element for which he was not registered
+ */
+#define NFCSTATUS_NOT_REGISTERED                              (0x0034)
+
+
+/* The Registration command has failed because the user wants to register on
+ * an element for which he is already registered
+ */
+#define NFCSTATUS_ALREADY_REGISTERED                          (0x0035)
+
+/*  Single Tag with Multiple
+    Protocol support detected */
+#define NFCSTATUS_MULTIPLE_PROTOCOLS                          (0x0036)
+
+/*
+ * Feature not supported
+ */
+#define NFCSTATUS_MULTIPLE_TAGS                               (0x0037)
+
+/*
+ * A DESELECT event has occurred
+ */
+#define NFCSTATUS_DESELECTED                                  (0x0038)
+
+/*
+ * A RELEASE event has occurred
+ */
+#define NFCSTATUS_RELEASED                                    (0x0039)
+
+/*
+ * The operation is currently not possible or not allowed
+ */
+#define NFCSTATUS_NOT_ALLOWED                                 (0x003A)
+
+/*
+ *  The system is busy with the previous operation.
+ */
+#define NFCSTATUS_BUSY                                        (0x006F)
+
+
+/* NDEF Mapping error codes */
+
+/* The remote device (type) is not valid for this request. */
+#define NFCSTATUS_INVALID_REMOTE_DEVICE                       (0x001D)
+
+/* Read operation failed */
+#define NFCSTATUS_READ_FAILED                                 (0x0014)
+
+/*
+ * Write operation failed
+ */
+#define NFCSTATUS_WRITE_FAILED                                (0x0015)
+
+/* Non Ndef Compliant */
+#define NFCSTATUS_NO_NDEF_SUPPORT                             (0x0016)
+
+/* Could not proceed further with the write operation: reached card EOF*/
+#define NFCSTATUS_EOF_NDEF_CONTAINER_REACHED                  (0x001A)
+
+/* Incorrect number of bytes received from the card*/
+#define NFCSTATUS_INVALID_RECEIVE_LENGTH                      (0x001B)
+
+/* The data format/composition is not understood/correct. */
+#define NFCSTATUS_INVALID_FORMAT                              (0x001C)
+
+
+/* There is not sufficient storage available. */
+#define NFCSTATUS_INSUFFICIENT_STORAGE                        (0x001F)
+
+/* The Ndef Format procedure has failed. */
+#define NFCSTATUS_FORMAT_ERROR                                (0x0023)
+
+/* The NCI Cedit error */
+#define NFCSTATUS_CREDIT_TIMEOUT                              (0x0024)
+
+/*
+ * Response Time out for the control message(NFCC not responded)
+ */
+#define NFCSTATUS_RESPONSE_TIMEOUT                            (0x0025)
+
+/*
+ * Device is already connected
+ */
+#define NFCSTATUS_ALREADY_CONNECTED                           (0x0026)
+
+/*
+ * Device is already connected
+ */
+#define NFCSTATUS_ANOTHER_DEVICE_CONNECTED                    (0x0027)
+
+/*
+ * Single Target Detected and Activated
+ */
+#define NFCSTATUS_SINGLE_TAG_ACTIVATED                        (0x0028)
+
+/*
+ * Single Target Detected
+ */
+#define NFCSTATUS_SINGLE_TAG_DISCOVERED                       (0x0029)
+
+/*
+ * Secure element Detected and Activated
+ */
+#define NFCSTATUS_SECURE_ELEMENT_ACTIVATED                    (0x0028)
+
+/*
+ * Unknown error Status Codes
+ */
+#define NFCSTATUS_UNKNOWN_ERROR                               (0x00FE)
+
+/*
+ * Status code for failure
+ */
+#define NFCSTATUS_FAILED                                      (0x00FF)
+
+/*
+ * The function/command has been aborted
+ */
+#define NFCSTATUS_CMD_ABORTED                                 (0x0002)
+
+/*
+ * No target found after poll
+ */
+#define NFCSTATUS_NO_TARGET_FOUND                             (0x000A)
+
+/* Attempt to disconnect a not connected remote device. */
+#define NFCSTATUS_NO_DEVICE_CONNECTED                         (0x000B)
+
+/* External RF field detected. */
+#define NFCSTATUS_EXTERNAL_RF_DETECTED                        (0x000E)
+
+/* Message is not allowed by the state machine
+ * (e.g. configuration went wrong)
+ */
+#define NFCSTATUS_MSG_NOT_ALLOWED_BY_FSM                      (0x0010)
+
+/*
+ * No access has been granted
+ */
+#define NFCSTATUS_ACCESS_DENIED                               (0x001E)
+
+/* No registry node matches the specified input data. */
+#define NFCSTATUS_NODE_NOT_FOUND                              (0x0017)
+
+/* The current module is busy ; one might retry later */
+#define NFCSTATUS_SMX_BAD_STATE                               (0x00F0)
+
+
+/* The Abort mechanism has failed for unexpected reason: user can try again*/
+#define NFCSTATUS_ABORT_FAILED                                (0x00F2)
+
+
+/* The Registration command has failed because the user wants to register as target
+ * on a operating mode not supported
+ */
+#define NFCSTATUS_REG_OPMODE_NOT_SUPPORTED                    (0x00F5)
+
+/*
+ * Shutdown in progress, cannot handle the request at this time.
+ */
+#define NFCSTATUS_SHUTDOWN                  (0x0091)
+
+/*
+ * Target is no more in RF field
+ */
+#define NFCSTATUS_TARGET_LOST               (0x0092)
+
+/*
+ * Request is rejected
+ */
+#define NFCSTATUS_REJECTED                  (0x0093)
+
+/*
+ * Target is not connected
+ */
+#define NFCSTATUS_TARGET_NOT_CONNECTED      (0x0094)
+
+/*
+ * Invalid handle for the operation
+ */
+#define NFCSTATUS_INVALID_HANDLE            (0x0095)
+
+/*
+ * Process aborted
+ */
+#define NFCSTATUS_ABORTED                   (0x0096)
+
+/*
+ * Requested command is not supported
+ */
+#define NFCSTATUS_COMMAND_NOT_SUPPORTED     (0x0097)
+
+/*
+ * Tag is not NDEF compilant
+ */
+#define NFCSTATUS_NON_NDEF_COMPLIANT        (0x0098)
+
+/*
+ * Not enough memory available to complete the requested operation
+ */
+#define NFCSTATUS_NOT_ENOUGH_MEMORY         (0x001F)
+
+/*
+ * Indicates incoming connection
+ */
+#define NFCSTATUS_INCOMING_CONNECTION        (0x0045)
+
+/*
+ * Indicates Connection was successful
+ */
+#define NFCSTATUS_CONNECTION_SUCCESS         (0x0046)
+
+/*
+ * Indicates Connection failed
+ */
+#define NFCSTATUS_CONNECTION_FAILED          (0x0047)
+
+#endif /* PHNFCSTATUS_H */
diff --git a/halimpl/pn54x/common/phNfcTypes.h b/halimpl/pn54x/common/phNfcTypes.h
new file mode 100644
index 0000000..1e2fe9f
--- /dev/null
+++ b/halimpl/pn54x/common/phNfcTypes.h
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2010-2014 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 PHNFCTYPES_H
+#define PHNFCTYPES_H
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifndef TRUE
+#define TRUE            (0x01)            /* Logical True Value */
+#endif
+#ifndef FALSE
+#define FALSE           (0x00)            /* Logical False Value */
+#endif
+typedef uint8_t             utf8_t;       /* UTF8 Character String */
+typedef uint8_t             bool_t;       /* boolean data type */
+typedef uint16_t        NFCSTATUS;        /* Return values */
+#define STATIC static
+
+#define PHNFC_MAX_UID_LENGTH            0x0AU  /* Maximum UID length expected */
+#define PHNFC_MAX_ATR_LENGTH            0x30U  /* Maximum ATR_RES (General Bytes) length expected */
+#define PHNFC_NFCID_LENGTH              0x0AU  /* Maximum length of NFCID 1.3*/
+#define PHNFC_ATQA_LENGTH               0x02U  /* ATQA length */
+
+/*
+ * NFC Data structure
+ */
+typedef struct phNfc_sData
+{
+    uint8_t             *buffer; /* Buffer to store data */
+    uint32_t            length;  /* Buffer length */
+} phNfc_sData_t;
+
+/*
+ * Possible Hardware Configuration exposed to upper layer.
+ * Typically this should be port name (Ex:"COM1","COM2") to which PN54X is connected.
+ */
+typedef enum
+{
+   ENUM_LINK_TYPE_COM1,
+   ENUM_LINK_TYPE_COM2,
+   ENUM_LINK_TYPE_COM3,
+   ENUM_LINK_TYPE_COM4,
+   ENUM_LINK_TYPE_COM5,
+   ENUM_LINK_TYPE_COM6,
+   ENUM_LINK_TYPE_COM7,
+   ENUM_LINK_TYPE_COM8,
+   ENUM_LINK_TYPE_I2C,
+   ENUM_LINK_TYPE_SPI,
+   ENUM_LINK_TYPE_USB,
+   ENUM_LINK_TYPE_TCP,
+   ENUM_LINK_TYPE_NB
+} phLibNfc_eConfigLinkType;
+
+/*
+ * Deferred message. This message type will be posted to the client application thread
+ * to notify that a deferred call must be invoked.
+ */
+#define PH_LIBNFC_DEFERREDCALL_MSG        (0x311)
+
+/*
+ * Deferred call declaration.
+ * This type of API is called from ClientApplication ( main thread) to notify
+ * specific callback.
+ */
+typedef  void (*pphLibNfc_DeferredCallback_t) (void*);
+
+/*
+ * Deferred parameter declaration.
+ * This type of data is passed as parameter from ClientApplication (main thread) to the
+ * callback.
+ */
+typedef  void *pphLibNfc_DeferredParameter_t;
+
+/*
+ * Possible Hardware Configuration exposed to upper layer.
+ * Typically this should be at least the communication link (Ex:"COM1","COM2")
+ * the controller is connected to.
+ */
+typedef struct phLibNfc_sConfig
+{
+   uint8_t                 *pLogFile; /* Log File Name*/
+   /* Hardware communication link to the controller */
+   phLibNfc_eConfigLinkType  nLinkType;
+   /* The client ID (thread ID or message queue ID) */
+   uintptr_t              nClientId;
+} phLibNfc_sConfig_t, *pphLibNfc_sConfig_t;
+
+/*
+ * NFC Message structure contains message specific details like
+ * message type, message specific data block details, etc.
+ */
+typedef struct phLibNfc_Message
+{
+    uint32_t eMsgType;   /* Type of the message to be posted*/
+    void   * pMsgData;   /* Pointer to message specific data block in case any*/
+    uint32_t Size;       /* Size of the datablock*/
+} phLibNfc_Message_t,*pphLibNfc_Message_t;
+
+/*
+ * Deferred message specific info declaration.
+ * This type of information is packed as message data when PH_LIBNFC_DEFERREDCALL_MSG
+ * type message is posted to message handler thread.
+ */
+typedef struct phLibNfc_DeferredCall
+{
+    pphLibNfc_DeferredCallback_t pCallback;/* pointer to Deferred callback */
+    pphLibNfc_DeferredParameter_t pParameter;/* pointer to Deferred parameter */
+} phLibNfc_DeferredCall_t;
+
+/*
+ * Definitions for supported protocol
+ */
+typedef struct phNfc_sSupProtocol
+{
+    unsigned int MifareUL    : 1;  /* Protocol Mifare Ultra Light or any NFC Forum Type-2 tags */
+    unsigned int MifareStd   : 1;  /* Protocol Mifare Standard. */
+    unsigned int ISO14443_4A : 1;  /* Protocol ISO14443-4 Type A.  */
+    unsigned int ISO14443_4B : 1;  /* Protocol ISO14443-4 Type B.  */
+    unsigned int ISO15693    : 1;  /* Protocol ISO15693 HiTag.  */
+    unsigned int Felica      : 1;  /* Protocol Felica. */
+    unsigned int NFC         : 1;  /* Protocol NFC. */
+    unsigned int Jewel       : 1;  /* Protocol Innovision Jewel Tag. or Any T1T*/
+    unsigned int Desfire     : 1;  /*TRUE indicates specified feature (mapping
+                                   or formatting)for DESFire tag supported else not supported.*/
+    unsigned int Kovio       : 1;   /* Protocol Kovio Tag*/
+    unsigned int HID         : 1;   /* Protocol HID(Picopass) Tag*/
+    unsigned int Bprime      : 1;   /* Protocol BPrime Tag*/
+    unsigned int EPCGEN2     : 1;   /* Protocol EPCGEN2 Tag*/
+}phNfc_sSupProtocol_t;
+
+/*
+ *  Enumerated MIFARE Commands
+ */
+
+typedef enum phNfc_eMifareCmdList
+{
+    phNfc_eMifareRaw        = 0x00U,     /* This command performs raw transcations */
+    phNfc_eMifareAuthentA   = 0x60U,     /* This command performs an authentication with KEY A for a sector. */
+    phNfc_eMifareAuthentB   = 0x61U,     /* This command performs an authentication with KEY B for a sector. */
+    phNfc_eMifareRead16     = 0x30U,     /* Read 16 Bytes from a Mifare Standard block */
+    phNfc_eMifareRead       = 0x30U,     /* Read Mifare Standard */
+    phNfc_eMifareWrite16    = 0xA0U,     /* Write 16 Bytes to a Mifare Standard block */
+    phNfc_eMifareWrite4     = 0xA2U,     /* Write 4 bytes. */
+    phNfc_eMifareInc        = 0xC1U,     /* Increment */
+    phNfc_eMifareDec        = 0xC0U,     /* Decrement */
+    phNfc_eMifareTransfer   = 0xB0U,     /* Transfer */
+    phNfc_eMifareRestore    = 0xC2U,     /* Restore.   */
+    phNfc_eMifareReadSector = 0x38U,     /* Read Sector.   */
+    phNfc_eMifareWriteSector= 0xA8U,     /* Write Sector.   */
+    /* Above commands could be used for preparing raw command but below one can not be */
+    phNfc_eMifareReadN      = 0x01,      /* Proprietary Command */
+    phNfc_eMifareWriteN     = 0x02,      /* Proprietary Command */
+    phNfc_eMifareSectorSel  = 0x03,      /* Proprietary Command */
+    phNfc_eMifareAuth       = 0x04,      /* Proprietary Command */
+    phNfc_eMifareProxCheck  = 0x05,      /* Proprietary Command */
+    phNfc_eMifareInvalidCmd = 0xFFU      /* Invalid Command */
+} phNfc_eMifareCmdList_t;
+
+/*
+ * Information about ISO14443A
+ */
+typedef struct phNfc_sIso14443AInfo
+{
+    uint8_t         Uid[PHNFC_MAX_UID_LENGTH];      /* UID information of the TYPE A
+                                                     * Tag Discovered */
+    uint8_t         UidLength;                      /* UID information length */
+    uint8_t         AppData[PHNFC_MAX_ATR_LENGTH];  /* Application data information of the
+                              1                      * tag discovered (= Historical bytes for
+                                                     * type A) */
+    uint8_t         AppDataLength;                  /* Application data length */
+    uint8_t         Sak;                            /* SAK information of the TYPE A
+                                                     * Tag Discovered */
+    uint8_t         AtqA[PHNFC_ATQA_LENGTH];        /* ATQA informationof the TYPE A
+                                                     * Tag Discovered */
+    uint8_t         MaxDataRate;                    /* Maximum data rate supported
+                                                     * by the tag Discovered */
+    uint8_t         Fwi_Sfgt;                       /* Frame waiting time and start up
+                                                     * frame guard */
+}phNfc_sIso14443AInfo_t;
+
+/* Remote device information structure */
+typedef union phNfc_uRemoteDevInfo
+{
+    phNfc_sIso14443AInfo_t          Iso14443A_Info;/* ISO1443A Remote device info */
+}phNfc_uRemoteDevInfo_t;
+
+/*
+*
+*  The RF Device Type List is used to identify the type of
+*  remote device that is discovered and connected.
+*
+*/
+
+typedef enum phNfc_eRFDevType
+{
+    phNfc_eUnknown_DevType        = 0x00U,
+
+    phNfc_eISO14443_A_PCD,
+    phNfc_eISO14443_B_PCD,
+    phNfc_eISO14443_BPrime_PCD,
+    phNfc_eFelica_PCD,
+    phNfc_eJewel_PCD,
+    phNfc_eISO15693_PCD,
+    phNfc_eEpcGen2_PCD,
+    phNfc_ePCD_DevType,
+
+    phNfc_ePICC_DevType,
+    phNfc_eISO14443_A_PICC,
+    phNfc_eISO14443_4A_PICC,
+    phNfc_eISO14443_3A_PICC,
+    phNfc_eMifare_PICC,
+    phNfc_eISO14443_B_PICC,
+    phNfc_eISO14443_4B_PICC,
+    phNfc_eISO14443_BPrime_PICC,
+    phNfc_eFelica_PICC,
+    phNfc_eJewel_PICC,
+    phNfc_eISO15693_PICC,
+    phNfc_eEpcGen2_PICC,
+
+    phNfc_eNfcIP1_Target,
+    phNfc_eNfcIP1_Initiator,
+
+    phNfc_eInvalid_DevType
+
+}phNfc_eRFDevType_t;
+
+/*
+ * The Remote Device Type List is used to identify the type of
+ * remote device that is discovered/connected
+ */
+typedef phNfc_eRFDevType_t phNfc_eRemDevType_t;
+typedef phNfc_eRemDevType_t phHal_eRemDevType_t;
+
+/*
+ *   Union for each available type of Commands.
+ */
+
+typedef union phNfc_uCommand
+{
+  phNfc_eMifareCmdList_t         MfCmd;  /* Mifare command structure.  */
+}phNfc_uCmdList_t;
+
+/*
+ *  The Remote Device Information Structure holds information about one single Remote
+ *  Device detected.
+ */
+typedef struct phNfc_sRemoteDevInformation
+{
+    uint8_t                    SessionOpened;       /* Flag indicating the validity of
+                                                     * the handle of the remote device.
+                                                     * 1 = Device is not activer (Only discovered), 2 = Device is active and ready for use*/
+    phNfc_eRemDevType_t        RemDevType;          /* Remote device type */
+    phNfc_uRemoteDevInfo_t     RemoteDevInfo;       /* Union of available Remote Device */
+}phNfc_sRemoteDevInformation_t;
+
+
+/*
+ * Transceive Information Data Structure for sending commands/response to the remote device
+ */
+
+typedef struct phNfc_sTransceiveInfo
+{
+    phNfc_uCmdList_t                cmd;        /* Command for transceive */
+    uint8_t                         addr;       /* Start Block Number */
+    uint8_t                         NumBlock;   /* Number of Blocks to perform operation */
+    /* For Felica only*/
+    uint16_t *ServiceCodeList;                  /* 2 Byte service Code List */
+    uint16_t *Blocklist;                        /* 2 Byte Block list */
+    phNfc_sData_t                   sSendData; /* Send data */
+    phNfc_sData_t                   sRecvData; /* Recv data */
+    /* For EPC-GEN */
+    uint32_t                        dwWordPtr;   /* Word address for the memory write */
+    uint8_t                         bWordPtrLen; /* Specifies the length of word pointer
+                                                 00: 8  bits
+                                                 01: 16 bits
+                                                 10: 24 bits
+                                                 11: 32 bits
+                                                 */
+    uint8_t                        bWordCount;   /* Number of words to be read or written */
+}phNfc_sTransceiveInfo_t;
+
+#define UNUSED(X) (void)X;
+
+#endif /* PHNFCTYPES_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc.c b/halimpl/pn54x/dnld/phDnldNfc.c
new file mode 100644
index 0000000..512b186
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc.c
@@ -0,0 +1,1360 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+
+/*
+ * Download Component
+ * Download Interface routines implementation
+ */
+
+#include <phDnldNfc_Internal.h>
+#include <phTmlNfc.h>
+#include <phNxpLog.h>
+#include <dlfcn.h>
+
+static void *pFwLibHandle; /* Global firmware lib handle used in this file only */
+uint16_t wMwVer = 0; /* Middleware version no */
+uint16_t wFwVer = 0; /* Firmware version no */
+static pphDnldNfc_DlContext_t gpphDnldContext = NULL; /* Download contex */
+static pphDnldNfc_RspCb_t      UserCb; /* Upper layer call back function */
+static void*                   UserCtxt; /* Pointer to upper layer context */
+#undef EEPROM_Read_Mem_IMP
+
+/* Function prototype declaration */
+static void phDnldNfc_ReadComplete(void* pContext, NFCSTATUS status, void* pInfo);
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_Reset
+**
+** Description      Performs a soft reset of the download module
+**
+** Parameters       pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - reset request to NFCC is successful
+**                  NFCSTATUS_FAILED      - reset request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pNotify) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+            (gpphDnldContext->tCmdId) = PH_DL_CMD_RESET;
+            (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+            (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+            (gpphDnldContext->tUserData.pBuff) = NULL;
+            (gpphDnldContext->tUserData.wLen) = 0;
+            (gpphDnldContext->UserCb) = pNotify;
+            (gpphDnldContext->UserCtxt) = pContext;
+
+            wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventReset);
+
+            if(NFCSTATUS_PENDING == wStatus)
+            {
+                NXPLOG_FWDNLD_D("Reset Request submitted successfully");
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Reset Request Failed!!");
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_GetVersion
+**
+** Description      Retrieves Hardware version, ROM Code version, Protected Data version,
+**                  Trim data version, User data version, and Firmware version information
+**
+** Parameters       pVersionInfo - response buffer which gets updated with complete version info from NFCC
+**                  pNotify      - notify caller after getting response
+**                  pContext     - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - GetVersion request to NFCC is successful
+**                  NFCSTATUS_FAILED      - GetVersion request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pVersionInfo) || (NULL == pNotify) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if((NULL != pVersionInfo->pBuff) && (0 != pVersionInfo->wLen))
+            {
+                (gpphDnldContext->tRspBuffInfo.pBuff) = pVersionInfo->pBuff;
+                (gpphDnldContext->tRspBuffInfo.wLen) = pVersionInfo->wLen;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_GETVERSION;
+                (gpphDnldContext->tUserData.pBuff) = NULL;
+                (gpphDnldContext->tUserData.wLen) = 0;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventGetVer);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("GetVersion Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("GetVersion Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_GetSessionState
+**
+** Description      Retrieves the current session state of NFCC
+**
+** Parameters       pSession - response buffer which gets updated with complete version info from NFCC
+**                  pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - GetSessionState request to NFCC is successful
+**                  NFCSTATUS_FAILED      - GetSessionState request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pSession) || (NULL == pNotify) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if((NULL != pSession->pBuff) && (0 != pSession->wLen))
+            {
+                (gpphDnldContext->tRspBuffInfo.pBuff) = pSession->pBuff;
+                (gpphDnldContext->tRspBuffInfo.wLen) = pSession->wLen;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_GETSESSIONSTATE;
+                (gpphDnldContext->tUserData.pBuff) = NULL;
+                (gpphDnldContext->tUserData.wLen) = 0;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventGetSesnSt);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("GetSessionState Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("GetSessionState Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_CheckIntegrity
+**
+** Description      Inspects the integrity of EEPROM and FLASH contents of the NFCC,
+**                  provides CRC for each section
+**                  NOTE: The user data section CRC is valid only after fresh download
+**
+** Parameters       bChipVer - current ChipVersion for including additional parameters in request payload
+**                  pCRCData - response buffer which gets updated with respective section CRC status
+**                             and CRC bytes from NFCC
+**                  pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - CheckIntegrity request is successful
+**                  NFCSTATUS_FAILED      - CheckIntegrity request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pNotify) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            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) ||
+               (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bChipVer))
+            {
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_ChkIntg;
+            }
+            else
+            {
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTNone;
+            }
+
+            if((NULL != pCRCData->pBuff) && (0 != pCRCData->wLen))
+            {
+                (gpphDnldContext->tRspBuffInfo.pBuff) = pCRCData->pBuff;
+                (gpphDnldContext->tRspBuffInfo.wLen) = pCRCData->wLen;
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_CHECKINTEGRITY;
+                (gpphDnldContext->tUserData.pBuff) = NULL;
+                (gpphDnldContext->tUserData.wLen) = 0;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventIntegChk);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("CheckIntegrity Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("CheckIntegrity Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+/*******************************************************************************
+**
+** Function         phDnldNfc_ReadLog
+**
+** Description      Retrieves log data from EEPROM
+**
+** Parameters       pData    - response buffer which gets updated with data from EEPROM
+**                  pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - Read request to NFCC is successful
+**                  NFCSTATUS_FAILED      - Read request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pNotify) || (NULL == pData) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if((NULL != pData->pBuff) && (0 != pData->wLen))
+            {
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
+                (gpphDnldContext->FrameInp.dwAddr) = PHDNLDNFC_EEPROM_LOG_START_ADDR;
+                (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
+                (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
+                (gpphDnldContext->tUserData.pBuff) = NULL;
+                (gpphDnldContext->tUserData.wLen) = 0;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventRead);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("Read Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Read Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_Write
+**
+** Description      Writes requested  data of length len to desired EEPROM/FLASH address
+**
+** Parameters       bRecoverSeq - flag to indicate whether recover sequence data needs to be written or not
+**                  pData       - data buffer to write into EEPROM/FLASH by user
+**                  pNotify     - notify caller after getting response
+**                  pContext    - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - Write request to NFCC is successful
+**                  NFCSTATUS_FAILED      - Write request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Write(bool_t  bRecoverSeq, pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+    uint8_t *pImgPtr = NULL;
+    uint16_t wLen = 0;
+    phDnldNfc_Buff_t tImgBuff;
+
+    if((NULL == pNotify) || (NULL == pContext))
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if(NULL != pData)
+            {
+                pImgPtr = pData->pBuff;
+                wLen = pData->wLen;
+            }
+            else
+            {
+                if(FALSE == bRecoverSeq)
+                {
+
+                    pImgPtr = (uint8_t *)gpphDnldContext->nxp_nfc_fw;
+                    wLen = gpphDnldContext->nxp_nfc_fw_len;
+
+                }
+                else
+                {
+                    if(PH_DL_STATUS_PLL_ERROR == (gpphDnldContext->tLastStatus))
+                    {
+                        wStatus = phDnldNfc_LoadRecInfo();
+                    }
+                    else if(PH_DL_STATUS_SIGNATURE_ERROR == (gpphDnldContext->tLastStatus))
+                    {
+                        wStatus = phDnldNfc_LoadPKInfo();
+                    }
+                    else
+                    {
+                    }
+
+                    if(NFCSTATUS_SUCCESS == wStatus)
+                    {
+                        pImgPtr = (uint8_t *)gpphDnldContext->nxp_nfc_fwp;
+                        wLen = gpphDnldContext->nxp_nfc_fwp_len;
+                    }
+                    else
+                    {
+                        NXPLOG_FWDNLD_E("Platform Recovery Image extraction Failed!!");
+                        pImgPtr = NULL;
+                        wLen = 0;
+                    }
+                }
+            }
+
+            if((NULL != pImgPtr) && (0 != wLen))
+            {
+                tImgBuff.pBuff = pImgPtr;
+                tImgBuff.wLen = wLen;
+
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_WRITE;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTWrite;
+                (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+                (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+                (gpphDnldContext->tUserData.pBuff) = pImgPtr;
+                (gpphDnldContext->tUserData.wLen) = wLen;
+                (gpphDnldContext->bResendLastFrame) = FALSE;
+
+                memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+                (gpphDnldContext->tRWInfo.bFirstWrReq) = TRUE;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventWrite);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("Write Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Write Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Download Image Primitives extraction failed!!");
+                wStatus = NFCSTATUS_FAILED;
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_Log
+**
+** Description      Provides a full page free write to EEPROM
+**
+** Parameters       pData       - data buffer to write into EEPROM/FLASH by user
+**                  pNotify     - notify caller after getting response
+**                  pContext    - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - Write request to NFCC is successful
+**                  NFCSTATUS_FAILED      - Write request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pNotify) || (NULL == pData) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if((NULL != (pData->pBuff)) && ((0 != (pData->wLen) && (PHDNLDNFC_MAX_LOG_SIZE >= (pData->wLen)))))
+            {
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_LOG;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTLog;
+                (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+                (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+                (gpphDnldContext->tUserData.pBuff) = (pData->pBuff);
+                (gpphDnldContext->tUserData.wLen) = (pData->wLen);
+
+                memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventLog);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("Log Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Log Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Input Parameters for Log!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_Force
+**
+** Description      Used as an emergency recovery procedure for NFCC due to corrupt
+**                  settings of system platform specific parameters by the host
+**
+** Parameters       pInputs  - input buffer which contains  clk src & clk freq settings for desired platform
+**                  pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - Emergency Recovery request is successful
+**                  NFCSTATUS_FAILED      - Emergency Recovery failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint8_t bClkSrc = 0x00,bClkFreq = 0x00;
+    uint8_t bPldVal[3] = {0x11,0x00,0x00};  /* default values to be used if input not provided */
+
+    if((NULL == pNotify) || (NULL == pContext))
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            (gpphDnldContext->tCmdId) = PH_DL_CMD_FORCE;
+            (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTForce;
+            (gpphDnldContext->tRspBuffInfo.pBuff) = NULL;
+            (gpphDnldContext->tRspBuffInfo.wLen) = 0;
+
+            if((0 != (pInputs->wLen)) || (NULL != (pInputs->pBuff)))
+            {
+               if(CLK_SRC_XTAL == (pInputs->pBuff[0]))
+               {
+                   bClkSrc = phDnldNfc_ClkSrcXtal;
+               }
+               else if(CLK_SRC_PLL == (pInputs->pBuff[0]))
+               {
+                   bClkSrc = phDnldNfc_ClkSrcPLL;
+                   if(CLK_FREQ_13MHZ == (pInputs->pBuff[1]))
+                   {
+                       bClkFreq = phDnldNfc_ClkFreq_13Mhz;
+                   }
+                   else if(CLK_FREQ_19_2MHZ == (pInputs->pBuff[1]))
+                   {
+                       bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
+                   }
+                   else if(CLK_FREQ_24MHZ == (pInputs->pBuff[1]))
+                   {
+                       bClkFreq = phDnldNfc_ClkFreq_24Mhz;
+                   }
+                   else if(CLK_FREQ_26MHZ == (pInputs->pBuff[1]))
+                   {
+                       bClkFreq = phDnldNfc_ClkFreq_26Mhz;
+                   }
+                   else if(CLK_FREQ_38_4MHZ == (pInputs->pBuff[1]))
+                   {
+                       bClkFreq = phDnldNfc_ClkFreq_38_4Mhz;
+                   }
+                   else if(CLK_FREQ_52MHZ == (pInputs->pBuff[1]))
+                   {
+                       bClkFreq = phDnldNfc_ClkFreq_52Mhz;
+                   }
+                   else
+                   {
+                       NXPLOG_FWDNLD_E("Invalid Clk Frequency !! Using default value of 19.2Mhz..");
+                       bClkFreq = phDnldNfc_ClkFreq_19_2Mhz;
+                   }
+
+               }
+               else if(CLK_SRC_PADDIRECT == (pInputs->pBuff[0]))
+               {
+                   bClkSrc = phDnldNfc_ClkSrcPad;
+               }
+               else
+               {
+                   NXPLOG_FWDNLD_E("Invalid Clk src !! Using default value of PLL..");
+                   bClkSrc = phDnldNfc_ClkSrcPLL;
+               }
+
+               bPldVal[0] = 0U;
+               bPldVal[0] = ((bClkSrc << 3U) | bClkFreq);
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Clk src inputs not provided!! Using default values..");
+            }
+
+            (gpphDnldContext->tUserData.pBuff) = bPldVal;
+            (gpphDnldContext->tUserData.wLen) = sizeof(bPldVal);
+
+            memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+            (gpphDnldContext->UserCb) = pNotify;
+            (gpphDnldContext->UserCtxt) = pContext;
+
+            wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventForce);
+
+            if(NFCSTATUS_PENDING == wStatus)
+            {
+                NXPLOG_FWDNLD_D("Force Command Request submitted successfully");
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Force Command Request Failed!!");
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_SetHwDevHandle
+**
+** Description      Stores the HwDev handle to download context. The handle is required for subsequent operations
+**
+** Parameters       None
+**
+** Returns          None                -
+**
+*******************************************************************************/
+void phDnldNfc_SetHwDevHandle(void)
+{
+    pphDnldNfc_DlContext_t  psDnldContext = NULL;
+
+    if(NULL == gpphDnldContext)
+    {
+        NXPLOG_FWDNLD_D("Allocating Mem for Dnld Context..");
+        /* Create the memory for Download Mgmt Context */
+        psDnldContext = (pphDnldNfc_DlContext_t)
+                        malloc(sizeof(phDnldNfc_DlContext_t));
+
+        if(psDnldContext != NULL)
+        {
+            (void ) memset((void *)psDnldContext,0,
+                                            sizeof(phDnldNfc_DlContext_t));
+            gpphDnldContext = psDnldContext;
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Error Allocating Mem for Dnld Context..")
+        }
+    }
+    else
+    {
+        (void ) memset((void *)gpphDnldContext,0,
+                                            sizeof(phDnldNfc_DlContext_t));
+    }
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ReSetHwDevHandle
+**
+** Description      Frees the HwDev handle to download context.
+**
+** Parameters       None
+**
+** Returns          None                -
+**
+*******************************************************************************/
+void phDnldNfc_ReSetHwDevHandle(void)
+{
+    if (gpphDnldContext != NULL)
+    {
+        NXPLOG_FWDNLD_E("Freeing Mem for Dnld Context..")
+        free(gpphDnldContext);
+        gpphDnldContext = NULL;
+    }
+}
+
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_RawReq
+**
+** Description      Sends raw frame request to NFCC.
+**                  It is currently used for sending an NCI RESET cmd after doing a production key update
+**
+** Parameters       pFrameData - input buffer, contains raw frame packet to be sent to NFCC
+**                  pRspData   - response buffer received from NFCC
+**                  pNotify    - notify caller after getting response
+**                  pContext   - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - GetSessionState request to NFCC is successful
+**                  NFCSTATUS_FAILED      - GetSessionState request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData, pphDnldNfc_Buff_t pRspData, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pFrameData) || (NULL == pNotify) || (NULL == pRspData) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Raw Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if(((NULL != pFrameData->pBuff) && (0 != pFrameData->wLen)) &&
+                ((NULL != pRspData->pBuff) && (0 != pRspData->wLen))
+                )
+            {
+                (gpphDnldContext->tRspBuffInfo.pBuff) = pRspData->pBuff;
+                (gpphDnldContext->tRspBuffInfo.wLen) = pRspData->wLen;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRaw;
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_NONE;
+                (gpphDnldContext->tUserData.pBuff) = pFrameData->pBuff;
+                (gpphDnldContext->tUserData.wLen) = pFrameData->wLen;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventRaw);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("RawFrame Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("RawFrame Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_InitImgInfo
+**
+** Description      Extracts image information and stores it in respective variables,
+**                  to be used internally for write operation
+**
+** Parameters       None
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_InitImgInfo(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint8_t *pImageInfo =  NULL;
+    uint16_t ImageInfoLen = 0;
+
+    /* if memory is not allocated then allocate memory for donwload context structure */
+    phDnldNfc_SetHwDevHandle();
+
+    /* load the library and get the image info pointer */
+    wStatus = phDnldNfc_LoadFW(FW_LIB_PATH, &pImageInfo, &ImageInfoLen);
+
+    NXPLOG_FWDNLD_D("FW Image Length - ImageInfoLen %d",ImageInfoLen);
+    NXPLOG_FWDNLD_D("FW Image Info Pointer - pImageInfo %x",(uintptr_t)pImageInfo);
+
+    if((pImageInfo == NULL) || (ImageInfoLen == 0))
+    {
+        NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
+        wStatus = NFCSTATUS_FAILED;
+    }
+
+    if (wStatus != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("Error loading libpn54x_fw !!\n");
+    }
+
+   /* get the MW version */
+   if(NFCSTATUS_SUCCESS == wStatus)
+   {
+       //NXPLOG_FWDNLD_D("MW Major Version Num - %x",NXP_MW_VERSION_MAJ);
+       //NXPLOG_FWDNLD_D("MW Minor Version Num - %x",NXP_MW_VERSION_MIN);
+       wMwVer = (((uint16_t)(NXP_MW_VERSION_MAJ) << 8U) | (NXP_MW_VERSION_MIN));
+   }
+
+   if(NFCSTATUS_SUCCESS == wStatus)
+   {
+       gpphDnldContext->nxp_nfc_fw = (uint8_t*)pImageInfo;
+       gpphDnldContext->nxp_nfc_fw_len = ImageInfoLen;
+       if((NULL != gpphDnldContext->nxp_nfc_fw) && (0 != gpphDnldContext->nxp_nfc_fw_len))
+       {
+           NXPLOG_FWDNLD_D("FW Major Version Num - %x",gpphDnldContext->nxp_nfc_fw[5]);
+           NXPLOG_FWDNLD_D("FW Minor Version Num - %x",gpphDnldContext->nxp_nfc_fw[4]);
+           NXPLOG_FWDNLD_D("FW Image Length - %d",ImageInfoLen);
+           NXPLOG_FWDNLD_D("FW Image Info Pointer - %x",(uintptr_t)pImageInfo);
+
+           /* get the FW version */
+           wFwVer = (((uint16_t)(gpphDnldContext->nxp_nfc_fw[5]) << 8U) | (gpphDnldContext->nxp_nfc_fw[4]));
+           wStatus = NFCSTATUS_SUCCESS;
+       }
+       else
+       {
+           NXPLOG_FWDNLD_E("Image details extraction Failed!!");
+           wStatus = NFCSTATUS_FAILED;
+       }
+   }
+
+   return wStatus;
+}
+
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_LoadRecInfo
+**
+** Description      Extracts recovery sequence image information and stores it
+**                  in respective variables, to be used internally for write operation
+**
+** Parameters       None
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadRecInfo(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint8_t *pImageInfo = NULL;
+    uint16_t ImageInfoLen = 0;
+
+    /* if memory is not allocated then allocate memory for donwload context structure */
+    phDnldNfc_SetHwDevHandle();
+
+    wStatus = phDnldNfc_LoadFW(PLATFORM_LIB_PATH, &pImageInfo, &ImageInfoLen);
+
+    if((pImageInfo == NULL) || (ImageInfoLen == 0))
+    {
+        NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
+        wStatus = NFCSTATUS_FAILED;
+    }
+
+    /* load the PLL recovery image library */
+    if (wStatus != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("Error loading libpn54x_fw_platform !!\n");
+    }
+
+   if(NFCSTATUS_SUCCESS == wStatus)
+   {
+       /* fetch the PLL recovery image pointer and the image length */
+       gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
+       gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
+       if((NULL != gpphDnldContext->nxp_nfc_fwp) && (0 != gpphDnldContext->nxp_nfc_fwp_len))
+       {
+           NXPLOG_FWDNLD_D("Recovery Image Length - %d",ImageInfoLen);
+           NXPLOG_FWDNLD_D("Recovery Image Info Pointer - %x",(uintptr_t)pImageInfo);
+           wStatus = NFCSTATUS_SUCCESS;
+       }
+       else
+       {
+           NXPLOG_FWDNLD_E("Recovery Image details extraction Failed!!");
+           wStatus = NFCSTATUS_FAILED;
+       }
+   }
+
+   return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_LoadPKInfo
+**
+** Description      Extracts production sequence image information and stores it
+**                  in respective variables, to be used internally for write operation
+**
+** Parameters       None
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadPKInfo(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint8_t *pImageInfo = NULL;
+    uint16_t ImageInfoLen = 0;
+
+    /* if memory is not allocated then allocate memory for donwload context structure */
+    phDnldNfc_SetHwDevHandle();
+
+    /* load the PKU image library */
+    wStatus = phDnldNfc_LoadFW(PKU_LIB_PATH, &pImageInfo, &ImageInfoLen);
+
+    if((pImageInfo == NULL) || (ImageInfoLen == 0))
+    {
+        NXPLOG_FWDNLD_E("Image extraction Failed - invalid imginfo or imginfolen!!");
+        wStatus = NFCSTATUS_FAILED;
+    }
+
+    if (wStatus != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("Error loading libpn54x_fw_pku !!\n");
+    }
+
+   if(NFCSTATUS_SUCCESS == wStatus)
+   {
+       /* fetch the PKU image pointer and the image length */
+       gpphDnldContext->nxp_nfc_fwp = (uint8_t*)pImageInfo;
+       gpphDnldContext->nxp_nfc_fwp_len = ImageInfoLen;
+
+       if((NULL != gpphDnldContext->nxp_nfc_fwp) && (0 != gpphDnldContext->nxp_nfc_fwp_len))
+       {
+           NXPLOG_FWDNLD_D("PKU Image Length - %d",ImageInfoLen);
+           NXPLOG_FWDNLD_D("PKU Image Info Pointer - %x",(uintptr_t)pImageInfo);
+           wStatus = NFCSTATUS_SUCCESS;
+       }
+       else
+       {
+           NXPLOG_FWDNLD_E("PKU Image details extraction Failed!!");
+           wStatus = NFCSTATUS_FAILED;
+       }
+   }
+
+   return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_CloseFwLibHandle
+**
+** Description      Closes previously opened fw library handle as part of
+**                  dynamic loader processing
+**
+** Parameters       None
+**
+** Returns          None
+**
+*******************************************************************************/
+void phDnldNfc_CloseFwLibHandle(void)
+{
+    NFCSTATUS wStatus;
+
+    wStatus = phDnldNfc_UnloadFW();
+    if(wStatus != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("free library FAILED !!\n");
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E("free library SUCCESS !!\n");
+    }
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_LoadFW
+**
+** Description      Load the firmware version form firmware lib
+**
+** Parameters       pathName    - Firmware image path
+**                  pImgInfo    - Firmware image handle
+**                  pImgInfoLen - Firmware image length
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen)
+{
+    void* pImageInfo = NULL;
+    void* pImageInfoLen = NULL;
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    /* check for path name */
+    if(pathName == NULL)
+    {
+        pathName = "/system/vendor/firmware/libpn548ad_fw.so";
+    }
+#else
+    if(pathName == NULL)
+    {
+        pathName = "/system/vendor/firmware/libpn547_fw.so";
+    }
+#endif
+
+    /* check if the handle is not NULL then free the library */
+    if(pFwLibHandle != NULL)
+    {
+        phDnldNfc_UnloadFW();
+        pFwLibHandle = NULL;
+    }
+
+    /* load the DLL file */
+    pFwLibHandle = dlopen(pathName, RTLD_LAZY);
+    NXPLOG_FWDNLD_D ("@@@%s", pathName);
+
+    /* if library load failed then handle will be NULL */
+    if(pFwLibHandle == NULL)
+    {
+        NXPLOG_FWDNLD_E("NULL handler : unable to load the library file, specify correct path");
+        return NFCSTATUS_FAILED;
+    }
+
+    dlerror();    /* Clear any existing error */
+
+    /* load the address of download image pointer and image size */
+   pImageInfo     =  (void*)dlsym(pFwLibHandle,"gphDnldNfc_DlSeq");
+
+   if(dlerror()|| (NULL == pImageInfo))
+   {
+       NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeq");
+       return NFCSTATUS_FAILED;
+   }
+   (*pImgInfo) = (*(uint8_t**)pImageInfo);
+
+   pImageInfoLen  = (void*)dlsym(pFwLibHandle,"gphDnldNfc_DlSeqSz");
+   if(dlerror() || (NULL == pImageInfoLen))
+   {
+       NXPLOG_FWDNLD_E("Problem loading symbol : gphDnldNfc_DlSeqSz");
+       return NFCSTATUS_FAILED;
+   }
+
+   (*pImgInfoLen) = (uint16_t)(*((uint16_t*)pImageInfoLen));
+
+    return NFCSTATUS_SUCCESS;
+}
+
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_UnloadFW
+**
+** Description      Deinit the firmware handle
+**
+** Parameters       None
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_UnloadFW(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    int32_t   status;
+
+    /* check if the handle is not NULL then free the library */
+    if(pFwLibHandle != NULL)
+    {
+        status = dlclose(pFwLibHandle);
+        pFwLibHandle = NULL;
+
+        dlerror();    /* Clear any existing error */
+        if(status != 0)
+        {
+            wStatus = NFCSTATUS_FAILED;
+            NXPLOG_FWDNLD_E("Free library file failed");
+        }
+    }
+
+    return wStatus;
+}
+
+#ifdef EEPROM_Read_Mem_IMP
+/*******************************************************************************
+**
+** Function         phDnldNfc_ReadMem
+**
+** Description      Dumps the contents of EEPROM. The handle is required for subsequent operations
+**
+** Parameters       pHwRef   - pointer to the hardware device
+**                  pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - request to NFCC is successful
+**                  NFCSTATUS_FAILED      - request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_ReadMem(void *pHwRef, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint32_t wAddr = 0x2011C0; /* eeprom platform specific area start address */
+    uint32_t wRdAddr = 0;
+    uint8_t *pAddr;
+    static uint8_t bRdData[3519];  /* buffer to hold the read data */
+    static phDnldNfc_Buff_t Data;
+
+    if((NULL == pNotify) || (NULL == pContext))
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        /* Call Tml Ioctl to enable download mode */
+        wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+
+        if(NFCSTATUS_SUCCESS == wStatus)
+        {
+           /* Set the obtained device handle to download module */
+           phDnldNfc_SetHwDevHandle();
+        }
+        else
+        {
+            wStatus = NFCSTATUS_FAILED;
+        }
+
+        if(NFCSTATUS_SUCCESS == wStatus)
+        {
+            pAddr = (uint8_t *)&wAddr;
+
+            wRdAddr = (pAddr[3]);
+            wRdAddr <<= 8;
+            wRdAddr |= (pAddr[2]);
+            wRdAddr <<= 8;
+            wRdAddr |= (pAddr[1]);
+            wRdAddr <<= 8;
+            wRdAddr |= (pAddr[0]);
+
+            Data.pBuff = bRdData;
+            Data.wLen = sizeof(bRdData);
+            UserCb = pNotify;
+            UserCtxt = pContext;
+
+            wStatus = phDnldNfc_Read(&Data, wRdAddr,(pphDnldNfc_RspCb_t)phDnldNfc_ReadComplete,gpphDnldContext);
+        }
+        else
+        {
+            Data.pBuff = NULL;
+            Data.wLen = 0;
+            wStatus = NFCSTATUS_FAILED;
+        }
+
+        if(NFCSTATUS_PENDING == wStatus)
+        {
+            NXPLOG_FWDNLD_D("Read Request submitted successfully..");
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Read Request submission failed!!");
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ReadComplete
+**
+** Description      Read complete
+**
+** Parameters       pContext - caller layer context
+**                  status   - status of the transaction
+**                  pInfo    - transaction info
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phDnldNfc_ReadComplete(void* pContext,NFCSTATUS status,void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    UNUSED(pContext);
+
+    /* Call Tml Ioctl to enable/restore normal mode */
+    wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
+
+    if(NFCSTATUS_SUCCESS == wStatus)
+    {
+        NXPLOG_FWDNLD_D("Read Done!!");
+    }
+
+    UserCb(&UserCtxt,status,pInfo);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_Read
+**
+** Description      Retrieves requested data of specified length from desired EEPROM address
+**
+** Parameters       pData    - response buffer which gets updated with data from EEPROM
+**                  dwRdAddr - EEPROM address for data read
+**                  pNotify  - notify caller after getting response
+**                  pContext - caller context
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS     - Read request to NFCC is successful
+**                  NFCSTATUS_FAILED      - Read request failed due to internal error
+**                  NFCSTATUS_NOT_ALLOWED - command not allowed
+**                  Other command specific errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr, pphDnldNfc_RspCb_t pNotify, void *pContext)
+{
+    NFCSTATUS   wStatus = NFCSTATUS_SUCCESS;
+
+    if((NULL == pNotify) || (NULL == pData) ||
+       (NULL == pContext)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_TransitionIdle != gpphDnldContext->tDnldInProgress)
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request in Progress..Cannot Continue!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_BUSY);
+        }
+        else
+        {
+            if((NULL != pData->pBuff) && (0 != pData->wLen))
+            {
+                (gpphDnldContext->tCmdId) = PH_DL_CMD_READ;
+                (gpphDnldContext->FrameInp.Type) = phDnldNfc_FTRead;
+                (gpphDnldContext->FrameInp.dwAddr) = dwRdAddr;
+                (gpphDnldContext->tRspBuffInfo.pBuff) = pData->pBuff;
+                (gpphDnldContext->tRspBuffInfo.wLen) = pData->wLen;
+                (gpphDnldContext->tUserData.pBuff) = NULL;
+                (gpphDnldContext->tUserData.wLen) = 0;
+                (gpphDnldContext->UserCb) = pNotify;
+                (gpphDnldContext->UserCtxt) = pContext;
+
+                memset(&(gpphDnldContext->tRWInfo),0,sizeof(gpphDnldContext->tRWInfo));
+
+                wStatus = phDnldNfc_CmdHandler(gpphDnldContext,phDnldNfc_EventRead);
+
+                if(NFCSTATUS_PENDING == wStatus)
+                {
+                    NXPLOG_FWDNLD_D("Read Request submitted successfully");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Read Request Failed!!");
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Invalid Buff Parameters!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+    }
+
+    return wStatus;
+}
+#endif
diff --git a/halimpl/pn54x/dnld/phDnldNfc.h b/halimpl/pn54x/dnld/phDnldNfc.h
new file mode 100644
index 0000000..df95c93
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Firmware Download Interface File
+ */
+#ifndef PHDNLDNFC_H
+#define PHDNLDNFC_H
+
+#include <phNfcStatus.h>
+
+/*
+ *
+ * Callback for handling the received data/response from PN54X.
+ * Parameters to be passed/registered to download context during respective download function call:
+ *      pContext - Upper layer context
+ *      wStatus  - Status of the transaction
+ *      pInfo    - Contains the Transaction Info
+ */
+typedef void (*pphDnldNfc_RspCb_t)(void* pContext, NFCSTATUS wStatus,void* pInfo);
+
+#define PHLIBNFC_FWDNLD_SESSNOPEN    (0x01U)   /* download session is Open */
+#define PHLIBNFC_FWDNLD_SESSNCLOSED  (0x00U)   /* download session is Closed */
+
+#define PHDNLDNFC_HWVER_MRA1_0       (0x01U)   /* ChipVersion MRA1.0 */
+#define PHDNLDNFC_HWVER_MRA1_1       (0x02U)   /* ChipVersion MRA1.1 */
+#define PHDNLDNFC_HWVER_MRA2_0       (0x03U)   /* ChipVersion MRA2.0 */
+#define PHDNLDNFC_HWVER_MRA2_1       (0x04U)   /* ChipVersion MRA2.1 */
+#define PHDNLDNFC_HWVER_MRA2_2       (0x05U)   /* ChipVersion MRA2.2 */
+
+#define PHDNLDNFC_HWVER_PN548AD_MRA1_0       (0x08U)   /* PN548AD ChipVersion MRA1.0 */
+/*
+ * Enum definition contains Download Life Cycle States
+ */
+typedef enum phDnldNfc_LC{
+    phDnldNfc_LCCreat = 11,     /* Life Cycle Creation*/
+    phDnldNfc_LCInit = 13,      /* Life Cycle Initializing */
+    phDnldNfc_LCOper = 17,      /* Life Cycle Operational */
+    phDnldNfc_LCTerm = 19       /* Life Cycle Termination */
+}phDnldNfc_LC_t;
+
+/*
+ * Enum definition contains Clk Source Options for Force command request
+ */
+typedef enum phDnldNfc_ClkSrc{
+    phDnldNfc_ClkSrcXtal = 1U,     /* Crystal */
+    phDnldNfc_ClkSrcPLL = 2U,      /* PLL output */
+    phDnldNfc_ClkSrcPad = 3U      /* Directly use clk on CLK_IN Pad */
+}phDnldNfc_ClkSrc_t;
+
+/*
+ * Enum definition contains Clk Frequency value for Force command request
+ */
+typedef enum phDnldNfc_ClkFreq{
+    phDnldNfc_ClkFreq_13Mhz = 0U,    /* 13Mhz Clk Frequency */
+    phDnldNfc_ClkFreq_19_2Mhz = 1U,  /* 19.2Mhz Clk Frequency */
+    phDnldNfc_ClkFreq_24Mhz = 2U,    /* 24Mhz Clk Frequency */
+    phDnldNfc_ClkFreq_26Mhz = 3U,    /* 26Mhz Clk Frequency */
+    phDnldNfc_ClkFreq_38_4Mhz = 4U,  /* 38.4Mhz Clk Frequency */
+    phDnldNfc_ClkFreq_52Mhz = 5U     /* 52Mhz Clk Frequency */
+}phDnldNfc_ClkFreq_t;
+
+/*
+ * Struct contains buffer where user payload shall be stored
+ */
+typedef struct phDnldNfc_Buff
+{
+    uint8_t *pBuff;                  /*pointer to the buffer where user payload shall be stored*/
+    uint16_t wLen;                   /*Buffer length*/
+}phDnldNfc_Buff_t, *pphDnldNfc_Buff_t; /* pointer to #phDnldNfc_Buff_t */
+
+/*
+*********************** Function Prototype Declaration *************************
+*/
+
+extern NFCSTATUS phDnldNfc_Reset(pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_GetVersion(pphDnldNfc_Buff_t pVersionInfo, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_CheckIntegrity(uint8_t bChipVer, pphDnldNfc_Buff_t pCRCData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_GetSessionState(pphDnldNfc_Buff_t pSession, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_Force(pphDnldNfc_Buff_t pInputs, pphDnldNfc_RspCb_t pNotify,void *pContext);
+extern NFCSTATUS phDnldNfc_Read(pphDnldNfc_Buff_t pData, uint32_t dwRdAddr, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_ReadLog(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_Write(bool_t  bRecoverSeq, pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_Log(pphDnldNfc_Buff_t pData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern void phDnldNfc_SetHwDevHandle(void);
+void phDnldNfc_ReSetHwDevHandle(void);
+extern NFCSTATUS phDnldNfc_ReadMem(void *pHwRef, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_RawReq(pphDnldNfc_Buff_t pFrameData, pphDnldNfc_Buff_t pRspData, pphDnldNfc_RspCb_t pNotify, void *pContext);
+extern NFCSTATUS phDnldNfc_InitImgInfo(void);
+extern NFCSTATUS phDnldNfc_LoadRecInfo(void);
+extern NFCSTATUS phDnldNfc_LoadPKInfo(void);
+extern void phDnldNfc_CloseFwLibHandle(void);
+extern NFCSTATUS phDnldNfc_LoadFW(const char* pathName, uint8_t **pImgInfo, uint16_t* pImgInfoLen);
+extern NFCSTATUS phDnldNfc_UnloadFW(void);
+#endif /* PHDNLDNFC_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Cmd.h b/halimpl/pn54x/dnld/phDnldNfc_Cmd.h
new file mode 100644
index 0000000..91ef3f0
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Cmd.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Firmware Download command values
+ */
+
+#ifndef PHDNLDNFC_CMD_H
+#define PHDNLDNFC_CMD_H
+
+#include <phNfcStatus.h>
+
+/*
+ * Enum definition contains Firmware Download Command Ids
+ */
+typedef enum phDnldNfc_CmdId
+{
+    PH_DL_CMD_NONE            = 0x00, /* Invalid Cmd */
+    PH_DL_CMD_RESET           = 0xF0, /* Reset */
+    PH_DL_CMD_GETVERSION      = 0xF1, /* Get Version */
+    PH_DL_CMD_CHECKINTEGRITY  = 0xE0, /* Check Integrity */
+    PH_DL_CMD_WRITE           = 0xC0, /* Write */
+    PH_DL_CMD_READ            = 0xA2, /* Read */
+    PH_DL_CMD_LOG             = 0xA7, /* Log */
+    PH_DL_CMD_FORCE           = 0xD0, /* Force */
+    PH_DL_CMD_GETSESSIONSTATE = 0xF2  /* Get Session State */
+}phDnldNfc_CmdId_t;
+
+#endif /* PHDNLDNFC_CMD_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Internal.c b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
new file mode 100644
index 0000000..628e582
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.c
@@ -0,0 +1,1322 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Internal Download Management routines
+ * Download Component
+ */
+
+#include <phDnldNfc_Internal.h>
+#include <phDnldNfc_Utils.h>
+#include <phTmlNfc.h>
+#include <phNxpLog.h>
+#include <phNxpNciHal_utils.h>
+
+#define PHDNLDNFC_MIN_PLD_LEN   (0x04U)                      /* Minimum length of payload including 1 byte CmdId */
+
+#define PHDNLDNFC_FRAME_HDR_OFFSET  (0x00)                    /* Offset of Length byte within the frame */
+#define PHDNLDNFC_FRAMEID_OFFSET (PHDNLDNFC_FRAME_HDR_LEN)        /* Offset of FrameId within the frame */
+#define PHDNLDNFC_FRAMESTATUS_OFFSET PHDNLDNFC_FRAMEID_OFFSET  /* Offset of status byte within the frame */
+#define PHDNLDNFC_PLD_OFFSET    (PHDNLDNFC_MIN_PLD_LEN - 1)    /* Offset within frame where payload starts*/
+
+#define PHDNLDNFC_FRAME_RDDATA_OFFSET ((PHDNLDNFC_FRAME_HDR_LEN) + \
+                                      (PHDNLDNFC_MIN_PLD_LEN)) /* recvd frame offset where data starts */
+
+#define PHDNLDNFC_FRAME_SIGNATURE_SIZE   (0xC0U)        /* Size of first secure write frame Signature */
+#define PHDNLDNFC_FIRST_FRAME_PLD_SIZE   (0xE4U)        /* Size of first secure write frame payload */
+
+#define PHDNLDNFC_FIRST_FRAGFRAME_RESP   (0x2DU)        /* Status response for first fragmented write frame */
+#define PHDNLDNFC_NEXT_FRAGFRAME_RESP    (0x2EU)        /* Status response for subsequent fragmented write frame */
+
+#define PHDNLDNFC_SET_HDR_FRAGBIT(n)      ((n) | (1<<10))    /* Header chunk bit set macro */
+#define PHDNLDNFC_CLR_HDR_FRAGBIT(n)      ((n) & ~(1U<<10))   /* Header chunk bit clear macro */
+#define PHDNLDNFC_CHK_HDR_FRAGBIT(n)      ((n) & 0x04)       /* macro to check if frag bit is set in Hdr */
+
+#define PHDNLDNFC_RSP_TIMEOUT   (2500)                /* Timeout value to wait for response from NFCC */
+#define PHDNLDNFC_RETRY_FRAME_WRITE   (50)            /* Timeout value to wait before resending the last frame */
+
+#define PHDNLDNFC_USERDATA_EEPROM_LENSIZE    (0x02U)    /* size of EEPROM user data length */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSIZE    (0x02U)    /* size of EEPROM offset */
+
+#ifdef  NXP_PN547C1_DOWNLOAD
+/* EEPROM offset and length value for C1 */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x003CU)    /* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0DC0U)    /* 16 bits length of user data area */
+#else
+
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+/* EEPROM offset and length value for C2 */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x023CU)    /* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0C80U)    /* 16 bits length of user data area */
+#else
+/* EEPROM offset and length value for PN548AD */
+#define PHDNLDNFC_USERDATA_EEPROM_OFFSET  (0x02BCU)    /* 16 bits offset indicating user data area start location */
+#define PHDNLDNFC_USERDATA_EEPROM_LEN     (0x0C00U)    /* 16 bits length of user data area */
+#endif
+
+#endif
+#define PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT (1)
+
+/* Function prototype declarations */
+static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext);
+static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext);
+static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext);
+static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t   pDlContext, phTmlNfc_TransactInfo_t  *pInfo, uint16_t wPldLen);
+static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext);
+static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void *pContext);
+
+/*
+*************************** Function Definitions ***************************
+*/
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_CmdHandler
+**
+** Description      Download Command Handler Mechanism
+**                  - holds the sub states for each command processing
+**                  - coordinates with TML download thread to complete a download command request
+**                  - calls the user callback on completion of a cmd
+**
+** Parameters       pContext  - pointer to the download context structure
+**                  TrigEvent - event requested by user
+**
+** Returns          NFC status:
+**                  NFCSTATUS_PENDING           - download request sent to NFCC successfully,response pending
+**                  NFCSTATUS_BUSY              - handler is busy processing a download request
+**                  NFCSTATUS_INVALID_PARAMETER - one or more of the supplied parameters could not be interpreted properly
+**                  Other errors                -
+**
+*******************************************************************************/
+NFCSTATUS phDnldNfc_CmdHandler(void *pContext, phDnldNfc_Event_t TrigEvent)
+{
+    NFCSTATUS  status = NFCSTATUS_SUCCESS;
+    pphDnldNfc_DlContext_t  pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+    if(NULL == pDlCtxt)
+    {
+      NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+      status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        switch(TrigEvent)
+        {
+            case phDnldNfc_EventReset:
+            case phDnldNfc_EventGetVer:
+            case phDnldNfc_EventIntegChk:
+            case phDnldNfc_EventGetSesnSt:
+            case phDnldNfc_EventRaw:
+            {
+                if(phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent))
+                {
+                    NXPLOG_FWDNLD_D("Processing Normal Sequence..");
+                    pDlCtxt->tCurrEvent = TrigEvent;
+                    pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy;
+
+                    phDnldNfc_ProcessSeqState(pDlCtxt,NULL);
+
+                    status = pDlCtxt->wCmdSendStatus;
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Prev Norml Sequence not completed/restored!!");
+                    status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+                }
+                break;
+            }
+            case phDnldNfc_EventWrite:
+            case phDnldNfc_EventRead:
+            case phDnldNfc_EventLog:
+            case phDnldNfc_EventForce:
+            {
+                if(phDnldNfc_EventInvalid == (pDlCtxt->tCurrEvent))
+                {
+                    NXPLOG_FWDNLD_D("Processing R/W Sequence..");
+                    pDlCtxt->tCurrEvent = TrigEvent;
+                    pDlCtxt->tDnldInProgress = phDnldNfc_TransitionBusy;
+
+                    phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
+
+                    status = pDlCtxt->wCmdSendStatus;
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Prev R/W Sequence not completed/restored!!");
+                    status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+                }
+                break;
+            }
+            default:
+            {
+                /* Unknown Event */
+                NXPLOG_FWDNLD_E("Unknown Event Parameter!!");
+                status = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+                break;
+            }
+        }
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ProcessSeqState
+**
+** Description      Processes all cmd/resp sequences except read & write
+**
+** Parameters       pContext - pointer to the download context structure
+**                  pInfo    - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phDnldNfc_ProcessSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    NFCSTATUS wIntStatus;
+    uint32_t TimerId;
+    pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+    if(NULL == pDlCtxt)
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        switch(pDlCtxt->tCurrState)
+        {
+            case phDnldNfc_StateInit:
+            {
+                NXPLOG_FWDNLD_D("Initializing Sequence..");
+
+                if(0 == (pDlCtxt->TimerInfo.dwRspTimerId))
+                {
+                    TimerId = phOsalNfc_Timer_Create();
+
+                    if (0 == TimerId)
+                    {
+                        NXPLOG_FWDNLD_W("Response Timer Create failed!!");
+                        wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES;
+                        pDlCtxt->wCmdSendStatus = wStatus;
+                        break;
+                    }
+                    else
+                    {
+                        NXPLOG_FWDNLD_D("Response Timer Created Successfully");
+                        (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId;
+                        (pDlCtxt->TimerInfo.TimerStatus) = 0;
+                        (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+                    }
+                }
+                pDlCtxt->tCurrState = phDnldNfc_StateSend;
+            }
+            case phDnldNfc_StateSend:
+            {
+                wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
+
+                if(NFCSTATUS_SUCCESS == wStatus)
+                {
+                    pDlCtxt->tCurrState = phDnldNfc_StateRecv;
+
+                    wStatus = phTmlNfc_Write( (pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
+                        (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
+                                    (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
+                                    pDlCtxt);
+                }
+                pDlCtxt->wCmdSendStatus = wStatus;
+                break;
+            }
+            case phDnldNfc_StateRecv:
+            {
+                wStatus = phDnldNfc_ProcessRecvInfo(pContext,pInfo);
+
+                if(NFCSTATUS_SUCCESS == wStatus)
+                {
+                    wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId),
+                                                PHDNLDNFC_RSP_TIMEOUT,
+                                                &phDnldNfc_RspTimeOutCb,
+                                                pDlCtxt);
+
+                    if (NFCSTATUS_SUCCESS == wStatus)
+                    {
+                        NXPLOG_FWDNLD_D("Response timer started");
+                        pDlCtxt->TimerInfo.TimerStatus = 1;
+                        pDlCtxt->tCurrState = phDnldNfc_StateTimer;
+                    }
+                    else
+                    {
+                         NXPLOG_FWDNLD_W("Response timer not started");
+                        pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+                    }
+                    /* Call TML_Read function and register the call back function */
+                    wStatus = phTmlNfc_Read(
+                        pDlCtxt->tCmdRspFrameInfo.aFrameBuff,
+                        (uint16_t )PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE,
+                        (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessSeqState,
+                        (void *)pDlCtxt);
+
+                    break;
+                }
+                else
+                {
+                    /* Setting TimerExpStatus below to avoid frame processing in response state */
+                    (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
+                    pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+                }
+            }
+            case phDnldNfc_StateTimer:
+            {
+                if (1 == (pDlCtxt->TimerInfo.TimerStatus)) /*Is Timer Running*/
+                {
+                    /*Stop Timer*/
+                    (void)phOsalNfc_Timer_Stop(pDlCtxt->TimerInfo.dwRspTimerId);
+                    (pDlCtxt->TimerInfo.TimerStatus) = 0; /*timer stopped*/
+                }
+                pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+            }
+            case phDnldNfc_StateResponse:
+            {
+                if(NFCSTATUS_RF_TIMEOUT != (pDlCtxt->TimerInfo.wTimerExpStatus))
+                {
+                    /* Process response */
+                    wStatus = phDnldNfc_ProcessFrame(pContext,pInfo);
+                }
+                else
+                {
+                    if(phDnldNfc_EventReset != pDlCtxt->tCurrEvent)
+                    {
+                        wStatus = (pDlCtxt->TimerInfo.wTimerExpStatus);
+                    }
+                    else
+                    {
+                        wStatus = NFCSTATUS_SUCCESS;
+                    }
+                    (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+                }
+
+                /* Abort TML read operation which is always kept open */
+                wIntStatus  = phTmlNfc_ReadAbort();
+
+                if(NFCSTATUS_SUCCESS != wIntStatus)
+                {
+                    /* TODO:-Action to take in this case:-Tml read abort failed!? */
+                    NXPLOG_FWDNLD_W("Tml Read Abort failed!!");
+                }
+
+                pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
+                pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
+                pDlCtxt->tCurrState = phDnldNfc_StateInit;
+
+                /* Delete the timer & reset timer primitives in context */
+                (void)phOsalNfc_Timer_Delete(pDlCtxt->TimerInfo.dwRspTimerId);
+                (pDlCtxt->TimerInfo.dwRspTimerId) = 0;
+                (pDlCtxt->TimerInfo.TimerStatus) = 0;
+                (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+
+                if((NULL != (pDlCtxt->UserCb)) && (NULL != (pDlCtxt->UserCtxt)))
+                {
+                    pDlCtxt->UserCb((pDlCtxt->UserCtxt),wStatus,&(pDlCtxt->tRspBuffInfo));
+                }
+                break;
+            }
+            default:
+            {
+                pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
+                pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
+                break;
+            }
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ProcessRWSeqState
+**
+** Description      Processes read/write cmd/rsp sequence
+**
+** Parameters       pContext - pointer to the download context structure
+**                  pInfo    - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phDnldNfc_ProcessRWSeqState(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    NFCSTATUS wIntStatus = wStatus;
+    uint32_t TimerId;
+    pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+    if(NULL == pDlCtxt)
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        switch(pDlCtxt->tCurrState)
+        {
+            case phDnldNfc_StateInit:
+            {
+                if(0 == (pDlCtxt->TimerInfo.dwRspTimerId))
+                {
+                    TimerId = phOsalNfc_Timer_Create();
+
+                    if (0 == TimerId)
+                    {
+                        NXPLOG_FWDNLD_E("Response Timer Create failed!!");
+                        wStatus = NFCSTATUS_INSUFFICIENT_RESOURCES;
+                    }
+                    else
+                    {
+                        NXPLOG_FWDNLD_D("Response Timer Created Successfully");
+                        (pDlCtxt->TimerInfo.dwRspTimerId) = TimerId;
+                        (pDlCtxt->TimerInfo.TimerStatus) = 0;
+                        (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+                    }
+                }
+                pDlCtxt->tCurrState = phDnldNfc_StateSend;
+            }
+            case phDnldNfc_StateSend:
+            {
+                if(FALSE == pDlCtxt->bResendLastFrame)
+                {
+                    wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
+                }
+                else
+                {
+                    pDlCtxt->bResendLastFrame = FALSE;
+                }
+
+                if(NFCSTATUS_SUCCESS == wStatus)
+                {
+                    pDlCtxt->tCurrState = phDnldNfc_StateRecv;
+
+                    wStatus = phTmlNfc_Write((pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
+                        (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
+                                    (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
+                                    pDlCtxt);
+                }
+                pDlCtxt->wCmdSendStatus = wStatus;
+                break;
+            }
+            case phDnldNfc_StateRecv:
+            {
+                wStatus = phDnldNfc_ProcessRecvInfo(pContext,pInfo);
+
+                if(NFCSTATUS_SUCCESS == wStatus)
+                {
+                    /* processing For Pipelined write before calling timer below */
+                    wStatus = phOsalNfc_Timer_Start((pDlCtxt->TimerInfo.dwRspTimerId),
+                                                PHDNLDNFC_RSP_TIMEOUT,
+                                                &phDnldNfc_RspTimeOutCb,
+                                                pDlCtxt);
+
+                    if (NFCSTATUS_SUCCESS == wStatus)
+                    {
+                        NXPLOG_FWDNLD_D("Response timer started");
+                        pDlCtxt->TimerInfo.TimerStatus = 1;
+                        pDlCtxt->tCurrState = phDnldNfc_StateTimer;
+                    }
+                    else
+                    {
+                         NXPLOG_FWDNLD_W("Response timer not started");
+                        pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+                        /* Todo:- diagnostic in this case */
+                    }
+                    /* Call TML_Read function and register the call back function */
+                    wStatus = phTmlNfc_Read(
+                        pDlCtxt->tCmdRspFrameInfo.aFrameBuff,
+                        (uint16_t )PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE,
+                        (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
+                        (void *)pDlCtxt);
+
+                    break;
+                }
+                else
+                {
+                    /* Setting TimerExpStatus below to avoid frame processing in reponse state */
+                    (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
+                    pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+                }
+            }
+            case phDnldNfc_StateTimer:
+            {
+                if (1 == (pDlCtxt->TimerInfo.TimerStatus)) /*Is Timer Running*/
+                {
+                    /* Stop Timer */
+                    (void)phOsalNfc_Timer_Stop(pDlCtxt->TimerInfo.dwRspTimerId);
+                    (pDlCtxt->TimerInfo.TimerStatus) = 0; /*timer stopped*/
+                }
+                pDlCtxt->tCurrState = phDnldNfc_StateResponse;
+            }
+            case phDnldNfc_StateResponse:
+            {
+                if(NFCSTATUS_RF_TIMEOUT != (pDlCtxt->TimerInfo.wTimerExpStatus))
+                {
+                    /* Process response */
+                    wStatus = phDnldNfc_ProcessFrame(pContext,pInfo);
+
+                    if(NFCSTATUS_BUSY == wStatus)
+                    {
+                        /* store the status for use in subsequent processing */
+                        wIntStatus = wStatus;
+
+                        /* setup the resend wait timer */
+                        wStatus = phDnldNfc_SetupResendTimer(pDlCtxt);
+
+                        if(NFCSTATUS_SUCCESS == wStatus)
+                        {
+                            /* restore the last mem_bsy status to avoid re-building frame below */
+                            wStatus = wIntStatus;
+                        }
+                    }
+                }
+                else
+                {
+                    wStatus = (pDlCtxt->TimerInfo.wTimerExpStatus);
+                    (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+                }
+
+                if((0 != (pDlCtxt->tRWInfo.wRemBytes)) && (NFCSTATUS_SUCCESS == wStatus))
+                {
+                    /* Abort TML read operation which is always kept open */
+                    wIntStatus  = phTmlNfc_ReadAbort();
+
+                    if(NFCSTATUS_SUCCESS != wIntStatus)
+                    {
+                         NXPLOG_FWDNLD_W("Tml read abort failed!");
+                    }
+
+                    wStatus = phDnldNfc_BuildFramePkt(pDlCtxt);
+
+                    if(NFCSTATUS_SUCCESS == wStatus)
+                    {
+                        pDlCtxt->tCurrState = phDnldNfc_StateRecv;
+                        wStatus = phTmlNfc_Write((pDlCtxt->tCmdRspFrameInfo.aFrameBuff),
+                            (uint16_t)(pDlCtxt->tCmdRspFrameInfo.dwSendlength),
+                                        (pphTmlNfc_TransactCompletionCb_t)&phDnldNfc_ProcessRWSeqState,
+                                        pDlCtxt);
+
+                        /* TODO:- Verify here if TML_Write returned NFC_PENDING status & take appropriate
+                              action otherwise ?? */
+                    }
+                }
+                else if(NFCSTATUS_BUSY == wStatus)
+                {
+                    /* No processing to be done,since resend wait timer should have already been started */
+                }
+                else
+                {
+                    (pDlCtxt->tRWInfo.bFramesSegmented) = FALSE;
+                    /* Abort TML read operation which is always kept open */
+                    wIntStatus  = phTmlNfc_ReadAbort();
+
+                    if(NFCSTATUS_SUCCESS != wIntStatus)
+                    {
+                         NXPLOG_FWDNLD_W("Tml read abort failed!");
+                    }
+
+                    pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
+                    pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
+                    pDlCtxt->tCurrState = phDnldNfc_StateInit;
+                    pDlCtxt->bResendLastFrame = FALSE;
+
+                    /* Delete the timer & reset timer primitives in context */
+                    (void)phOsalNfc_Timer_Delete(pDlCtxt->TimerInfo.dwRspTimerId);
+                    (pDlCtxt->TimerInfo.dwRspTimerId) = 0;
+                    (pDlCtxt->TimerInfo.TimerStatus) = 0;
+                    (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+
+                    if((NULL != (pDlCtxt->UserCb)) && (NULL != (pDlCtxt->UserCtxt)))
+                    {
+                        pDlCtxt->UserCb((pDlCtxt->UserCtxt),wStatus,&(pDlCtxt->tRspBuffInfo));
+                    }
+                }
+                break;
+            }
+            default:
+            {
+                pDlCtxt->tCurrEvent = phDnldNfc_EventInvalid;
+                pDlCtxt->tDnldInProgress = phDnldNfc_TransitionIdle;
+                break;
+            }
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_BuildFramePkt
+**
+** Description      Forms the frame packet
+**
+** Parameters       pDlContext - pointer to the download context structure
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_BuildFramePkt(pphDnldNfc_DlContext_t pDlContext)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint16_t wFrameLen = 0;
+    uint16_t wCrcVal;
+    uint8_t *pFrameByte;
+
+    if(NULL == pDlContext)
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(phDnldNfc_FTWrite == (pDlContext->FrameInp.Type))
+        {
+            if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
+            {
+                NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Write!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+            }
+            else
+            {
+                if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
+                {
+                    (pDlContext->tRWInfo.wRemBytes) = (pDlContext->tUserData.wLen);
+                    (pDlContext->tRWInfo.wOffset) = 0;
+                }
+            }
+        }
+        else if(phDnldNfc_FTRead == (pDlContext->FrameInp.Type))
+        {
+            if((0 == (pDlContext->tRspBuffInfo.wLen)) || (NULL == (pDlContext->tRspBuffInfo.pBuff)))
+            {
+                NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Read!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+            }
+            else
+            {
+                if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
+                {
+                    NXPLOG_FWDNLD_D("Verifying RspBuffInfo for Read Request..");
+                    wFrameLen = (pDlContext->tRspBuffInfo.wLen) + PHDNLDNFC_MIN_PLD_LEN;
+
+                    (pDlContext->tRWInfo.wRWPldSize) = (PHDNLDNFC_CMDRESP_MAX_PLD_SIZE - PHDNLDNFC_MIN_PLD_LEN);
+                    (pDlContext->tRWInfo.wRemBytes) = (pDlContext->tRspBuffInfo.wLen);
+                    (pDlContext->tRWInfo.dwAddr) = (pDlContext->FrameInp.dwAddr);
+                    (pDlContext->tRWInfo.wOffset) = 0;
+                    (pDlContext->tRWInfo.wBytesRead) = 0;
+
+                    if(PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < wFrameLen)
+                    {
+                        (pDlContext->tRWInfo.bFramesSegmented) = TRUE;
+                    }
+                }
+            }
+        }
+        else if(phDnldNfc_FTLog == (pDlContext->FrameInp.Type))
+        {
+            if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
+            {
+                NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Log!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+            }
+        }
+        else
+        {
+        }
+
+        if(NFCSTATUS_SUCCESS == wStatus)
+        {
+            wStatus = phDnldNfc_CreateFramePld(pDlContext);
+        }
+
+        if(NFCSTATUS_SUCCESS == wStatus)
+        {
+            wFrameLen = 0;
+            wFrameLen  = (pDlContext->tCmdRspFrameInfo.dwSendlength);
+
+            if(phDnldNfc_FTRaw != (pDlContext->FrameInp.Type))
+            {
+                if(phDnldNfc_FTWrite != (pDlContext->FrameInp.Type))
+                {
+                    pFrameByte = (uint8_t *)&wFrameLen;
+
+                    pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1];
+                    pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0];
+
+                    NXPLOG_FWDNLD_D("Inserting FrameId ..");
+                    pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET] =
+                        (pDlContext->tCmdId);
+
+                    wFrameLen += PHDNLDNFC_FRAME_HDR_LEN;
+                }
+                else
+                {
+                    if(0 != (pDlContext->tRWInfo.wRWPldSize))
+                    {
+                        if(TRUE == (pDlContext->tRWInfo.bFramesSegmented))
+                        {
+                            /* Turning ON the Fragmentation bit in FrameLen */
+                            wFrameLen = PHDNLDNFC_SET_HDR_FRAGBIT(wFrameLen);
+                        }
+
+                        pFrameByte = (uint8_t *)&wFrameLen;
+
+                        pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET] = pFrameByte[1];
+                        pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1] = pFrameByte[0];
+
+                        /* To ensure we have no frag bit set for crc calculation */
+                        wFrameLen = PHDNLDNFC_CLR_HDR_FRAGBIT(wFrameLen);
+
+                        wFrameLen += PHDNLDNFC_FRAME_HDR_LEN;
+                    }
+                }
+
+                /* calculate CRC16 */
+                wCrcVal = phDnldNfc_CalcCrc16((pDlContext->tCmdRspFrameInfo.aFrameBuff),wFrameLen);
+
+                pFrameByte = (uint8_t *)&wCrcVal;
+
+                /* Insert the computed Crc value */
+                pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen] = pFrameByte[1];
+                pDlContext->tCmdRspFrameInfo.aFrameBuff[wFrameLen+ 1] = pFrameByte[0];
+
+                wFrameLen += PHDNLDNFC_FRAME_CRC_LEN;
+            }
+
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) = wFrameLen;
+            NXPLOG_FWDNLD_D("Frame created successfully");
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Frame creation failed!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_CreateFramePld
+**
+** Description      Forms the frame payload
+**
+** Parameters       pDlContext - pointer to the download context structure
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_CreateFramePld(pphDnldNfc_DlContext_t pDlContext)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint16_t wBuffIdx = 0;
+    uint16_t wChkIntgVal = 0;
+    uint16_t wFrameLen = 0;
+
+    if(NULL == pDlContext)
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameter!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        memset((pDlContext->tCmdRspFrameInfo.aFrameBuff),0,PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE);
+        (pDlContext->tCmdRspFrameInfo.dwSendlength) = 0;
+
+        if(phDnldNfc_FTNone == (pDlContext->FrameInp.Type))
+        {
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+        }
+        else if(phDnldNfc_ChkIntg == (pDlContext->FrameInp.Type))
+        {
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+
+            wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_OFFSET;
+            memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]),
+                        &wChkIntgVal,sizeof(wChkIntgVal));
+
+            wChkIntgVal = PHDNLDNFC_USERDATA_EEPROM_LEN;
+            memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET +
+                PHDNLDNFC_USERDATA_EEPROM_OFFSIZE]),&wChkIntgVal,sizeof(wChkIntgVal));
+
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_USERDATA_EEPROM_LENSIZE;
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_USERDATA_EEPROM_OFFSIZE;
+        }
+        else if(phDnldNfc_FTWrite == (pDlContext->FrameInp.Type))
+        {
+            wBuffIdx = (pDlContext->tRWInfo.wOffset);
+
+            if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
+            {
+                wFrameLen = (pDlContext->tUserData.pBuff[wBuffIdx]);
+                wFrameLen <<= 8;
+                wFrameLen |= (pDlContext->tUserData.pBuff[wBuffIdx + 1]);
+
+                (pDlContext->tRWInfo.wRWPldSize) = wFrameLen;
+            }
+
+            if((pDlContext->tRWInfo.wRWPldSize) > PHDNLDNFC_CMDRESP_MAX_PLD_SIZE)
+            {
+                if(FALSE == (pDlContext->tRWInfo.bFirstChunkResp))
+                {
+                    (pDlContext->tRWInfo.wRemChunkBytes) = wFrameLen;
+                    (pDlContext->tRWInfo.wOffset) += PHDNLDNFC_FRAME_HDR_LEN;
+                    wBuffIdx = (pDlContext->tRWInfo.wOffset);
+                }
+
+                if(PHDNLDNFC_CMDRESP_MAX_PLD_SIZE < (pDlContext->tRWInfo.wRemChunkBytes))
+                {
+                    (pDlContext->tRWInfo.wBytesToSendRecv) = PHDNLDNFC_CMDRESP_MAX_PLD_SIZE;
+                    (pDlContext->tRWInfo.bFramesSegmented) = TRUE;
+                }
+                else
+                {
+                    (pDlContext->tRWInfo.wBytesToSendRecv) = (pDlContext->tRWInfo.wRemChunkBytes);
+                    (pDlContext->tRWInfo.bFramesSegmented) = FALSE;
+                }
+
+                memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[PHDNLDNFC_FRAMEID_OFFSET]),
+                        &(pDlContext->tUserData.pBuff[wBuffIdx]),(pDlContext->tRWInfo.wBytesToSendRecv));
+            }
+            else
+            {
+                (pDlContext->tRWInfo.wRWPldSize) = 0;
+                (pDlContext->tRWInfo.wBytesToSendRecv) = (wFrameLen + PHDNLDNFC_FRAME_HDR_LEN);
+
+                memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[0]),
+                    &(pDlContext->tUserData.pBuff[wBuffIdx]),(pDlContext->tRWInfo.wBytesToSendRecv));
+            }
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tRWInfo.wBytesToSendRecv);
+        }
+        else if(phDnldNfc_FTRead == (pDlContext->FrameInp.Type))
+        {
+            (pDlContext->tRWInfo.wBytesToSendRecv) = ((pDlContext->tRWInfo.wRemBytes) >
+                    (pDlContext->tRWInfo.wRWPldSize)) ? (pDlContext->tRWInfo.wRWPldSize) :
+                    (pDlContext->tRWInfo.wRemBytes);
+
+            wBuffIdx = (PHDNLDNFC_PLD_OFFSET + ((sizeof(pDlContext->tRWInfo.wBytesToSendRecv))
+                        % PHDNLDNFC_MIN_PLD_LEN) - 1);
+
+            memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+                &(pDlContext->tRWInfo.wBytesToSendRecv),(sizeof(pDlContext->tRWInfo.wBytesToSendRecv)));
+
+            wBuffIdx += sizeof(pDlContext->tRWInfo.wBytesToSendRecv);
+
+            memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+                &(pDlContext->tRWInfo.dwAddr),sizeof(pDlContext->tRWInfo.dwAddr));
+
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += (PHDNLDNFC_MIN_PLD_LEN +
+                (sizeof(pDlContext->tRWInfo.dwAddr)));
+        }
+        else if(phDnldNfc_FTLog == (pDlContext->FrameInp.Type))
+        {
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+
+            wBuffIdx = (PHDNLDNFC_MIN_PLD_LEN + PHDNLDNFC_FRAME_HDR_LEN);
+
+            memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+                (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
+
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tUserData.wLen);
+        }
+        else if(phDnldNfc_FTForce == (pDlContext->FrameInp.Type))
+        {
+            (pDlContext->tCmdRspFrameInfo.dwSendlength) += PHDNLDNFC_MIN_PLD_LEN;
+
+            wBuffIdx = PHDNLDNFC_PLD_OFFSET;
+
+            memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+                (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
+        }
+        else if(phDnldNfc_FTRaw == (pDlContext->FrameInp.Type))
+        {
+            if((0 == (pDlContext->tUserData.wLen)) || (NULL == (pDlContext->tUserData.pBuff)))
+            {
+                NXPLOG_FWDNLD_E("Invalid Input Parameter(s) for Raw Request!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+            }
+            else
+            {
+                memcpy(&(pDlContext->tCmdRspFrameInfo.aFrameBuff[wBuffIdx]),
+                    (pDlContext->tUserData.pBuff),(pDlContext->tUserData.wLen));
+
+                (pDlContext->tCmdRspFrameInfo.dwSendlength) += (pDlContext->tUserData.wLen);
+            }
+        }
+        else
+        {
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ProcessFrame
+**
+** Description      Processes response frame received
+**
+** Parameters       pContext - pointer to the download context structure
+**                  pInfo    - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns          NFCSTATUS_SUCCESS               - parameters successfully validated
+**                  NFCSTATUS_INVALID_PARAMETER     - invalid parameters
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_ProcessFrame(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint16_t wCrcVal,wRecvdCrc,wRecvdLen,wPldLen;
+    pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+    if((NULL == pDlCtxt) ||
+       (NULL == pInfo)
+       )
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if((PH_DL_STATUS_OK != pInfo->wStatus) ||
+            (0 == pInfo->wLength) ||
+            (NULL == pInfo->pBuff))
+        {
+            NXPLOG_FWDNLD_E("Dnld Cmd Request Failed!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+        }
+        else
+        {
+            if(phDnldNfc_FTRaw == (pDlCtxt->FrameInp.Type))
+            {
+              if((0 != (pDlCtxt->tRspBuffInfo.wLen)) &&
+                    (NULL != (pDlCtxt->tRspBuffInfo.pBuff)))
+              {
+                  memcpy((pDlCtxt->tRspBuffInfo.pBuff),(pInfo->pBuff),(pInfo->wLength));
+
+                  (pDlCtxt->tRspBuffInfo.wLen) = (pInfo->wLength);
+              }
+              else
+              {
+                  NXPLOG_FWDNLD_E("Cannot update Response buff with received data!!");
+              }
+            }
+            else
+            {
+                /* calculate CRC16 */
+                wCrcVal = phDnldNfc_CalcCrc16((pInfo->pBuff),((pInfo->wLength) - PHDNLDNFC_FRAME_CRC_LEN));
+
+                wRecvdCrc = 0;
+                wRecvdCrc = (((uint16_t)(pInfo->pBuff[(pInfo->wLength) - 2]) << 8U) |
+                               (pInfo->pBuff[(pInfo->wLength) - 1]));
+
+                if(wRecvdCrc == wCrcVal)
+                {
+                    wRecvdLen = (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET]) << 8U) |
+                               (pInfo->pBuff[PHDNLDNFC_FRAME_HDR_OFFSET + 1]));
+
+                    wPldLen = ((pInfo->wLength) - (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN));
+
+                    if(wRecvdLen != wPldLen)
+                    {
+                        NXPLOG_FWDNLD_E("Invalid frame payload length received");
+                        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+                    }
+                    else
+                    {
+                        wStatus = phDnldNfc_UpdateRsp(pDlCtxt,pInfo,(wPldLen - 1));
+                    }
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Invalid frame received");
+                    wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+                }
+            }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ProcessRecvInfo
+**
+** Description      Processes the response during the state phDnldNfc_StateRecv
+**
+** Parameters       pContext - pointer to the download context structure
+**                  pInfo    - pointer to the Transaction buffer updated by TML Thread
+**
+** Returns          NFCSTATUS_SUCCESS               - parameters successfully validated
+**                  NFCSTATUS_INVALID_PARAMETER     - invalid parameters
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_ProcessRecvInfo(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+    if(NULL != pContext)
+    {
+        if (NULL == pInfo)
+        {
+            NXPLOG_FWDNLD_E("Invalid pInfo received from TML!!");
+            wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+        }
+        else
+        {
+            wStatus = PHNFCSTATUS(pInfo->wStatus);
+
+            if(NFCSTATUS_SUCCESS == wStatus)
+            {
+                NXPLOG_FWDNLD_D("Send Success");
+            }else
+            {
+                NXPLOG_FWDNLD_E("Tml Write error!!");
+                 wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+            }
+        }
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E("Invalid context received from TML!!");
+         wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_FAILED);
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_SetupResendTimer
+**
+** Description      Sets up the timer for resending the previous write frame
+**
+** Parameters       pDlContext - pointer to the download context structure
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_SetupResendTimer(pphDnldNfc_DlContext_t pDlContext)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+    wStatus = phOsalNfc_Timer_Start((pDlContext->TimerInfo.dwRspTimerId),
+                                                PHDNLDNFC_RETRY_FRAME_WRITE,
+                                                &phDnldNfc_ResendTimeOutCb,
+                                                pDlContext);
+
+    if(NFCSTATUS_SUCCESS == wStatus)
+    {
+        NXPLOG_FWDNLD_D("Frame Resend wait timer started");
+        (pDlContext->TimerInfo.TimerStatus) = 1;
+        pDlContext->tCurrState = phDnldNfc_StateTimer;
+    }
+    else
+    {
+         NXPLOG_FWDNLD_W("Frame Resend wait timer not started");
+         (pDlContext->TimerInfo.TimerStatus) = 0;/*timer stopped*/
+         pDlContext->tCurrState = phDnldNfc_StateResponse;
+        /* Todo:- diagnostic in this case */
+    }
+
+    return wStatus;
+}
+
+#if !defined(PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT)
+#   error PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT has to be defined
+#endif
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_RspTimeOutCb
+**
+** Description      Callback function in case of timer expiration
+**
+** Parameters       TimerId  - expired timer id
+**                  pContext - pointer to the download context structure
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phDnldNfc_RspTimeOutCb(uint32_t TimerId, void *pContext)
+{
+    pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+    if (NULL != pDlCtxt)
+    {
+        UNUSED(TimerId);
+
+        if(1 == pDlCtxt->TimerInfo.TimerStatus)
+        {
+            /* No response received and the timer expired */
+            pDlCtxt->TimerInfo.TimerStatus = 0;    /* Reset timer status flag */
+
+            NXPLOG_FWDNLD_D("%x",pDlCtxt->tLastStatus);
+
+#if PH_LIBNFC_VEN_RESET_ON_DOWNLOAD_TIMEOUT
+            if ( PH_DL_STATUS_SIGNATURE_ERROR  == pDlCtxt->tLastStatus ) {
+                /* Do a VEN Reset of the chip. */
+                NXPLOG_FWDNLD_E("Performing a VEN Reset");
+                phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
+                phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+                NXPLOG_FWDNLD_E("VEN Reset Done");
+            }
+#endif
+
+
+            (pDlCtxt->TimerInfo.wTimerExpStatus) = NFCSTATUS_RF_TIMEOUT;
+
+            if((phDnldNfc_EventRead == pDlCtxt->tCurrEvent) || (phDnldNfc_EventWrite == pDlCtxt->tCurrEvent))
+            {
+                phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
+            }
+            else
+            {
+                phDnldNfc_ProcessSeqState(pDlCtxt,NULL);
+            }
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_ResendTimeOutCb
+**
+** Description      Callback function in case of Frame Resend Wait timer expiration
+**
+** Parameters       TimerId  - expired timer id
+**                  pContext - pointer to the download context structure
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phDnldNfc_ResendTimeOutCb(uint32_t TimerId, void *pContext)
+{
+    pphDnldNfc_DlContext_t pDlCtxt = (pphDnldNfc_DlContext_t)pContext;
+
+    if (NULL != pDlCtxt)
+    {
+        UNUSED(TimerId);
+
+        if(1 == pDlCtxt->TimerInfo.TimerStatus)
+        {
+            /* No response received and the timer expired */
+            pDlCtxt->TimerInfo.TimerStatus = 0;    /* Reset timer status flag */
+
+            (pDlCtxt->TimerInfo.wTimerExpStatus) = 0;
+
+             pDlCtxt->tCurrState = phDnldNfc_StateSend;
+
+             /* set the flag to trigger last frame re-transmission */
+             pDlCtxt->bResendLastFrame = TRUE;
+
+             phDnldNfc_ProcessRWSeqState(pDlCtxt,NULL);
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_UpdateRsp
+**
+** Description      verifies the payload status byte and copies data
+**                  to response buffer if successful
+**
+** Parameters       pDlContext - pointer to the download context structure
+**                  pInfo      - pointer to the Transaction buffer updated by TML Thread
+**                  wPldLen    - Length of the payload bytes to copy to response buffer
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phDnldNfc_UpdateRsp(pphDnldNfc_DlContext_t   pDlContext, phTmlNfc_TransactInfo_t  *pInfo, uint16_t wPldLen)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint16_t wReadLen = 0;
+
+    if((NULL == pDlContext) || (NULL == pInfo))
+    {
+        NXPLOG_FWDNLD_E("Invalid Input Parameters!!");
+        wStatus = PHNFCSTVAL(CID_NFC_DNLD,NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        if(PH_DL_CMD_WRITE == (pDlContext->tCmdId))
+        {
+            if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                /* first write frame response received case */
+                if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
+                {
+                    NXPLOG_FWDNLD_D("First Write Frame Success Status received!!");
+                    (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
+                }
+
+                if(TRUE == (pDlContext->tRWInfo.bFirstChunkResp))
+                {
+                    if(FALSE == (pDlContext->tRWInfo.bFramesSegmented))
+                    {
+                        NXPLOG_FWDNLD_D("Chunked Write Frame Success Status received!!");
+                        (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+                        (pDlContext->tRWInfo.bFirstChunkResp) = FALSE;
+                    }
+                    else
+                    {
+                        NXPLOG_FWDNLD_E("UnExpected Status received!!");
+                        wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
+                    }
+                }
+
+                if(NFCSTATUS_SUCCESS == wStatus)
+                {
+                    (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+                    (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+                }
+            }
+            else if((FALSE == (pDlContext->tRWInfo.bFirstChunkResp)) &&
+                (TRUE == (pDlContext->tRWInfo.bFramesSegmented)) &&
+                (PHDNLDNFC_FIRST_FRAGFRAME_RESP == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])))
+            {
+                (pDlContext->tRWInfo.bFirstChunkResp) = TRUE;
+                (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+                (pDlContext->tRWInfo.wRemBytes) -= ((pDlContext->tRWInfo.wBytesToSendRecv) + PHDNLDNFC_FRAME_HDR_LEN);
+                (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+
+                /* first write frame response received case */
+                if(TRUE == (pDlContext->tRWInfo.bFirstWrReq))
+                {
+                    NXPLOG_FWDNLD_D("First Write Frame Success Status received!!");
+                    (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
+                }
+            }
+            else if((TRUE == (pDlContext->tRWInfo.bFirstChunkResp)) &&
+                (TRUE == (pDlContext->tRWInfo.bFramesSegmented)) &&
+                (PHDNLDNFC_NEXT_FRAGFRAME_RESP == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET])))
+            {
+                (pDlContext->tRWInfo.wRemChunkBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+                (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+                (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+            }
+            else if(PH_DL_STATUS_FIRMWARE_VERSION_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                NXPLOG_FWDNLD_E("Firmware Already Up To Date!!");
+                (pDlContext->tRWInfo.bFirstWrReq) = FALSE;
+                /* resetting wRemBytes to 0 to avoid any further write frames send */
+                (pDlContext->tRWInfo.wRemBytes) = 0;
+                (pDlContext->tRWInfo.wOffset) = 0;
+                wStatus = NFCSTATUS_SUCCESS;
+            }
+            else if(PH_DL_STATUS_PLL_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                NXPLOG_FWDNLD_E("PLL Error Status received!!");
+                (pDlContext->tLastStatus) = PH_DL_STATUS_PLL_ERROR;
+                wStatus = NFCSTATUS_WRITE_FAILED;
+            }
+            else if(PH_DL_STATUS_SIGNATURE_ERROR == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                NXPLOG_FWDNLD_E("Signature Mismatch Error received!!");
+                /* save the status for use in loading the relevant recovery image (either signature or platform) */
+                (pDlContext->tLastStatus) = PH_DL_STATUS_SIGNATURE_ERROR;
+                wStatus = NFCSTATUS_REJECTED;
+            }
+            else if(PH_DL_STATUS_MEM_BSY == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                NXPLOG_FWDNLD_E("Mem Busy Status received!!");
+                (pDlContext->tLastStatus) = PH_DL_STATUS_MEM_BSY;
+                wStatus = NFCSTATUS_BUSY;
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Unsuccessful Status received!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
+            }
+        }
+        else if(PH_DL_CMD_READ == (pDlContext->tCmdId))
+        {
+            if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                wReadLen = (((uint16_t)(pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 3]) << 8U) |
+                           (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 2]));
+
+                if(wReadLen != (pDlContext->tRWInfo.wBytesToSendRecv))
+                {
+                    NXPLOG_FWDNLD_E("Desired Length bytes not received!!");
+                    wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
+                }
+                else
+                {
+                    memcpy(&(pDlContext->tRspBuffInfo.pBuff[(pDlContext->tRWInfo.wOffset)]),
+                        &(pInfo->pBuff[PHDNLDNFC_FRAME_RDDATA_OFFSET]),
+                        wReadLen);
+
+                    (pDlContext->tRWInfo.wBytesRead) += wReadLen;
+
+                    (pDlContext->tRspBuffInfo.wLen) = (pDlContext->tRWInfo.wBytesRead);
+
+                    (pDlContext->tRWInfo.wRemBytes) -= (pDlContext->tRWInfo.wBytesToSendRecv);
+                    (pDlContext->tRWInfo.dwAddr) += (pDlContext->tRWInfo.wBytesToSendRecv);
+                    (pDlContext->tRWInfo.wOffset) += (pDlContext->tRWInfo.wBytesToSendRecv);
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Unsuccessful Status received!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
+            }
+        }
+        else
+        {
+            if(PH_DL_STATUS_OK == (pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET]))
+            {
+                if((0 != (pDlContext->tRspBuffInfo.wLen)) &&
+                    (NULL != (pDlContext->tRspBuffInfo.pBuff)))
+                {
+                    memcpy((pDlContext->tRspBuffInfo.pBuff),&(pInfo->pBuff[PHDNLDNFC_FRAMESTATUS_OFFSET + 1]),
+                        wPldLen);
+
+                    (pDlContext->tRspBuffInfo.wLen) = wPldLen;
+                }
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Unsuccessful Status received!!");
+                wStatus = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FAILED);
+            }
+        }
+    }
+
+    return wStatus;
+}
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Internal.h b/halimpl/pn54x/dnld/phDnldNfc_Internal.h
new file mode 100644
index 0000000..c6d7834
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Internal.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Internal Primitives (Functions + Variables) used for Firmware Download
+ */
+#ifndef PHDNLDNFC_INTERNAL_H
+#define PHDNLDNFC_INTERNAL_H
+
+#include <phDnldNfc.h>
+#include <phDnldNfc_Cmd.h>
+#include <phDnldNfc_Status.h>
+
+#define PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE   (0x100U)  /* DL Host Frame Buffer Size for all CMD/RSP
+                                                         except pipelined WRITE */
+#if ( PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE > PHNFC_I2C_FRAGMENT_SIZE )
+#undef PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE
+#define PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE   (PHNFC_I2C_FRAGMENT_SIZE)
+#endif
+
+#define PHDNLDNFC_WRITERSP_BUFF_SIZE  (0x08U)   /* DL Host Short Frame Buffer Size for pipelined WRITE RSP */
+
+#define PHDNLDNFC_FRAME_HDR_LEN  (0x02U)   /* DL Host Frame Buffer Header Length */
+#define PHDNLDNFC_FRAME_CRC_LEN  (PHDNLDNFC_FRAME_HDR_LEN)   /* DL Host Frame Buffer CRC Length */
+#define PHDNLDNFC_FRAME_ID_LEN   (0x01U)    /* Length of Cmd Id */
+
+#define PHDNLDNFC_EEFL_ADDR_SIZE          (0x03U)      /* size of EEPROM/Flash address */
+#define PHDNLDNFC_DATA_SIZE               (PHDNLDNFC_FRAME_HDR_LEN)      /* 2 Byte size of data */
+
+#define PHDNLDNFC_EEPROM_LOG_START_ADDR   (0x201F80U)   /* Start of EEPROM address for log */
+#define PHDNLDNFC_EEPROM_LOG_END_ADDR     (0x201FBFU)   /* End of EEPROM address for log */
+
+#define PHDNLDNFC_MAX_LOG_SIZE        ((PHDNLDNFC_EEPROM_LOG_END_ADDR - PHDNLDNFC_EEPROM_LOG_START_ADDR) + 1)
+
+/* DL Max Payload Size */
+#define PHDNLDNFC_CMDRESP_MAX_PLD_SIZE    ((PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE) - \
+                                          (PHDNLDNFC_FRAME_HDR_LEN + PHDNLDNFC_FRAME_CRC_LEN))
+
+/*
+ * Enum definition contains Download Event Types
+ */
+typedef enum phDnldNfc_Event{
+    phDnldNfc_EventInvalid = 0x00,   /*Invalid Event Value*/
+    phDnldNfc_EventReset,            /* Reset event */
+    phDnldNfc_EventGetVer,           /* Get Version event*/
+    phDnldNfc_EventWrite,            /* Write event*/
+    phDnldNfc_EventRead,             /* Read event*/
+    phDnldNfc_EventIntegChk,         /* Integrity Check event*/
+    phDnldNfc_EventGetSesnSt,        /* Get Session State event*/
+    phDnldNfc_EventLog,              /* Log event*/
+    phDnldNfc_EventForce,            /* Force event*/
+    phDnldNfc_EventRaw,              /* Raw Req/Rsp event,used currently for sending NCI RESET cmd */
+    phDnldNfc_EVENT_INT_MAX          /* Max Event Count*/
+}phDnldNfc_Event_t;
+
+/*
+ * Enum definition contains Download Handler states for each event requested
+ */
+typedef enum phDnldNfc_State{
+    phDnldNfc_StateInit=0x00,        /* Handler init state */
+    phDnldNfc_StateSend,             /* Send frame to NFCC state */
+    phDnldNfc_StateRecv,             /* Recv Send complete State */
+    phDnldNfc_StateTimer,            /* State to stop prev set timer on Recv or handle timed out scenario */
+    phDnldNfc_StateResponse,         /* Process response from NFCC state */
+    phDnldNfc_StatePipelined,        /* Write requests to be pipelined state */
+    phDnldNfc_StateInvalid           /* Invalid Handler state */
+}phDnldNfc_State_t;
+
+/*
+ * Enum definition contains Download Handler Transition
+ */
+typedef enum phDnldNfc_Transition{
+    phDnldNfc_TransitionIdle = 0x00,      /* Handler in Idle state - No Download in progress */
+    phDnldNfc_TransitionBusy,             /* Handler is busy processing download request */
+    phDnldNfc_TransitionInvalid           /* Invalid Handler Transition */
+}phDnldNfc_Transition_t;
+
+/*
+ * Enum definition contains the Frame input type for CmdId in process
+ */
+ typedef enum
+ {
+     phDnldNfc_FTNone = 0,     /* input type None */
+     phDnldNfc_ChkIntg,        /* user eeprom offset & len to be added for Check Integrity Request */
+     phDnldNfc_FTWrite,        /* Frame inputs for Write request */
+     phDnldNfc_FTLog,          /* Frame inputs for Log request */
+     phDnldNfc_FTForce,        /* Frame input for Force cmd request */
+     phDnldNfc_FTRead,         /* Addr input required for read request */
+     phDnldNfc_FTRaw           /* Raw Req/Rsp type */
+}phDnldNfc_FrameInputType_t;
+
+/*
+ * Contains Host Frame Buffer information.
+ */
+typedef struct phDnldNfc_FrameInfo
+{
+    uint16_t dwSendlength;                                  /* length of the payload  */
+    uint8_t aFrameBuff[PHDNLDNFC_CMDRESP_MAX_BUFF_SIZE];    /* Buffer to store command that needs to be sent*/
+}phDnldNfc_FrameInfo_t,*pphDnldNfc_FrameInfo_t; /* pointer to #phDnldNfc_FrameInfo_t */
+
+/*
+ * Frame Input Type & Value for CmdId in Process
+ */
+typedef struct phDnldNfc_FrameInput
+{
+    phDnldNfc_FrameInputType_t Type;   /* Type of frame input required for current cmd in process */
+    uint32_t  dwAddr;       /* Address value required for Read/Write Cmd*/
+}phDnldNfc_FrameInput_t, *pphDnldNfc_FrameInput_t;/* pointer to #phDnldNfc_FrameInput_t */
+
+/*
+ * Context for the response timeout
+ */
+typedef struct phDnldNfc_RspTimerInfo
+{
+    uint32_t   dwRspTimerId;                  /* Timer for Core to handle response */
+    uint8_t    TimerStatus;                   /* 0 = Timer not running 1 = timer running*/
+    NFCSTATUS  wTimerExpStatus;               /* Holds the status code on timer expiry */
+}phDnldNfc_RspTimerInfo_t;
+
+/*
+ * Read/Write Processing Info
+ */
+typedef struct phDnldNfc_RWInfo
+{
+    uint32_t  dwAddr;                /* current Addr updated for read/write */
+    uint16_t  wOffset;               /* current offset within the user buffer to read/write */
+    uint16_t  wRemBytes;             /* Remaining bytes to read/write */
+    uint16_t  wRemChunkBytes;        /* Remaining bytes within the chunked frame */
+    uint16_t  wRWPldSize;            /* Size of the read/write payload per transaction */
+    uint16_t  wBytesToSendRecv;      /* Num of Bytes being written/read currently */
+    uint16_t  wBytesRead;            /* Bytes read from read cmd currently */
+    bool_t    bFramesSegmented;      /* Flag to indicate if Read/Write frames are segmented */
+    bool_t    bFirstWrReq;           /* Flag to indicate if this is the first write frame being sent */
+    bool_t    bFirstChunkResp;       /* Flag to indicate if we got the first chunk response */
+}phDnldNfc_RWInfo_t, *pphDnldNfc_RWInfo_t;/* pointer to #phDnldNfc_RWInfo_t */
+
+/*
+ * Download context structure
+ */
+typedef struct phDnldNfc_DlContext
+{
+    const uint8_t           *nxp_nfc_fw;           /* Pointer to firmware version from image */
+    const uint8_t           *nxp_nfc_fwp;          /* Pointer to firmware version from get_version cmd */
+    uint16_t                nxp_nfc_fwp_len;       /* Length of firmware image length */
+    uint16_t                nxp_nfc_fw_len;        /* Firmware image length */
+    bool_t                  bResendLastFrame;      /* Flag to resend the last write frame after MEM_BSY status */
+    phDnldNfc_Transition_t  tDnldInProgress;       /* Flag to indicate if download request is ongoing */
+    phDnldNfc_Event_t       tCurrEvent;            /* Current event being processed */
+    phDnldNfc_State_t       tCurrState;            /* Current state being processed */
+    pphDnldNfc_RspCb_t      UserCb    ;            /* Upper layer call back function */
+    void*                   UserCtxt  ;            /* Pointer to upper layer context */
+    phDnldNfc_Buff_t        tUserData;             /* Data buffer provided by caller */
+    phDnldNfc_Buff_t        tRspBuffInfo;          /* Buffer to store payload field of the received response*/
+    phDnldNfc_FrameInfo_t   tCmdRspFrameInfo;      /* Buffer to hold the cmd/resp frame except pipeline write */
+    phDnldNfc_FrameInfo_t   tPipeLineWrFrameInfo;  /* Buffer to hold the pipelined write frame */
+    NFCSTATUS  wCmdSendStatus;                     /* Holds the status of cmd request made to cmd handler */
+    phDnldNfc_CmdId_t       tCmdId;                /* Cmd Id of the currently processed cmd */
+    phDnldNfc_FrameInput_t  FrameInp;              /* input value required for current cmd in process */
+    phDnldNfc_RspTimerInfo_t TimerInfo;            /* Timer context handled into download context*/
+    phDnldNfc_Buff_t        tTKey;                 /* Defualt Transport Key provided by caller */
+    phDnldNfc_RWInfo_t      tRWInfo;               /* Read/Write segmented frame info */
+    phDnldNfc_Status_t      tLastStatus;           /* saved status to distinguish signature or pltform recovery */
+}phDnldNfc_DlContext_t,*pphDnldNfc_DlContext_t; /* pointer to #phDnldNfc_DlContext_t structure */
+
+/* The phDnldNfc_CmdHandler function declaration */
+extern NFCSTATUS phDnldNfc_CmdHandler(void *pContext, phDnldNfc_Event_t TrigEvent);
+
+#endif /* PHDNLDNFC_INTERNAL_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Status.h b/halimpl/pn54x/dnld/phDnldNfc_Status.h
new file mode 100644
index 0000000..59747d9
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Status.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Firmware Download Status Values
+ */
+#ifndef PHDNLDNFC_STATUS_H
+#define PHDNLDNFC_STATUS_H
+
+#include <phNfcStatus.h>
+
+/* reusing LibNfcStatus.h value below as a placeholder for now, need to find
+   the right value */
+#define NFCSTATUS_ABORTED                   (0x0096)   /* Command aborted */
+
+/*
+ * Enum definition contains Firmware Download Status codes
+ */
+typedef enum phDnldNfc_Status
+{
+    PH_DL_STATUS_PLL_ERROR                        = 0x0D,
+    PH_DL_STATUS_LC_WRONG                         = 0x13,
+    PH_DL_STATUS_LC_TERMINATION_NOT_SUPPORTED     = 0x14,
+    PH_DL_STATUS_LC_CREATION_NOT_SUPPORTED        = 0x15,
+    PH_DL_STATUS_LC_UNKNOWN                       = 0x16,
+    PH_DL_STATUS_AUTHENTICATION_ERROR             = 0x19,
+    PH_DL_STATUS_NOT_AUTHENTICATED                = 0x1A,
+    PH_DL_STATUS_AUTHENTICATION_LOST              = 0x1B,
+    PH_DL_STATUS_WRITE_PROTECTED                  = 0x1C,
+    PH_DL_STATUS_READ_PROTECTED                   = 0x1D,
+    PH_DL_STATUS_ADDR_RANGE_OFL_ERROR             = 0x1E,
+    PH_DL_STATUS_BUFFER_OFL_ERROR                 = 0x1F,
+    PH_DL_STATUS_MEM_BSY                          = 0x20,
+    PH_DL_STATUS_SIGNATURE_ERROR                  = 0x21,
+    PH_DL_STATUS_SESSION_WAS_OPEN                 = 0x22,
+    PH_DL_STATUS_SESSION_WAS_CLOSED               = 0x23,
+    /* the Firmware version passed to CommitSession is not greater than
+        the EEPROM resident stored Firmware version number */
+    PH_DL_STATUS_FIRMWARE_VERSION_ERROR           = 0x24,
+    PH_DL_STATUS_LOOPBACK_DATA_MISSMATCH_ERROR    = 0x25,
+      /*****************************/
+    PH_DL_STATUS_HOST_PAYLOAD_UFL_ERROR           = 0x26,
+    PH_DL_STATUS_HOST_PAYLOAD_OFL_ERROR           = 0x27,
+    PH_DL_STATUS_PROTOCOL_ERROR                   = 0x28,
+      /* Download codes re-mapped to generic entries */
+    PH_DL_STATUS_INVALID_ADDR                     = NFCSTATUS_INVALID_PARAMETER,
+    PH_DL_STATUS_GENERIC_ERROR                    = NFCSTATUS_FAILED,
+    PH_DL_STATUS_ABORTED_CMD                      = NFCSTATUS_ABORTED,
+    PH_DL_STATUS_FLASH_WRITE_PROTECTED            = PH_DL_STATUS_WRITE_PROTECTED,
+    PH_DL_STATUS_FLASH_READ_PROTECTED             = PH_DL_STATUS_READ_PROTECTED,
+    PH_DL_STATUS_USERDATA_WRITE_PROTECTED         = PH_DL_STATUS_WRITE_PROTECTED,
+    PH_DL_STATUS_USERDATA_READ_PROTECTED          = PH_DL_STATUS_READ_PROTECTED,
+    PH_DL_STATUS_OK                               = NFCSTATUS_SUCCESS
+} phDnldNfc_Status_t ;
+
+#endif /* PHDNLDNFC_STATUS_H */
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Utils.c b/halimpl/pn54x/dnld/phDnldNfc_Utils.c
new file mode 100644
index 0000000..d1c84ff
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Utils.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Download Component
+ * Download Utility routines implementation
+ */
+
+#include <phDnldNfc_Utils.h>
+#include <phNxpLog.h>
+
+static uint16_t const aCrcTab[256] =
+{ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad,
+  0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
+  0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+  0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7,
+  0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5,
+  0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a,
+  0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e,
+  0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae,
+  0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32,
+  0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca,
+  0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+  0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235,
+  0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3,
+  0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d,
+  0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f,
+  0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d,
+  0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0,
+  0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64,
+  0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+  0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 };
+
+/*******************************************************************************
+**
+** Function         phDnldNfc_CalcCrc16
+**
+** Description      Calculates CRC16 for the frame buffer
+**
+** Parameters       pBuff - CRC16 calculation input buffer
+**                  wLen  - input buffer length
+**
+** Returns          wCrc  - computed 2 byte CRC16 value
+**
+*******************************************************************************/
+uint16_t phDnldNfc_CalcCrc16(uint8_t* pBuff, uint16_t wLen)
+{
+    uint16_t wTmp;
+    uint16_t wValue;
+    uint16_t wCrc = 0xffff;
+    uint32_t i;
+
+
+    if((NULL == pBuff) || (0 == wLen))
+    {
+        NXPLOG_FWDNLD_W("Invalid Params supplied!!");
+    }
+    else
+    {
+        /* Perform CRC calculation according to ccitt with a initial value of 0x1d0f */
+        for (i = 0; i < wLen; i++)
+        {
+           wValue = 0x00ffU & (uint16_t) pBuff[i];
+           wTmp = (wCrc >> 8U) ^ wValue;
+           wCrc = (wCrc << 8U) ^ aCrcTab[wTmp];
+        }
+    }
+
+    return wCrc;
+}
diff --git a/halimpl/pn54x/dnld/phDnldNfc_Utils.h b/halimpl/pn54x/dnld/phDnldNfc_Utils.h
new file mode 100644
index 0000000..4b4e2af
--- /dev/null
+++ b/halimpl/pn54x/dnld/phDnldNfc_Utils.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Firmware Download Utilities File
+ */
+#ifndef PHDNLDNFC_UTILS_H
+#define PHDNLDNFC_UTILS_H
+
+#include <phDnldNfc.h>
+
+extern uint16_t phDnldNfc_CalcCrc16(uint8_t* pBuff, uint16_t wLen);
+
+#endif /* PHDNLDNFC_UTILS_H */
diff --git a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
new file mode 100644
index 0000000..c8acb13
--- /dev/null
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.c
@@ -0,0 +1,1945 @@
+/*
+ * Copyright (C) 2012-2014 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 <phTmlNfc.h>
+#include <phDnldNfc.h>
+#include <phNxpNciHal_Dnld.h>
+#include <phNxpNciHal_utils.h>
+#include <phNxpLog.h>
+#include <phNxpConfig.h>
+
+/* Macro */
+#define PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS 3
+#define PHLIBNFC_IOCTL_DNLD_GETVERLEN          (0x0BU)
+#define PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1   (0x09U)
+#define PHLIBNFC_DNLD_MEM_READ (0xECU)
+#define PHLIBNFC_DNLD_MEM_WRITE (0xEDU)
+#define PHLIBNFC_DNLD_READ_LOG  (0xEEU)
+#define NFC_MEM_READ (0xD0U)
+#define NFC_MEM_WRITE (0xD1U)
+#define NFC_FW_DOWNLOAD (0x09F7U)
+
+/* External global variable to get FW version */
+extern uint16_t wFwVer;
+extern uint16_t wMwVer;
+
+/* RF Configuration structure */
+typedef struct phLibNfc_IoctlSetRfConfig
+{
+    uint8_t  bNumOfParams;    /* Number of Rf configurable parameters to be set */
+    uint8_t  *pInputBuffer;   /* Buffer containing Rf configurable parameters */
+    uint8_t  bSetSysPmuFlag;  /* Flag to decide wether to set SystemPmu or no from the first byte */
+}phLibNfc_IoctlSetRfConfig;
+
+/* Structure to hold information from EEPROM */
+typedef struct phLibNfc_EELogParams
+{
+    uint16_t     wCurrMwVer;        /* Holds current MW version on the chip */
+    uint16_t     wCurrFwVer;        /* Holds current FW version on the chip */
+    uint16_t     wNumDnldTrig;      /* Total number of times dnld has been attempted */
+    uint16_t     wNumDnldSuccess;   /* Total number of times dnld has been successful */
+    uint16_t     wNumDnldFail;      /* Total number of times dnld has Failed */
+    uint16_t     wDnldFailCnt;      /* holds the number of times dnld has failed,will be reset on success */
+    bool_t       bConfig;           /* Flag to be set in dnld mode after successful dnld,to be reset in NCI Mode
+                                      after setting the NCI configuration */
+} phLibNfc_EELogParams_t;
+
+/* FW download module context structure */
+typedef struct
+{
+    bool_t                       bDnldEepromWrite;  /* Flag to indicate eeprom write request*/
+    bool_t                       bSkipSeq;       /* Flag to indicate FW download sequence to be skipped or not */
+    bool_t                       bSkipReset;     /* Flag to indicate Reset cmd to be skipped or not in FW download sequence */
+    bool_t                       bSkipForce;     /* Flag to indicate Force cmd to be skipped or not in FW recovery sequence */
+    bool_t                       bPrevSessnOpen; /* Flag to indicate previous download session is open or not */
+    bool_t                       bLibNfcCtxtMem; /* flag to indicate if mem was allocated for gpphLibNfc_Context */
+    bool_t                       bDnldInitiated; /* Flag to indicate if fw upgrade was initiated */
+    bool_t                       bSendNciCmd;    /* Flag to indicate if NCI cmd to be sent or not,after PKU */
+    uint8_t                      bChipVer;       /* holds the hw chip version */
+    bool_t                       bDnldRecovery;  /* Flag to indicate if dnld recovery sequence needs to be triggered */
+    bool_t                       bForceDnld;     /* Flag to indicate if forced download option is enabled */
+    bool_t                       bRetryDnld;     /* Flag to indicate retry download after successful recovery complete */
+    uint8_t                      bDnldAttempts;  /* Holds the count of no. of dnld attempts made.max 3 */
+    uint16_t                     IoctlCode;      /* Ioctl code*/
+    bool_t                       bDnldAttemptFailed;  /* Flag to indicate last download attempt failed */
+    NFCSTATUS                    bLastStatus;    /* Holds the actual download write attempt status */
+    phLibNfc_EELogParams_t       tLogParams;     /* holds the params that could be logged to reserved EE address */
+    uint8_t                      bClkSrcVal;     /* Holds the System clock source read from config file */
+    uint8_t                      bClkFreqVal;    /* Holds the System clock frequency read from config file */
+} phNxpNciHal_fw_Ioctl_Cntx_t;
+
+
+/* Global variables used in this file only*/
+static phNxpNciHal_fw_Ioctl_Cntx_t gphNxpNciHal_fw_IoctlCtx;
+
+/* Local function prototype */
+static NFCSTATUS
+phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_get_version_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_get_version(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_get_sessn_state(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_chk_integrity(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status, void* pInfo);
+
+static void
+phNxpNciHal_fw_dnld_send_ncicmd_Cb(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status, void* pInfo);
+
+static NFCSTATUS
+phNxpNciHal_fw_dnld_complete(void* pContext, NFCSTATUS status, void* pInfo);
+
+/** Internal function to verify Crc Status byte received during CheckIntegrity */
+static NFCSTATUS
+phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus);
+
+static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
+        void* pInfo);
+
+static NFCSTATUS phNxpNciHal_fw_seq_handler(NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo));
+
+/* Array of pointers to start fw download seq */
+static NFCSTATUS (*phNxpNciHal_dwnld_seqhandler[])(
+        void* pContext, NFCSTATUS status, void* pInfo) = {
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+    phNxpNciHal_fw_dnld_normal,
+    phNxpNciHal_fw_dnld_normal,
+#endif
+    phNxpNciHal_fw_dnld_get_sessn_state,
+    phNxpNciHal_fw_dnld_get_version,
+    phNxpNciHal_fw_dnld_log_read,
+    phNxpNciHal_fw_dnld_write,
+    phNxpNciHal_fw_dnld_get_sessn_state,
+    phNxpNciHal_fw_dnld_get_version,
+    phNxpNciHal_fw_dnld_log,
+    phNxpNciHal_fw_dnld_chk_integrity,
+    NULL
+};
+
+/* Download Recovery Sequence */
+static NFCSTATUS (*phNxpNciHal_dwnld_rec_seqhandler[])(
+        void* pContext, NFCSTATUS status, void* pInfo) = {
+    phNxpNciHal_fw_dnld_reset,
+    phNxpNciHal_fw_dnld_force,
+    phNxpNciHal_fw_dnld_recover,
+    phNxpNciHal_fw_dnld_send_ncicmd,
+    NULL
+};
+
+/* Download Log Sequence */
+static NFCSTATUS (*phNxpNciHal_dwnld_log_seqhandler[])(
+        void* pContext, NFCSTATUS status, void* pInfo) = {
+    phNxpNciHal_fw_dnld_log,
+    NULL
+};
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_reset_cb
+**
+** Description      Download Reset callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_reset_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    UNUSED(pInfo);
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_reset_cb - Request Successful");
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset_cb - Request Failed!!");
+    }
+    p_cb_data->status = status;
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_reset
+**
+** Description      Download Reset
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_reset(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || (TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipReset)))
+    {
+        if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipReset))
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE;
+        }
+        return NFCSTATUS_SUCCESS;
+    }
+
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data  failed");
+        return NFCSTATUS_FAILED;
+    }
+    wStatus = phDnldNfc_Reset((pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_reset_cb, (void*) &cb_data);
+
+    if (wStatus != NFCSTATUS_PENDING)
+    {
+        NXPLOG_FWDNLD_E("phDnldNfc_Reset failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_normal_cb
+**
+** Description      Download Normal callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_normal_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    UNUSED(pInfo);
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_normal_cb - Request Successful");
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal_cb - Request Failed!!");
+        /* In this fail scenario trick the sequence handler to call next recover sequence */
+        status = NFCSTATUS_SUCCESS;
+    }
+    p_cb_data->status = status;
+
+    SEM_POST(p_cb_data);
+    usleep(1000 * 10);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_force_cb
+**
+** Description      Download Force callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_force_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    UNUSED(pInfo);
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_FWDNLD_D("phLibNfc_DnldForceCb - Request Successful");
+        (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+        (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = TRUE;
+    }
+    else
+    {
+        /* In this fail scenario trick the sequence handler to call next recover sequence */
+        status = NFCSTATUS_SUCCESS;
+        NXPLOG_FWDNLD_E("phLibNfc_DnldForceCb - Request Failed!!");
+
+    }
+    p_cb_data->status = status;
+
+    SEM_POST(p_cb_data);
+    usleep(1000 * 10);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_normal
+**
+** Description      Download Normal
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_normal(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint8_t bClkVal[2];
+    phDnldNfc_Buff_t tData;
+    phNxpNciHal_Sem_t cb_data;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+    else
+    {
+        /*
+        bClkVal[0] = NXP_SYS_CLK_SRC_SEL;
+        bClkVal[1] = NXP_SYS_CLK_FREQ_SEL;
+        */
+        bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal;
+        bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal;
+
+        (tData.pBuff) = bClkVal;
+        (tData.wLen) = sizeof(bClkVal);
+
+        if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+        }
+
+        if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data  failed");
+            return NFCSTATUS_FAILED;
+        }
+        wStatus = phDnldNfc_Force(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_normal_cb, (void*) &cb_data);
+
+        if(NFCSTATUS_PENDING != wStatus)
+        {
+            NXPLOG_FWDNLD_E("phDnldNfc_Normal failed");
+            (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+            goto clean_and_return;
+        }
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_normal cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_force
+**
+** Description      Download Force
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_force(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    uint8_t bClkVal[2];
+    phDnldNfc_Buff_t tData;
+    phNxpNciHal_Sem_t cb_data;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+    else
+    {
+        /*
+        bClkVal[0] = NXP_SYS_CLK_SRC_SEL;
+        bClkVal[1] = NXP_SYS_CLK_FREQ_SEL;
+        */
+        bClkVal[0] = gphNxpNciHal_fw_IoctlCtx.bClkSrcVal;
+        bClkVal[1] = gphNxpNciHal_fw_IoctlCtx.bClkFreqVal;
+
+        (tData.pBuff) = bClkVal;
+        (tData.wLen) = sizeof(bClkVal);
+
+        if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+        }
+
+        if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_reset Create dnld_cb_data  failed");
+            return NFCSTATUS_FAILED;
+        }
+        wStatus = phDnldNfc_Force(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_force_cb, (void*) &cb_data);
+
+        if(NFCSTATUS_PENDING != wStatus)
+        {
+            NXPLOG_FWDNLD_E("phDnldNfc_Force failed");
+            (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+            goto clean_and_return;
+        }
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_force cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_get_version_cb
+**
+** Description      Download Get version callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_get_version_cb(void* pContext,
+        NFCSTATUS status, void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS wStatus = status;
+    pphDnldNfc_Buff_t   pRespBuff;
+    uint16_t wFwVern = 0;
+    uint16_t wMwVern = 0;
+    uint8_t bHwVer = 0;
+    uint8_t bExpectedLen = 0;
+    uint8_t bNewVer[2];
+    uint8_t bCurrVer[2];
+
+    if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo))
+    {
+        NXPLOG_FWDNLD_D ("phNxpNciHal_fw_dnld_get_version_cb - Request Successful");
+
+        pRespBuff = (pphDnldNfc_Buff_t) pInfo;
+
+        if ((0 != pRespBuff->wLen) && (NULL != pRespBuff->pBuff))
+        {
+            bHwVer = (pRespBuff->pBuff[0]);
+            bHwVer &= 0x0F; /* 0x0F is the mask to extract chip version */
+
+            if ((PHDNLDNFC_HWVER_MRA2_1 == bHwVer) || (PHDNLDNFC_HWVER_MRA2_2 == bHwVer) ||
+                    (PHDNLDNFC_HWVER_PN548AD_MRA1_0 == bHwVer))
+            {
+                bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN_MRA2_1;
+                (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
+            }
+            else if ((bHwVer >= PHDNLDNFC_HWVER_MRA1_0) && (bHwVer
+                        <= PHDNLDNFC_HWVER_MRA2_0))
+            {
+                bExpectedLen = PHLIBNFC_IOCTL_DNLD_GETVERLEN;
+                (gphNxpNciHal_fw_IoctlCtx.bChipVer) = bHwVer;
+            }
+            else
+            {
+                wStatus = NFCSTATUS_FAILED;
+                NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Invalid ChipVersion!!");
+            }
+        }
+        else
+        {
+            wStatus = NFCSTATUS_FAILED;
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff Invalid...\n");
+        }
+
+        if ((NFCSTATUS_SUCCESS == wStatus) && (bExpectedLen == pRespBuff->wLen)
+                && (NULL != pRespBuff->pBuff))
+        {
+            NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_version_cb - Valid Version Resp Buff!!...\n");
+
+            /* Validate version details to confirm if continue with the next sequence of Operations. */
+            memcpy(bCurrVer, &(pRespBuff->pBuff[bExpectedLen - 2]),
+                    sizeof(bCurrVer));
+            wFwVern = wFwVer;
+            wMwVern = wMwVer;
+
+            memcpy(bNewVer,&wFwVern,sizeof(bNewVer));
+
+            /* check if the ROM code version and FW Major version is valid for the chip*/
+            /* ES2.2 Rom Version - 0x7 and Valid FW Major Version - 0x1 */
+            if ((pRespBuff->pBuff[1] == 0x07) &&(bNewVer[1] !=0x01))
+            {
+                NXPLOG_FWDNLD_E("C1 FW on C2 chip is not allowed - FW Major Version!= 1 on ES2.2");
+                wStatus = NFCSTATUS_NOT_ALLOWED;
+            }
+            /* Major Version number check */
+            else if((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && (bNewVer[1] < bCurrVer[1]))
+            {
+                NXPLOG_FWDNLD_E("Version Check Failed - MajorVerNum Mismatch\n");
+                wStatus = NFCSTATUS_NOT_ALLOWED;
+            }
+            /* Minor Version number check - before download.*/
+            else if((FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && ((bNewVer[0] == bCurrVer[0]) &&
+                        (bNewVer[1] == bCurrVer[1])))
+            {
+                wStatus = NFCSTATUS_SUCCESS;
+#if (PH_LIBNFC_ENABLE_FORCE_DOWNLOAD == 0)
+                NXPLOG_FWDNLD_D("Version Already UpToDate!!\n");
+                (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE;
+#else
+                (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = TRUE;
+#endif
+
+            }
+            /* Minor Version number check - after download
+             * after download, we should get the same version information.*/
+            else if ((TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)) && ((bNewVer[0] != bCurrVer[0]) ||
+                        (bNewVer[1] != bCurrVer[1])))
+            {
+                NXPLOG_FWDNLD_E("Version Not Updated After Download!!\n");
+                wStatus = NFCSTATUS_FAILED;
+            }
+            else
+            {
+                NXPLOG_FWDNLD_D("Version Check Successful\n");
+                /* Store the Mw & Fw Version for updating in EEPROM Log Area after successful download */
+                if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+                {
+                    NXPLOG_FWDNLD_W("Updating Fw & Mw Versions..");
+                    (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrMwVer) = wMwVern;
+                    (gphNxpNciHal_fw_IoctlCtx.tLogParams.wCurrFwVer) = wFwVern;
+                }
+
+            }
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Version Resp Buff Invalid...\n");
+        }
+    }
+    else
+    {
+        wStatus = NFCSTATUS_FAILED;
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version_cb - Request Failed!!");
+    }
+
+    p_cb_data->status = wStatus;
+    SEM_POST(p_cb_data);
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_get_version
+**
+** Description      Download Get version
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_get_version(void* pContext,
+        NFCSTATUS status, void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    static uint8_t bGetVerRes[11];
+    phDnldNfc_Buff_t tDnldBuff;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) ||
+            (TRUE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    tDnldBuff.pBuff = bGetVerRes;
+    tDnldBuff.wLen = sizeof(bGetVerRes);
+
+    wStatus = phDnldNfc_GetVersion(&tDnldBuff,
+            (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_get_version_cb,
+            (void*) &cb_data);
+    if (wStatus != NFCSTATUS_PENDING)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_get_sessn_state_cb
+**
+** Description      Download Get session state callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_get_sessn_state_cb(void* pContext,
+        NFCSTATUS status, void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS wStatus = status;
+    pphDnldNfc_Buff_t pRespBuff;
+    if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo))
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Successful");
+
+        pRespBuff = (pphDnldNfc_Buff_t) pInfo;
+
+        if ((3 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff)))
+        {
+            NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_get_sessn_state_cb - Valid Session State Resp Buff!!...");
+
+            if (phDnldNfc_LCOper == pRespBuff->pBuff[2])
+            {
+                if (PHLIBNFC_FWDNLD_SESSNOPEN == pRespBuff->pBuff[0])
+                {
+                    NXPLOG_FWDNLD_E("Prev Fw Upgrade Session still Open..");
+                    (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = TRUE;
+                    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+                    {
+                        NXPLOG_FWDNLD_D("Session still Open after Prev Fw Upgrade attempt!!");
+
+                        if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS)
+                        {
+                            NXPLOG_FWDNLD_W("Setting Dnld Retry ..");
+                            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+                        }
+                        else
+                        {
+                            NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
+                            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+                        }
+                        wStatus = NFCSTATUS_FAILED;
+                    }
+                }
+                else
+                {
+                    gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen = FALSE;
+                }
+            }
+            else
+            {
+                wStatus = NFCSTATUS_FAILED;
+                NXPLOG_FWDNLD_E("NFCC not in Operational State..Fw Upgrade not allowed!!");
+            }
+        }
+        else
+        {
+            wStatus = NFCSTATUS_FAILED;
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_sessn_state_cb - Session State Resp Buff Invalid...");
+        }
+    }
+    else
+    {
+        wStatus = NFCSTATUS_FAILED;
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_sessn_state_cb - Request Failed!!");
+    }
+
+    p_cb_data->status = wStatus;
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_get_sessn_state
+**
+** Description      Download Get session state
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_get_sessn_state(void* pContext,
+        NFCSTATUS status, void* pInfo)
+{
+    phDnldNfc_Buff_t tDnldBuff;
+    static uint8_t bGSnStateRes[3];
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if (TRUE == gphNxpNciHal_fw_IoctlCtx.bSkipSeq)
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_get_version cb_data creation failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    tDnldBuff.pBuff = bGSnStateRes;
+    tDnldBuff.wLen = sizeof(bGSnStateRes);
+
+    wStatus = phDnldNfc_GetSessionState(&tDnldBuff,
+            &phNxpNciHal_fw_dnld_get_sessn_state_cb, (void *) &cb_data);
+    if (wStatus != NFCSTATUS_PENDING)
+    {
+        NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phDnldNfc_GetSessionState cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_log_read_cb
+**
+** Description      Download Logread callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_log_read_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+    if((NFCSTATUS_SUCCESS == status) && (NULL != pInfo))
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_log_read_cb - Request Successful");
+    }
+    else
+    {
+        status = NFCSTATUS_FAILED;
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read_cb - Request Failed!!");
+    }
+
+    p_cb_data->status = status;
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_log_read
+**
+** Description      Download Log Read
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_log_read(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    phDnldNfc_Buff_t Data;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if((((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) || (TRUE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))) &&
+                (FALSE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) || (((TRUE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen))) &&
+                    (TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld))))
+
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb_data creation failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    (Data.pBuff) = (void *)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
+    (Data.wLen) = sizeof(phLibNfc_EELogParams_t);
+
+    wStatus = phDnldNfc_ReadLog(&Data,
+            (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_log_read_cb,
+            (void *) &cb_data);
+    if (wStatus != NFCSTATUS_PENDING)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_read cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_write_cb
+**
+** Description      Download Write callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_write_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    UNUSED(pInfo);
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Request Successful");
+        (gphNxpNciHal_fw_IoctlCtx.bDnldEepromWrite) = FALSE;
+        if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+        {
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldSuccess) += 1;
+
+            if((gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) > 0)
+            {
+                NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Resetting DnldFailCnt");
+                (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) = 0;
+            }
+
+            if(FALSE == (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig))
+            {
+                NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write_cb - Setting bConfig for use by NCI mode");
+                (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = TRUE;
+            }
+        }
+
+        /* Reset the previously set DnldAttemptFailed flag */
+        if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed))
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = FALSE;
+        }
+    }
+    else
+    {
+        if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+        {
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = FALSE;
+        }
+        if(NFCSTATUS_WRITE_FAILED == status)
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = TRUE;
+            (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE;
+        }
+        //status = NFCSTATUS_FAILED;
+
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write_cb - Request Failed!!");
+    }
+
+    p_cb_data->status = status;
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_write
+**
+** Description      Download Write
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_write(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    UNUSED(pContext);
+    UNUSED(status);
+    UNUSED(pInfo);
+    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld))
+    {
+        (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+    }
+
+    if((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq))
+            && (FALSE == (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb_data creation failed");
+        return NFCSTATUS_FAILED;
+    }
+    if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_write - Incrementing NumDnldTrig..");
+        (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = TRUE;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+        (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldTrig) += 1;
+    }
+    wStatus = phDnldNfc_Write(FALSE, NULL,
+            (pphDnldNfc_RspCb_t) &phNxpNciHal_fw_dnld_write_cb,
+            (void *) &cb_data);
+    if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))
+    {
+        if (wStatus != NFCSTATUS_PENDING)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write failed");
+            wStatus = NFCSTATUS_FAILED;
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.wNumDnldFail) += 1;
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.wDnldFailCnt) += 1;
+            (gphNxpNciHal_fw_IoctlCtx.tLogParams.bConfig) = FALSE;
+            goto clean_and_return;
+        }
+    }
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_write cb failed");
+        wStatus = cb_data.status;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_chk_integrity_cb
+**
+** Description      Download Check Integrity callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_chk_integrity_cb(void* pContext,
+        NFCSTATUS status, void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS wStatus = status;
+    pphDnldNfc_Buff_t pRespBuff;
+    //uint8_t bUserDataCrc[4];
+
+    if ((NFCSTATUS_SUCCESS == wStatus) && (NULL != pInfo))
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Successful");
+        pRespBuff = (pphDnldNfc_Buff_t) pInfo;
+
+        if ((31 == (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff)))
+        {
+            NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_chk_integrity_cb - Valid Resp Buff!!...\n");
+            wStatus = phLibNfc_VerifyCrcStatus(pRespBuff->pBuff[0]);
+            /*
+            memcpy(bUserDataCrc, &(pRespBuff->pBuff[27]),
+                    sizeof(bUserDataCrc));*/
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Resp Buff Invalid...\n");
+        }
+    }
+    else
+    {
+        wStatus = NFCSTATUS_FAILED;
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity_cb - Request Failed!!");
+    }
+
+    p_cb_data->status = wStatus;
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_chk_integrity
+**
+** Description      Download Check Integrity
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_chk_integrity(void* pContext,
+        NFCSTATUS status, void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    phDnldNfc_Buff_t tDnldBuff;
+    static uint8_t bChkIntgRes[31];
+    UNUSED(pInfo);
+    UNUSED(pContext);
+    UNUSED(status);
+    if(TRUE == gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)
+    {
+        NXPLOG_FWDNLD_D("Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
+        return NFCSTATUS_SUCCESS;
+    }
+
+    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+    else if(TRUE == gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen)
+    {
+        NXPLOG_FWDNLD_E("Previous Upload session is open..Cannot issue ChkIntegrity Cmd!!");
+        return NFCSTATUS_SUCCESS;
+    }
+
+    tDnldBuff.pBuff = bChkIntgRes;
+    tDnldBuff.wLen = sizeof(bChkIntgRes);
+
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb_data creation failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    wStatus = phDnldNfc_CheckIntegrity((gphNxpNciHal_fw_IoctlCtx.bChipVer),
+            &tDnldBuff, &phNxpNciHal_fw_dnld_chk_integrity_cb,
+            (void *) &cb_data);
+    if (wStatus != NFCSTATUS_PENDING)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity semaphore error");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_chk_integrity cb failed");
+        wStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_recover
+**
+** Description      Download Recover
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS  phNxpNciHal_fw_dnld_recover(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+
+    UNUSED(pInfo);
+    UNUSED(status);
+    UNUSED(pContext);
+    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+    {
+        if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb_data creation failed");
+            return NFCSTATUS_FAILED;
+        }
+        (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts)++;
+
+        /* resetting this flag to avoid cyclic issuance of recovery sequence in case of failure */
+        (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+
+        wStatus = phDnldNfc_Write(TRUE,NULL,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_recover_cb, (void*) &cb_data);
+
+        if(NFCSTATUS_PENDING != wStatus)
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+            goto clean_and_return;
+        }
+        /* Wait for callback response */
+        if (SEM_WAIT(cb_data))
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover semaphore error");
+            wStatus = NFCSTATUS_FAILED;
+            goto clean_and_return;
+        }
+
+        if (cb_data.status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_recover cb failed");
+            wStatus = NFCSTATUS_FAILED;
+            goto clean_and_return;
+        }
+        wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+        phNxpNciHal_cleanup_cb_data(&cb_data);
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_recover_cb
+**
+** Description      Download Recover callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_recover_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS wStatus = status;
+    UNUSED(pContext);
+    UNUSED(pInfo);
+
+    if(NFCSTATUS_SUCCESS == wStatus)
+    {
+        if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipForce))
+        {
+            NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Successful");
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+        }
+        else
+        {
+            NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Production key update Request Successful");
+            (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = TRUE;
+        }
+    }
+    else
+    {
+        wStatus = NFCSTATUS_FAILED;
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_recoverCb - Request Failed!!");
+    }
+
+    /* resetting this flag to avoid cyclic issuance of recovery sequence in case of failure */
+    (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+
+    /* reset previously set SkipForce */
+    (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+    p_cb_data->status = wStatus;
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_send_ncicmd_cb
+**
+** Description      Download Send NCI Command callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static  void phNxpNciHal_fw_dnld_send_ncicmd_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS wStatus = status;
+    pphDnldNfc_Buff_t pRespBuff;
+    UNUSED(pContext);
+
+    if(NFCSTATUS_SUCCESS == wStatus)
+    {
+        NXPLOG_FWDNLD_D("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Successful");
+        pRespBuff = (pphDnldNfc_Buff_t)pInfo;
+
+        if((0 != (pRespBuff->wLen)) && (NULL != (pRespBuff->pBuff)))
+        {
+            if(0 == (pRespBuff->pBuff[3]))
+            {
+                NXPLOG_FWDNLD_D("Successful Response received for Nci Reset Cmd");
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E("Nci Reset Request Failed!!");
+            }
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Invalid Response received for Nci Reset Request!!");
+        }
+        /* Call Tml Ioctl to enable download mode */
+        wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+
+        if(NFCSTATUS_SUCCESS == wStatus)
+        {
+            NXPLOG_FWDNLD_D("Switched Successfully to dnld mode..");
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = TRUE;
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Switching back to dnld mode Failed!!");
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+            wStatus = NFCSTATUS_FAILED;
+        }
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmdCb - Request Failed!!");
+    }
+
+    (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+    p_cb_data->status = wStatus;
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_send_ncicmd
+**
+** Description      Download Send NCI Command
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_send_ncicmd(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    static uint8_t bNciCmd[4] = {0x20,0x00,0x01,0x00};  /* Nci Reset Cmd with KeepConfig option */
+    static uint8_t bNciResp[6];
+    phDnldNfc_Buff_t tsData;
+    phDnldNfc_Buff_t trData;
+    phNxpNciHal_Sem_t cb_data;
+
+    UNUSED(pInfo);
+    UNUSED(status);
+    UNUSED(pContext);
+    if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+    else
+    {
+        /* Call Tml Ioctl to enable/restore normal mode */
+        wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
+
+        if(NFCSTATUS_SUCCESS != wStatus)
+        {
+            NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+            (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+        }
+        else
+        {
+            if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb_data creation failed");
+                return NFCSTATUS_FAILED;
+            }
+            (tsData.pBuff) = bNciCmd;
+            (tsData.wLen) = sizeof(bNciCmd);
+            (trData.pBuff) = bNciResp;
+            (trData.wLen) = sizeof(bNciResp);
+
+            wStatus = phDnldNfc_RawReq(&tsData,&trData,
+                    (pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_send_ncicmd_cb, (void*) &cb_data);
+            if(NFCSTATUS_PENDING != wStatus)
+            {
+                goto clean_and_return;
+            }
+            /* Wait for callback response */
+            if (SEM_WAIT(cb_data))
+            {
+                NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd semaphore error");
+                wStatus = NFCSTATUS_FAILED;
+                goto clean_and_return;
+            }
+
+            if (cb_data.status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_send_ncicmd cb failed");
+                wStatus = NFCSTATUS_FAILED;
+                goto clean_and_return;
+            }
+            wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+            phNxpNciHal_cleanup_cb_data(&cb_data);
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_log_cb
+**
+** Description      Download Log callback
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_fw_dnld_log_cb(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS wStatus = status;
+    UNUSED(pContext);
+    UNUSED(pInfo);
+
+    if(NFCSTATUS_SUCCESS == wStatus)
+    {
+        NXPLOG_FWDNLD_D("phLibNfc_DnldLogCb - Request Successful");
+        (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+    }
+    else
+    {
+        wStatus = NFCSTATUS_FAILED;
+        NXPLOG_FWDNLD_E("phLibNfc_DnldLogCb - Request Failed!!");
+    }
+    p_cb_data->status = wStatus;
+
+    SEM_POST(p_cb_data);
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_log
+**
+** Description      Download Log
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_dnld_log(void* pContext, NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    phDnldNfc_Buff_t tData;
+
+    UNUSED(pInfo);
+    UNUSED(status);
+    UNUSED(pContext);
+    if(((TRUE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq)) ||
+                (TRUE == (gphNxpNciHal_fw_IoctlCtx.bForceDnld))) &&
+            (FALSE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated)))
+    {
+        return NFCSTATUS_SUCCESS;
+    }
+    else
+    {
+        if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log cb_data creation failed");
+            return NFCSTATUS_FAILED;
+        }
+        (tData.pBuff) = (void *)&(gphNxpNciHal_fw_IoctlCtx.tLogParams);
+        (tData.wLen) = sizeof(gphNxpNciHal_fw_IoctlCtx.tLogParams);
+
+        wStatus = phDnldNfc_Log(&tData,(pphDnldNfc_RspCb_t)&phNxpNciHal_fw_dnld_log_cb, (void*) &cb_data);
+
+        if (wStatus != NFCSTATUS_PENDING)
+        {
+            NXPLOG_FWDNLD_E("phDnldNfc_Log failed");
+            (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+            wStatus = NFCSTATUS_FAILED;
+            goto clean_and_return;
+        }
+        /* Wait for callback response */
+        if (SEM_WAIT(cb_data))
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log semaphore error");
+            wStatus = NFCSTATUS_FAILED;
+            goto clean_and_return;
+        }
+
+        if (cb_data.status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_FWDNLD_E("phNxpNciHal_fw_dnld_log_cb failed");
+            wStatus = NFCSTATUS_FAILED;
+            goto clean_and_return;
+        }
+
+        wStatus = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+        phNxpNciHal_cleanup_cb_data(&cb_data);
+
+        return wStatus;
+    }
+
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_seq_handler
+**
+** Description      Sequence Handler
+**
+** Returns          NFCSTATUS_SUCCESS if sequence completed uninterrupted
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_seq_handler(NFCSTATUS (*seq_handler[])(void* pContext, NFCSTATUS status, void* pInfo))
+{
+    char *pContext = "FW-Download";
+    int16_t seq_counter = 0;
+    phDnldNfc_Buff_t pInfo;
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    status = phTmlNfc_ReadAbort();
+    if(NFCSTATUS_SUCCESS != status)
+    {
+      NXPLOG_FWDNLD_E("Tml Read Abort failed!!");
+      return status;
+    }
+
+    while(seq_handler[seq_counter] != NULL )
+    {
+        status = NFCSTATUS_FAILED;
+        status = (seq_handler[seq_counter])(pContext, status, &pInfo );
+        if(NFCSTATUS_SUCCESS != status)
+        {
+            NXPLOG_FWDNLD_E(" phNxpNciHal_fw_seq_handler : FAILED");
+            break;
+        }
+        seq_counter++;
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_dnld_complete
+**
+** Description      Download Sequence Complete
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+static  NFCSTATUS phNxpNciHal_fw_dnld_complete(void* pContext,NFCSTATUS status,
+        void* pInfo)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    NFCSTATUS fStatus = status;
+    UNUSED(pInfo);
+    UNUSED(pContext);
+
+    if(NFCSTATUS_WRITE_FAILED == status)
+    {
+        if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS)
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE;
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
+            (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+        }
+    }
+    else if(NFCSTATUS_REJECTED == status)
+    {
+        if((gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) < PHLIBNFC_IOCTL_DNLD_MAX_ATTEMPTS)
+        {
+            (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = TRUE;
+
+            /* in case of signature error we need to try recover sequence directly bypassing the force cmd */
+            (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = TRUE;
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Max Dnld Retry Counts Exceeded!!");
+            (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+            (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+        }
+    }
+
+    if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated))
+    {
+        (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = status;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = TRUE;
+
+        NXPLOG_FWDNLD_E("Invoking Pending Download Log Sequence..");
+        (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+        /* Perform the Logging sequence */
+        wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_log_seqhandler);
+        status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
+        if (NFCSTATUS_SUCCESS == status)
+        {
+            NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
+        }
+
+    }
+    else if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery))
+    {
+        NXPLOG_FWDNLD_E("Invoking Download Recovery Sequence..");
+
+        if(NFCSTATUS_SUCCESS == wStatus)
+        {
+            /* Perform the download Recovery sequence */
+            wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_rec_seqhandler);
+
+            status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
+            if (NFCSTATUS_SUCCESS == status)
+            {
+                NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
+            }
+            else
+            {
+                NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
+            }
+        }
+    }
+    else if(TRUE == (gphNxpNciHal_fw_IoctlCtx.bRetryDnld))
+    {
+        (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+
+        /* Perform the download sequence ... after successful recover attempt */
+        wStatus = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
+
+        status = phNxpNciHal_fw_dnld_complete(pContext, wStatus, &pInfo);
+        if (NFCSTATUS_SUCCESS == status)
+        {
+            NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
+        }
+    }
+    else
+    {
+        if(FALSE == (gphNxpNciHal_fw_IoctlCtx.bSkipSeq))
+        {
+            if(NFCSTATUS_SUCCESS == status)
+            {
+                if(NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("Fw Download success.. ");
+                }
+                else if(PHLIBNFC_DNLD_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("Read Request success.. ");
+                }
+                else if(PHLIBNFC_DNLD_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("Write Request success.. ");
+                }
+                else if(PHLIBNFC_DNLD_READ_LOG == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("ReadLog Request success.. ");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Invalid Request!!");
+                }
+            }
+            else
+            {
+                if(NFC_FW_DOWNLOAD == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("Fw Download Failed!!");
+                }
+                else if(NFC_MEM_READ == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("Read Request Failed!!");
+                }
+                else if(NFC_MEM_WRITE == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("Write Request Failed!!");
+                }
+                else if(PHLIBNFC_DNLD_READ_LOG == gphNxpNciHal_fw_IoctlCtx.IoctlCode)
+                {
+                    NXPLOG_FWDNLD_E("ReadLog Request Failed!!");
+                }
+                else
+                {
+                    NXPLOG_FWDNLD_E("Invalid Request!!");
+                }
+            }
+        }
+
+        if(FALSE == gphNxpNciHal_fw_IoctlCtx.bSendNciCmd)
+        {
+            /* Call Tml Ioctl to enable/restore normal mode */
+            wStatus = phTmlNfc_IoCtl(phTmlNfc_e_EnableNormalMode);
+
+            if(NFCSTATUS_SUCCESS != wStatus)
+            {
+                NXPLOG_FWDNLD_E("Switching to NormalMode Failed!!");
+            }
+            else
+            {
+                wStatus = fStatus;
+            }
+        }
+
+        (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
+        (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+        (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
+
+        if(FALSE == gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed)
+        {
+        }
+        else
+        {
+            NXPLOG_FWDNLD_E("Returning Download Failed Status to Caller!!");
+
+            (gphNxpNciHal_fw_IoctlCtx.bLastStatus) = NFCSTATUS_SUCCESS;
+            (gphNxpNciHal_fw_IoctlCtx.bDnldAttemptFailed) = FALSE;
+        }
+        phDnldNfc_CloseFwLibHandle();
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_fw_download_seq
+**
+** Description      Download Sequence
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    phDnldNfc_Buff_t pInfo;
+    char *pContext = "FW-Download";
+
+    /* reset the global flags */
+    gphNxpNciHal_fw_IoctlCtx.IoctlCode = NFC_FW_DOWNLOAD;
+    (gphNxpNciHal_fw_IoctlCtx.bPrevSessnOpen) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bDnldInitiated) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bChipVer) = 0;
+    (gphNxpNciHal_fw_IoctlCtx.bSkipSeq) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bForceDnld) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bDnldRecovery) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bRetryDnld) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bSkipReset) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bSkipForce) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bSendNciCmd) = FALSE;
+    (gphNxpNciHal_fw_IoctlCtx.bDnldAttempts) = 0;
+    (gphNxpNciHal_fw_IoctlCtx.bClkSrcVal) = bClkSrcVal;
+    (gphNxpNciHal_fw_IoctlCtx.bClkFreqVal) = bClkFreqVal;
+    /* Get firmware version */
+    if (NFCSTATUS_SUCCESS == phDnldNfc_InitImgInfo())
+    {
+        NXPLOG_FWDNLD_D("phDnldNfc_InitImgInfo:SUCCESS");
+        status = phNxpNciHal_fw_seq_handler(phNxpNciHal_dwnld_seqhandler);
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E("phDnldNfc_InitImgInfo: FAILED");
+    }
+
+    /* Chage to normal mode */
+    status = phNxpNciHal_fw_dnld_complete(pContext, status, &pInfo);
+    /*if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_FWDNLD_D(" phNxpNciHal_fw_dnld_complete : SUCCESS");
+    }
+    else
+    {
+        NXPLOG_FWDNLD_E(" phNxpNciHal_fw_dnld_complete : FAILED");
+    }*/
+
+    return status;
+}
+
+static
+NFCSTATUS
+phLibNfc_VerifyCrcStatus(uint8_t bCrcStatus)
+{
+    uint8_t bBitPos = 0;
+    uint8_t bShiftVal = 1;
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    while(bBitPos < 7)
+    {
+        if(!(bCrcStatus & bShiftVal))
+        {
+            switch(bBitPos)
+            {
+                case 0:
+                {
+                    NXPLOG_FWDNLD_E("User Data Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                case 1:
+                {
+                    NXPLOG_FWDNLD_E("Trim Data Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                case 2:
+                {
+                    NXPLOG_FWDNLD_E("Protected Data Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                case 3:
+                {
+                    NXPLOG_FWDNLD_E("Patch Code Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                case 4:
+                {
+                    NXPLOG_FWDNLD_E("Function Code Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                case 5:
+                {
+                    NXPLOG_FWDNLD_E("Patch Table Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                case 6:
+                {
+                    NXPLOG_FWDNLD_E("Function Table Crc is NOT OK!!");
+                    wStatus = NFCSTATUS_FAILED;
+                    break;
+                }
+                default:
+                {
+                    break;
+                }
+            }
+        }
+
+        bShiftVal <<= 1;
+        ++bBitPos;
+    }
+
+    return wStatus;
+}
diff --git a/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h
new file mode 100644
index 0000000..fb448ab
--- /dev/null
+++ b/halimpl/pn54x/dnld/phNxpNciHal_Dnld.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_DNLD_H_
+#define _PHNXPNCIHAL_DNLD_H_
+
+#include <phNfcTypes.h>
+#include <phNfcStatus.h>
+
+NFCSTATUS phNxpNciHal_fw_download_seq(uint8_t bClkSrcVal, uint8_t bClkFreqVal);
+
+#endif /* _PHNXPNCIHAL_DNLD_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal.c b/halimpl/pn54x/hal/phNxpNciHal.c
new file mode 100644
index 0000000..aa70d79
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal.c
@@ -0,0 +1,2340 @@
+/*
+ * Copyright (C) 2012-2014 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 <sys/stat.h>
+#include <phNxpNciHal.h>
+#include <phNxpNciHal_ext.h>
+#include <phNxpNciHal_Dnld.h>
+#include <phNxpNciHal_Adaptation.h>
+#include <phTmlNfc.h>
+#include <phDnldNfc.h>
+#include <phDal4Nfc_messageQueueLib.h>
+#include <phNxpLog.h>
+#include <phNxpConfig.h>
+#include <phNxpNciHal_NfcDepSWPrio.h>
+#include <phNxpNciHal_Kovio.h>
+/*********************** Global Variables *************************************/
+#define PN547C2_CLOCK_SETTING
+#undef  PN547C2_FACTORY_RESET_DEBUG
+#define CORE_RES_STATUS_BYTE 3
+/* Processing of ISO 15693 EOF */
+extern uint8_t icode_send_eof;
+static uint8_t cmd_icode_eof[] = { 0x00, 0x00, 0x00 };
+
+/* FW download success flag */
+static uint8_t fw_download_success = 0;
+
+static uint8_t config_access = FALSE;
+/* NCI HAL Control structure */
+phNxpNciHal_Control_t nxpncihal_ctrl;
+
+/* NXP Poll Profile structure */
+phNxpNciProfile_Control_t nxpprofile_ctrl;
+
+/* TML Context */
+extern phTmlNfc_Context_t *gpphTmlNfc_Context;
+extern void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result);
+/* global variable to get FW version from NCI response*/
+uint32_t wFwVerRsp;
+/* External global variable to get FW version */
+extern uint16_t wFwVer;
+extern int send_to_upper_kovio;
+extern int kovio_detected;
+extern int disable_kovio;
+static uint8_t Rx_data[NCI_MAX_DATA_LEN];
+
+uint32_t timeoutTimerId = 0;
+phNxpNciHal_Sem_t config_data;
+
+phNxpNciClock_t phNxpNciClock={0,};
+
+phNxpNciRfSetting_t phNxpNciRfSet={0,};
+
+/**************** local methods used in this file only ************************/
+static NFCSTATUS phNxpNciHal_fw_download(void);
+static void phNxpNciHal_open_complete(NFCSTATUS status);
+static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void phNxpNciHal_close_complete(NFCSTATUS status);
+static void phNxpNciHal_core_initialized_complete(NFCSTATUS status);
+static void phNxpNciHal_pre_discover_complete(NFCSTATUS status);
+static void phNxpNciHal_power_cycle_complete(NFCSTATUS status);
+static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl);
+static void *phNxpNciHal_client_thread(void *arg);
+static void phNxpNciHal_get_clk_freq(void);
+static void phNxpNciHal_set_clock(void);
+static void phNxpNciHal_check_factory_reset(void);
+static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len);
+static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void);
+static void phNxpNciHal_enable_i2c_fragmentation();
+NFCSTATUS phNxpNciHal_check_clock_config(void);
+NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void);
+int  check_config_parameter();
+/******************************************************************************
+ * Function         phNxpNciHal_client_thread
+ *
+ * Description      This function is a thread handler which handles all TML and
+ *                  NCI messages.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+static void *phNxpNciHal_client_thread(void *arg)
+{
+    phNxpNciHal_Control_t *p_nxpncihal_ctrl = (phNxpNciHal_Control_t *) arg;
+    phLibNfc_Message_t msg;
+
+    NXPLOG_NCIHAL_D("thread started");
+
+    p_nxpncihal_ctrl->thread_running = 1;
+
+    while (p_nxpncihal_ctrl->thread_running == 1)
+    {
+        /* Fetch next message from the NFC stack message queue */
+        if (phDal4Nfc_msgrcv(p_nxpncihal_ctrl->gDrvCfg.nClientId,
+                &msg, 0, 0) == -1)
+        {
+            NXPLOG_NCIHAL_E("NFC client received bad message");
+            continue;
+        }
+
+        if(p_nxpncihal_ctrl->thread_running == 0){
+            break;
+        }
+
+        switch (msg.eMsgType)
+        {
+            case PH_LIBNFC_DEFERREDCALL_MSG:
+            {
+                phLibNfc_DeferredCall_t *deferCall =
+                        (phLibNfc_DeferredCall_t *) (msg.pMsgData);
+
+                REENTRANCE_LOCK();
+                deferCall->pCallback(deferCall->pParameter);
+                REENTRANCE_UNLOCK();
+
+            break;
+        }
+
+        case NCI_HAL_OPEN_CPLT_MSG:
+        {
+            REENTRANCE_LOCK();
+            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+            {
+                /* Send the event */
+                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
+                        HAL_NFC_STATUS_OK);
+            }
+            REENTRANCE_UNLOCK();
+            break;
+        }
+
+        case NCI_HAL_CLOSE_CPLT_MSG:
+        {
+            REENTRANCE_LOCK();
+            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+            {
+                /* Send the event */
+                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_CLOSE_CPLT_EVT,
+                        HAL_NFC_STATUS_OK);
+                phNxpNciHal_kill_client_thread(&nxpncihal_ctrl);
+            }
+            REENTRANCE_UNLOCK();
+            break;
+        }
+
+        case NCI_HAL_POST_INIT_CPLT_MSG:
+        {
+            REENTRANCE_LOCK();
+            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+            {
+                /* Send the event */
+                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_POST_INIT_CPLT_EVT,
+                        HAL_NFC_STATUS_OK);
+            }
+            REENTRANCE_UNLOCK();
+            break;
+        }
+
+        case NCI_HAL_PRE_DISCOVER_CPLT_MSG:
+        {
+            REENTRANCE_LOCK();
+            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+            {
+                /* Send the event */
+                (*nxpncihal_ctrl.p_nfc_stack_cback)(
+                        HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
+            }
+            REENTRANCE_UNLOCK();
+            break;
+        }
+
+        case NCI_HAL_ERROR_MSG:
+        {
+            REENTRANCE_LOCK();
+            if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+            {
+                /* Send the event */
+                (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ERROR_EVT,
+                        HAL_NFC_STATUS_FAILED);
+            }
+            REENTRANCE_UNLOCK();
+            break;
+        }
+
+        case NCI_HAL_RX_MSG:
+        {
+            REENTRANCE_LOCK();
+            if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
+            {
+                (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+                        nxpncihal_ctrl.rsp_len, nxpncihal_ctrl.p_rsp_data);
+            }
+            REENTRANCE_UNLOCK();
+            break;
+        }
+        }
+    }
+
+    NXPLOG_NCIHAL_D("NxpNciHal thread stopped");
+
+    return NULL;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_kill_client_thread
+ *
+ * Description      This function safely kill the client thread and clean all
+ *                  resources.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_kill_client_thread(phNxpNciHal_Control_t *p_nxpncihal_ctrl)
+{
+    NXPLOG_NCIHAL_D("Terminating phNxpNciHal client thread...");
+
+    p_nxpncihal_ctrl->p_nfc_stack_cback = NULL;
+    p_nxpncihal_ctrl->p_nfc_stack_data_cback = NULL;
+    p_nxpncihal_ctrl->thread_running = 0;
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_fw_download
+ *
+ * Description      This function download the PN54X secure firmware to IC. If
+ *                  firmware version in Android filesystem and firmware in the
+ *                  IC is same then firmware download will return with success
+ *                  without downloading the firmware.
+ *
+ * Returns          NFCSTATUS_SUCCESS if firmware download successful
+ *                  NFCSTATUS_FAILED in case of failure
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_fw_download(void)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    phNxpNciHal_get_clk_freq();
+    status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        /* Set the obtained device handle to download module */
+        phDnldNfc_SetHwDevHandle();
+        NXPLOG_NCIHAL_D("Calling Seq handler for FW Download \n");
+        status = phNxpNciHal_fw_download_seq(nxpprofile_ctrl.bClkSrcVal, nxpprofile_ctrl.bClkFreqVal);
+        phDnldNfc_ReSetHwDevHandle();
+    }
+    else
+    {
+        status = NFCSTATUS_FAILED;
+    }
+
+    return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_CheckValidFwVersion
+ *
+ * Description      This function checks the valid FW for Mobile device.
+ *                  If the FW doesn't belong the Mobile device it further
+ *                  checks nxp config file to override.
+ *
+ * Returns          NFCSTATUS_SUCCESS if valid fw version found
+ *                  NFCSTATUS_NOT_ALLOWED in case of FW not valid for mobile
+ *                  device
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_CheckValidFwVersion(void)
+{
+    NFCSTATUS status = NFCSTATUS_NOT_ALLOWED;
+    const unsigned char sfw_mobile_major_no = 0x01;
+    const unsigned char sfw_infra_major_no = 0x02;
+    unsigned char ufw_current_major_no = 0x00;
+    unsigned long num = 0;
+    int isfound = 0;
+
+    /* extract the firmware's major no */
+    ufw_current_major_no = ((0x00FF) & (wFwVer >> 8U));
+
+    NXPLOG_NCIHAL_D("%s current_major_no = 0x%x", __FUNCTION__,ufw_current_major_no );
+    if ( ufw_current_major_no == sfw_mobile_major_no)
+    {
+        status = NFCSTATUS_SUCCESS;
+    }
+    else if (ufw_current_major_no == sfw_infra_major_no)
+    {
+        /* Check the nxp config file if still want to go for download */
+        /* By default NAME_NXP_FW_PROTECION_OVERRIDE will not be defined in config file.
+           If user really want to override the Infra firmware over mobile firmware, please
+           put "NXP_FW_PROTECION_OVERRIDE=0x01" in libnfc-nxp.conf file.
+           Please note once Infra firmware downloaded to Mobile device, The device
+           can never be updated to Mobile firmware*/
+        isfound = GetNxpNumValue(NAME_NXP_FW_PROTECION_OVERRIDE, &num, sizeof(num));
+        if (isfound > 0)
+        {
+            if (num == 0x01)
+            {
+                NXPLOG_NCIHAL_D("Override Infra FW over Mobile");
+                status = NFCSTATUS_SUCCESS;
+            }
+            else
+            {
+                NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE invalid value)");
+            }
+        }
+        else
+        {
+            NXPLOG_NCIHAL_D("Firmware download not allowed (NXP_FW_PROTECION_OVERRIDE not defiend)");
+        }
+    }
+    else if (wFwVerRsp == 0)
+    {
+        NXPLOG_NCIHAL_E("FW Version not received by NCI command >>> Force Firmware download");
+        status = NFCSTATUS_SUCCESS;
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Wrong FW Version >>> Firmware download not allowed");
+    }
+
+    return status;
+}
+
+static void phNxpNciHal_get_clk_freq(void)
+{
+    unsigned long num = 0;
+    int isfound = 0;
+
+    nxpprofile_ctrl.bClkSrcVal = 0;
+    nxpprofile_ctrl.bClkFreqVal = 0;
+    nxpprofile_ctrl.bTimeout = 0;
+
+    isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_SRC_SEL, &num, sizeof(num));
+    if (isfound > 0)
+    {
+        nxpprofile_ctrl.bClkSrcVal = num;
+    }
+
+    num = 0;
+    isfound = 0;
+    isfound = GetNxpNumValue(NAME_NXP_SYS_CLK_FREQ_SEL, &num, sizeof(num));
+    if (isfound > 0)
+    {
+        nxpprofile_ctrl.bClkFreqVal = num;
+    }
+
+    num = 0;
+    isfound = 0;
+    isfound = GetNxpNumValue(NAME_NXP_SYS_CLOCK_TO_CFG, &num, sizeof(num));
+    if (isfound > 0)
+    {
+        nxpprofile_ctrl.bTimeout = num;
+    }
+
+    NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkSrcVal = 0x%x", nxpprofile_ctrl.bClkSrcVal);
+    NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bClkFreqVal);
+    NXPLOG_FWDNLD_D("gphNxpNciHal_fw_IoctlCtx.bClkFreqVal = 0x%x", nxpprofile_ctrl.bTimeout);
+
+    if ((nxpprofile_ctrl.bClkSrcVal < CLK_SRC_XTAL) ||
+            (nxpprofile_ctrl.bClkSrcVal > CLK_SRC_PLL))
+    {
+        NXPLOG_FWDNLD_E("Clock source value is wrong in config file, setting it as default");
+        nxpprofile_ctrl.bClkSrcVal = NXP_SYS_CLK_SRC_SEL;
+    }
+    if ((nxpprofile_ctrl.bClkFreqVal < CLK_FREQ_13MHZ) ||
+            (nxpprofile_ctrl.bClkFreqVal > CLK_FREQ_52MHZ))
+    {
+        NXPLOG_FWDNLD_E("Clock frequency value is wrong in config file, setting it as default");
+        nxpprofile_ctrl.bClkFreqVal = NXP_SYS_CLK_FREQ_SEL;
+    }
+    if ((nxpprofile_ctrl.bTimeout < CLK_TO_CFG_DEF) || (nxpprofile_ctrl.bTimeout > CLK_TO_CFG_MAX))
+    {
+        NXPLOG_FWDNLD_E("Clock timeout value is wrong in config file, setting it as default");
+        nxpprofile_ctrl.bTimeout = CLK_TO_CFG_DEF;
+    }
+
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_open
+ *
+ * Description      This function is called by libnfc-nci during the
+ *                  initialization of the NFCC. It opens the physical connection
+ *                  with NFCC (PN54X) and creates required client thread for
+ *                  operation.
+ *                  After open is complete, status is informed to libnfc-nci
+ *                  through callback function.
+ *
+ * Returns          This function return NFCSTATUS_SUCCES (0) in case of success
+ *                  In case of failure returns other failure value.
+ *
+ ******************************************************************************/
+int phNxpNciHal_open(nfc_stack_callback_t *p_cback, nfc_stack_data_callback_t *p_data_cback)
+{
+    phOsalNfc_Config_t tOsalConfig;
+    phTmlNfc_Config_t tTmlConfig;
+    NFCSTATUS wConfigStatus = NFCSTATUS_SUCCESS;
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    /*NCI_INIT_CMD*/
+    static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
+    /*NCI_RESET_CMD*/
+    static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
+    /* reset config cache */
+    resetNxpConfig();
+
+    int init_retry_cnt=0;
+
+    /* initialize trace level */
+    phNxpLog_InitializeLogLevel();
+
+    /*Create the timer for extns write response*/
+    timeoutTimerId = phOsalNfc_Timer_Create();
+
+    if (phNxpNciHal_init_monitor() == NULL)
+    {
+        NXPLOG_NCIHAL_E("Init monitor failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    CONCURRENCY_LOCK();
+
+    memset(&nxpncihal_ctrl, 0x00, sizeof(nxpncihal_ctrl));
+    memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
+    memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
+    memset (&nxpprofile_ctrl, 0, sizeof(phNxpNciProfile_Control_t));
+
+    /* By default HAL status is HAL_STATUS_OPEN */
+    nxpncihal_ctrl.halStatus = HAL_STATUS_OPEN;
+
+    nxpncihal_ctrl.p_nfc_stack_cback = p_cback;
+    nxpncihal_ctrl.p_nfc_stack_data_cback = p_data_cback;
+
+    /* Configure hardware link */
+    nxpncihal_ctrl.gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+    nxpncihal_ctrl.gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN54X */
+    tTmlConfig.pDevName = (int8_t *) "/dev/pn54x";
+    tOsalConfig.dwCallbackThreadId
+    = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
+    tOsalConfig.pLogFile = NULL;
+    tTmlConfig.dwGetMsgThreadId = (uintptr_t) nxpncihal_ctrl.gDrvCfg.nClientId;
+
+    /* Initialize TML layer */
+    wConfigStatus = phTmlNfc_Init(&tTmlConfig);
+    if (wConfigStatus != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
+        goto clean_and_return;
+    }
+
+    /* Create the client thread */
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    if (pthread_create(&nxpncihal_ctrl.client_thread, &attr,
+            phNxpNciHal_client_thread, &nxpncihal_ctrl) != 0)
+    {
+        NXPLOG_NCIHAL_E("pthread_create failed");
+        wConfigStatus = phTmlNfc_Shutdown();
+        goto clean_and_return;
+    }
+
+    CONCURRENCY_UNLOCK();
+
+    /* call read pending */
+    status = phTmlNfc_Read(
+            nxpncihal_ctrl.p_cmd_data,
+            NCI_MAX_DATA_LEN,
+            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+            NULL);
+    if (status != NFCSTATUS_PENDING)
+    {
+        NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
+        wConfigStatus = phTmlNfc_Shutdown();
+        wConfigStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+init_retry:
+
+    phNxpNciHal_ext_init();
+
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+    if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
+    {
+        NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
+        wConfigStatus = NFCSTATUS_FAILED;
+        goto force_download;
+    }
+    else if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+        if(init_retry_cnt < 3) {
+            init_retry_cnt++;
+            (void)phNxpNciHal_power_cycle();
+            goto init_retry;
+        } else
+            init_retry_cnt = 0;
+        wConfigStatus = phTmlNfc_Shutdown();
+        wConfigStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
+        if(init_retry_cnt < 3) {
+            init_retry_cnt++;
+            (void)phNxpNciHal_power_cycle();
+            goto init_retry;
+        } else
+            init_retry_cnt = 0;
+        wConfigStatus = phTmlNfc_Shutdown();
+        wConfigStatus = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+    phNxpNciHal_enable_i2c_fragmentation();
+    /*Get FW version from device*/
+    status = phDnldNfc_InitImgInfo();
+    NXPLOG_NCIHAL_D ("FW version for FW file = 0x%x", wFwVer);
+    NXPLOG_NCIHAL_D ("FW version from device = 0x%x", wFwVerRsp);
+    if ((wFwVerRsp & 0x0000FFFF) == wFwVer)
+    {
+        NXPLOG_NCIHAL_D ("FW uptodate not required");
+        phDnldNfc_ReSetHwDevHandle();
+    }
+    else
+    {
+force_download:
+        if (wFwVerRsp == 0)
+        {
+            phDnldNfc_InitImgInfo();
+        }
+        if (NFCSTATUS_SUCCESS == phNxpNciHal_CheckValidFwVersion())
+        {
+            NXPLOG_NCIHAL_D ("FW update required");
+            fw_download_success = 0;
+            status = phNxpNciHal_fw_download();
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E ("FW Download failed - NFCC init will continue");
+            }
+            else
+            {
+                wConfigStatus = NFCSTATUS_SUCCESS;
+                fw_download_success = 1;
+                /* call read pending */
+                status = phTmlNfc_Read(
+                nxpncihal_ctrl.p_cmd_data,
+                NCI_MAX_DATA_LEN,
+                   (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+                        NULL);
+                if (status != NFCSTATUS_PENDING)
+                {
+                    NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
+                    wConfigStatus = phTmlNfc_Shutdown();
+                    wConfigStatus = NFCSTATUS_FAILED;
+                    goto clean_and_return;
+                }
+            }
+        }
+        else
+        {
+            if (wFwVerRsp == 0)
+               phDnldNfc_ReSetHwDevHandle();
+        }
+    }
+    /* Call open complete */
+    phNxpNciHal_open_complete(wConfigStatus);
+
+    return wConfigStatus;
+
+    clean_and_return:
+    CONCURRENCY_UNLOCK();
+    /* Report error status */
+    (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_OPEN_CPLT_EVT,
+            HAL_NFC_STATUS_FAILED);
+
+    nxpncihal_ctrl.p_nfc_stack_cback = NULL;
+    nxpncihal_ctrl.p_nfc_stack_data_cback = NULL;
+    phNxpNciHal_cleanup_monitor();
+    nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
+    return NFCSTATUS_FAILED;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_open_complete
+ *
+ * Description      This function inform the status of phNxpNciHal_open
+ *                  function to libnfc-nci.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_open_complete(NFCSTATUS status)
+{
+    static phLibNfc_Message_t msg;
+
+    if (status == NFCSTATUS_SUCCESS)
+    {
+        msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
+        nxpncihal_ctrl.hal_open_status = TRUE;
+    }
+    else
+    {
+        msg.eMsgType = NCI_HAL_ERROR_MSG;
+    }
+
+    msg.pMsgData = NULL;
+    msg.Size = 0;
+
+    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+            (phLibNfc_Message_t *) &msg);
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_write
+ *
+ * Description      This function write the data to NFCC through physical
+ *                  interface (e.g. I2C) using the PN54X driver interface.
+ *                  Before sending the data to NFCC, phNxpNciHal_write_ext
+ *                  is called to check if there is any extension processing
+ *                  is required for the NCI packet being sent out.
+ *
+ * Returns          It returns number of bytes successfully written to NFCC.
+ *
+ ******************************************************************************/
+int phNxpNciHal_write(uint16_t data_len, const uint8_t *p_data)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    static phLibNfc_Message_t msg;
+
+    /* Create local copy of cmd_data */
+    memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
+    nxpncihal_ctrl.cmd_len = data_len;
+
+#ifdef P2P_PRIO_LOGIC_HAL_IMP
+    /* Specific logic to block RF disable when P2P priority logic is busy */
+    if (p_data[0] == 0x21&&
+        p_data[1] == 0x06 &&
+        p_data[2] == 0x01 &&
+        EnableP2P_PrioLogic == TRUE)
+    {
+        NXPLOG_NCIHAL_D ("P2P priority logic busy: Disable it.");
+        phNxpNciHal_clean_P2P_Prio();
+    }
+#endif
+    /* Specific logic to block RF disable when Kovio detection logic is active */
+    if (p_data[0] == 0x21&&
+        p_data[1] == 0x06 &&
+        p_data[2] == 0x01 &&
+        kovio_detected == TRUE)
+    {
+        NXPLOG_NCIHAL_D ("Kovio detection logic is active: Set Flag to disable it.");
+        disable_kovio=0x01;
+    }
+
+    /* Check for NXP ext before sending write */
+    status = phNxpNciHal_write_ext(&nxpncihal_ctrl.cmd_len,
+            nxpncihal_ctrl.p_cmd_data, &nxpncihal_ctrl.rsp_len,
+            nxpncihal_ctrl.p_rsp_data);
+    if (status != NFCSTATUS_SUCCESS)
+    {
+        /* Do not send packet to PN54X, send response directly */
+        msg.eMsgType = NCI_HAL_RX_MSG;
+        msg.pMsgData = NULL;
+        msg.Size = 0;
+
+        phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+                (phLibNfc_Message_t *) &msg);
+        goto clean_and_return;
+    }
+
+    CONCURRENCY_LOCK();
+    data_len = phNxpNciHal_write_unlocked(nxpncihal_ctrl.cmd_len,
+            nxpncihal_ctrl.p_cmd_data);
+    CONCURRENCY_UNLOCK();
+
+    if (icode_send_eof == 1)
+    {
+        usleep (10000);
+        icode_send_eof = 2;
+        phNxpNciHal_send_ext_cmd (3, cmd_icode_eof);
+    }
+
+    clean_and_return:
+    /* No data written */
+    return data_len;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_write_unlocked
+ *
+ * Description      This is the actual function which is being called by
+ *                  phNxpNciHal_write. This function writes the data to NFCC.
+ *                  It waits till write callback provide the result of write
+ *                  process.
+ *
+ * Returns          It returns number of bytes successfully written to NFCC.
+ *
+ ******************************************************************************/
+int phNxpNciHal_write_unlocked(uint16_t data_len, const uint8_t *p_data)
+{
+    NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
+    phNxpNciHal_Sem_t cb_data;
+    nxpncihal_ctrl.retry_cnt = 0;
+    static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};
+
+    /* Create the local semaphore */
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_write_unlocked Create cb data failed");
+        data_len = 0;
+        goto clean_and_return;
+    }
+
+    /* Create local copy of cmd_data */
+    memcpy(nxpncihal_ctrl.p_cmd_data, p_data, data_len);
+    nxpncihal_ctrl.cmd_len = data_len;
+
+    retry:
+
+    data_len = nxpncihal_ctrl.cmd_len;
+
+    status = phTmlNfc_Write( (uint8_t *) nxpncihal_ctrl.p_cmd_data,
+            (uint16_t) nxpncihal_ctrl.cmd_len,
+            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_write_complete,
+            (void *) &cb_data);
+    if (status != NFCSTATUS_PENDING)
+    {
+        NXPLOG_NCIHAL_E("write_unlocked status error");
+        data_len = 0;
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_NCIHAL_E("write_unlocked semaphore error");
+        data_len = 0;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        data_len = 0;
+        if(nxpncihal_ctrl.retry_cnt++ < MAX_RETRY_COUNT)
+        {
+            NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode - Retry");
+            /* 1ms delay to give NFCC wake up delay */
+            usleep(1000);
+            goto retry;
+        }
+        else
+        {
+
+            NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode (max count = 0x%x)", nxpncihal_ctrl.retry_cnt);
+
+            status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+
+            if(NFCSTATUS_SUCCESS == status)
+            {
+                NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
+            }
+            else
+            {
+                NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
+            }
+            if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
+                nxpncihal_ctrl.p_rx_data!= NULL &&
+                nxpncihal_ctrl.hal_open_status == TRUE)
+            {
+                NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
+                //Send the Core Reset NTF to upper layer, which will trigger the recovery.
+                nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
+                memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
+                (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+            }
+        }
+    }
+
+    clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+    return data_len;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_write_complete
+ *
+ * Description      This function handles write callback.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_write_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+    if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
+    }
+
+    p_cb_data->status = pInfo->wStatus;
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_read_complete
+ *
+ * Description      This function is called whenever there is an NCI packet
+ *                  received from NFCC. It could be RSP or NTF packet. This
+ *                  function provide the received NCI packet to libnfc-nci
+ *                  using data callback of libnfc-nci.
+ *                  There is a pending read called from each
+ *                  phNxpNciHal_read_complete so each a packet received from
+ *                  NFCC can be provide to libnfc-nci.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_read_complete(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    UNUSED(pContext);
+    if(nxpncihal_ctrl.read_retry_cnt == 1)
+    {
+        nxpncihal_ctrl.read_retry_cnt = 0;
+    }
+
+    if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("read successful status = 0x%x", pInfo->wStatus);
+
+        nxpncihal_ctrl.p_rx_data = pInfo->pBuff;
+        nxpncihal_ctrl.rx_data_len = pInfo->wLength;
+
+        status = phNxpNciHal_process_ext_rsp (nxpncihal_ctrl.p_rx_data, &nxpncihal_ctrl.rx_data_len);
+
+        phNxpNciHal_print_res_status(nxpncihal_ctrl.p_rx_data,  &nxpncihal_ctrl.rx_data_len);
+        /* Check if response should go to hal module only */
+        if (nxpncihal_ctrl.hal_ext_enabled == 1
+                && (nxpncihal_ctrl.p_rx_data[0x00] & 0x40) == 0x40)
+        {
+            if(status == NFCSTATUS_FAILED)
+            {
+                NXPLOG_NCIHAL_D("enter into NFCC init recovery");
+                nxpncihal_ctrl.ext_cb_data.status = status;
+            }
+            /* Unlock semaphore */
+            SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
+        }
+        /* Read successful send the event to higher layer */
+        else if ((nxpncihal_ctrl.p_nfc_stack_data_cback != NULL) &&
+                (status == NFCSTATUS_SUCCESS)&&(send_to_upper_kovio==1))
+        {
+            (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+                    nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+        }
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("read error status = 0x%x", pInfo->wStatus);
+    }
+
+    if(nxpncihal_ctrl.halStatus == HAL_STATUS_CLOSE)
+    {
+        return;
+    }
+    /* Read again because read must be pending always.*/
+    status = phTmlNfc_Read(
+            Rx_data,
+            NCI_MAX_DATA_LEN,
+            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+            NULL);
+    if (status != NFCSTATUS_PENDING)
+    {
+        NXPLOG_NCIHAL_E("read status error status = %x", status);
+        /* TODO: Not sure how to handle this ? */
+    }
+
+    return;
+}
+
+void read_retry()
+{
+    /* Read again because read must be pending always.*/
+    NFCSTATUS status = phTmlNfc_Read(
+            Rx_data,
+            NCI_MAX_DATA_LEN,
+            (pphTmlNfc_TransactCompletionCb_t) &phNxpNciHal_read_complete,
+            NULL);
+    if (status != NFCSTATUS_PENDING)
+    {
+        NXPLOG_NCIHAL_E("read status error status = %x", status);
+        /* TODO: Not sure how to handle this ? */
+    }
+}
+/******************************************************************************
+ * Function         phNxpNciHal_core_initialized
+ *
+ * Description      This function is called by libnfc-nci after successful open
+ *                  of NFCC. All proprietary setting for PN54X are done here.
+ *                  After completion of proprietary settings notification is
+ *                  provided to libnfc-nci through callback function.
+ *
+ * Returns          Always returns NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    static uint8_t p2p_listen_mode_routing_cmd[] = { 0x21, 0x01, 0x07, 0x00, 0x01,
+                                                0x01, 0x03, 0x00, 0x01, 0x05 };
+
+    uint8_t swp_full_pwr_mode_on_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0,
+                                           0xF1,0x01,0x01 };
+
+    static uint8_t android_l_aid_matching_mode_on_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x91, 0x01, 0x01};
+    static uint8_t swp_switch_timeout_cmd[] = {0x20, 0x02, 0x06, 0x01, 0xA0, 0xF3, 0x02, 0x00, 0x00};
+
+    uint8_t *buffer = NULL;
+    long bufflen = 260;
+    long retlen = 0;
+    int isfound;
+    /* Temp fix to re-apply the proper clock setting */
+     int temp_fix = 1;
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+    unsigned long num = 0;
+#endif
+    // recovery --start
+    /*NCI_INIT_CMD*/
+    static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
+    /*NCI_RESET_CMD*/
+    static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00}; //keep configuration
+    /* reset config cache */
+    static uint8_t retry_core_init_cnt;
+
+    if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)) //initializing for recovery.
+    {
+retry_core_init:
+        config_access = FALSE;
+        if(buffer != NULL)
+            free(buffer);
+        if(retry_core_init_cnt > 3)
+        {
+            return NFCSTATUS_FAILED;
+        }
+
+        status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+        if(NFCSTATUS_SUCCESS == status) { NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n"); }
+        else { NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n"); }
+
+        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+        if((status != NFCSTATUS_SUCCESS) && (nxpncihal_ctrl.retry_cnt >= MAX_RETRY_COUNT))
+        {
+            NXPLOG_NCIHAL_E("Force FW Download, NFCC not coming out from Standby");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+        else if(status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+
+        }
+
+        if(*p_core_init_rsp_params == 2) {
+            NXPLOG_NCIHAL_E(" Last command is CORE_RESET!!");
+            goto invoke_callback;
+        }
+
+        status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
+        if(status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+
+        if(*p_core_init_rsp_params == 3) {
+            NXPLOG_NCIHAL_E(" Last command is CORE_INIT!!");
+            goto invoke_callback;
+        }
+    }
+// recovery --end
+
+
+    buffer = (uint8_t*) malloc(bufflen*sizeof(uint8_t));
+    if(NULL == buffer)
+    {
+        return NFCSTATUS_FAILED;
+    }
+    config_access = TRUE;
+    retlen = 0;
+    isfound = GetNxpByteArrayValue(NAME_NXP_ACT_PROP_EXTN, (char *) buffer,
+            bufflen, &retlen);
+    if (retlen > 0) {
+        /* NXP ACT Proprietary Ext */
+        status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+    }
+
+    //
+    status = phNxpNciHal_check_clock_config();
+    if (status != NFCSTATUS_SUCCESS) {
+        NXPLOG_NCIHAL_E("phNxpNciHal_check_clock_config failed");
+        retry_core_init_cnt++;
+        goto retry_core_init;
+    }
+
+#ifdef PN547C2_CLOCK_SETTING
+    if (isNxpConfigModified() || (fw_download_success == 1) || (phNxpNciClock.issetConfig)
+#if(NFC_NXP_HFO_SETTINGS == TRUE)
+        || temp_fix == 1
+#endif
+        )
+    {
+        //phNxpNciHal_get_clk_freq();
+        phNxpNciHal_set_clock();
+        phNxpNciClock.issetConfig = FALSE;
+#if(NFC_NXP_HFO_SETTINGS == TRUE)
+        if (temp_fix == 1 )
+        {
+            NXPLOG_NCIHAL_D("Applying Default Clock setting and DPLL register at power on");
+            /*
+            # A0, 0D, 06, 06, 83, 55, 2A, 04, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_GEAR_REG
+            # A0, 0D, 06, 06, 82, 33, 14, 17, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_REG
+            # A0, 0D, 06, 06, 84, AA, 85, 00, 80 RF_CLIF_CFG_TARGET CLIF_DPLL_INIT_FREQ_REG
+            # A0, 0D, 06, 06, 81, 63, 00, 00, 00 RF_CLIF_CFG_TARGET CLIF_DPLL_CONTROL_REG
+            */
+            static uint8_t cmd_dpll_set_reg_nci[] = {0x20, 0x02, 0x25, 0x04,
+                                                                            0xA0, 0x0D, 0x06, 0x06, 0x83, 0x55, 0x2A, 0x04, 0x00,
+                                                                            0xA0, 0x0D, 0x06, 0x06, 0x82, 0x33, 0x14, 0x17, 0x00,
+                                                                            0xA0, 0x0D, 0x06, 0x06, 0x84, 0xAA, 0x85, 0x00, 0x80,
+                                                                            0xA0, 0x0D, 0x06, 0x06, 0x81, 0x63, 0x00, 0x00, 0x00};
+
+            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_dpll_set_reg_nci), cmd_dpll_set_reg_nci);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("NXP DPLL REG ACT Proprietary Ext failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+            /* reset the NFCC after applying the clock setting and DPLL setting */
+            //phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+            temp_fix = 0;
+            goto retry_core_init;
+        }
+#endif
+    }
+#endif
+
+    phNxpNciHal_check_factory_reset();
+    retlen = 0;
+    config_access = TRUE;
+    isfound = GetNxpByteArrayValue(NAME_NXP_NFC_PROFILE_EXTN, (char *) buffer,
+            bufflen, &retlen);
+    if (retlen > 0) {
+        /* NXP ACT Proprietary Ext */
+        status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("NXP ACT Proprietary Ext failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+    }
+
+    if(isNxpConfigModified() || (fw_download_success == 1))
+    {
+
+        retlen = 0;
+        fw_download_success = 0;
+
+#if(NFC_NXP_CHIP_TYPE == PN548C2)
+        NXPLOG_NCIHAL_D ("Performing TVDD Settings");
+        isfound = GetNxpNumValue(NAME_NXP_EXT_TVDD_CFG, &num, sizeof(num));
+        if (isfound > 0) {
+            if(num == 1) {
+                isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_1, (char *) buffer,
+                        bufflen, &retlen);
+                if (retlen > 0) {
+                    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+                    if (status != NFCSTATUS_SUCCESS) {
+                        NXPLOG_NCIHAL_E("EXT TVDD CFG 1 Settings failed");
+                        retry_core_init_cnt++;
+                        goto retry_core_init;
+                    }
+                }
+            }
+            else if(num == 2) {
+                isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_2, (char *) buffer,
+                        bufflen, &retlen);
+                    if (retlen > 0) {
+                    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+                    if (status != NFCSTATUS_SUCCESS) {
+                        NXPLOG_NCIHAL_E("EXT TVDD CFG 2 Settings failed");
+                        retry_core_init_cnt++;
+                        goto retry_core_init;
+                    }
+                }
+            }
+            else if(num == 3) {
+                isfound = GetNxpByteArrayValue(NAME_NXP_EXT_TVDD_CFG_3, (char *) buffer,
+                        bufflen, &retlen);
+                    if (retlen > 0) {
+                    status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+                    if (status != NFCSTATUS_SUCCESS) {
+                        NXPLOG_NCIHAL_E("EXT TVDD CFG 3 Settings failed");
+                        retry_core_init_cnt++;
+                        goto retry_core_init;
+                    }
+                }
+            }
+            else {
+                NXPLOG_NCIHAL_E("Wrong Configuration Value %ld", num);
+            }
+
+        }
+#endif
+        retlen = 0;
+        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 1");
+        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_1, (char *) buffer,
+                bufflen, &retlen);
+        if (retlen > 0) {
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("RF Settings BLK 1 failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        retlen = 0;
+
+        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 2");
+        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_2, (char *) buffer,
+                bufflen, &retlen);
+        if (retlen > 0) {
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("RF Settings BLK 2 failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        retlen = 0;
+
+        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 3");
+        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_3, (char *) buffer,
+                bufflen, &retlen);
+        if (retlen > 0) {
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("RF Settings BLK 3 failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        retlen = 0;
+
+        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 4");
+        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_4, (char *) buffer,
+                bufflen, &retlen);
+        if (retlen > 0) {
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("RF Settings BLK 4 failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        retlen = 0;
+
+        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 5");
+        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_5, (char *) buffer,
+                bufflen, &retlen);
+        if (retlen > 0) {
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("RF Settings BLK 5 failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        retlen = 0;
+
+        NXPLOG_NCIHAL_D ("Performing RF Settings BLK 6");
+        isfound = GetNxpByteArrayValue(NAME_NXP_RF_CONF_BLK_6, (char *) buffer,
+                bufflen, &retlen);
+        if (retlen > 0) {
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("RF Settings BLK 6 failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        retlen = 0;
+
+        NXPLOG_NCIHAL_D ("Performing NAME_NXP_CORE_CONF_EXTN Settings");
+        isfound = GetNxpByteArrayValue(NAME_NXP_CORE_CONF_EXTN,
+                (char *) buffer, bufflen, &retlen);
+        if (retlen > 0) {
+            /* NXP ACT Proprietary Ext */
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("NXP Core configuration failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+
+        retlen = 0;
+
+        isfound = GetNxpByteArrayValue(NAME_NXP_CORE_MFCKEY_SETTING,
+                (char *) buffer, bufflen, &retlen);
+        if (retlen > 0) {
+            /* NXP ACT Proprietary Ext */
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("Setting mifare keys failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+
+        retlen = 0;
+
+        isfound = GetNxpByteArrayValue(NAME_NXP_CORE_RF_FIELD,
+                (char *) buffer, bufflen, &retlen);
+        if (retlen > 0) {
+            /* NXP ACT Proprietary Ext */
+            status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+            if (status != NFCSTATUS_SUCCESS) {
+                NXPLOG_NCIHAL_E("Setting NXP_CORE_RF_FIELD status failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+        retlen = 0;
+
+        /* NXP SWP switch timeout Setting*/
+        if(GetNxpNumValue(NAME_NXP_SWP_SWITCH_TIMEOUT, (void *)&retlen, sizeof(retlen)))
+        {
+            //Check the permissible range [0 - 60]
+            if(0 <= retlen && retlen <= 60)
+            {
+                if( 0 < retlen)
+                {
+                    uint16_t timeout = retlen * 1000;
+                    uint16_t timeoutHx = 0x0000;
+
+                    uint8_t buffer[10];
+                    snprintf ( buffer, 10, "%04x", timeout );
+                    sscanf (buffer,"%x",&timeoutHx);
+
+                    swp_switch_timeout_cmd[7]= (timeoutHx & 0xFF);
+                    swp_switch_timeout_cmd[8]=  ((timeoutHx & 0xFF00) >> 8);
+                }
+
+                status = phNxpNciHal_send_ext_cmd (sizeof(swp_switch_timeout_cmd),
+                                                          swp_switch_timeout_cmd);
+                if (status != NFCSTATUS_SUCCESS)
+                {
+                   NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed");
+                   retry_core_init_cnt++;
+                   goto retry_core_init;
+                }
+            }
+            else
+            {
+                NXPLOG_NCIHAL_E("SWP switch timeout Setting Failed - out of range!");
+            }
+
+        }
+
+        status = phNxpNciHal_china_tianjin_rf_setting();
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("phNxpNciHal_china_tianjin_rf_setting failed");
+            return NFCSTATUS_FAILED;
+        }
+#endif
+    }
+
+    retlen = 0;
+
+    isfound = GetNxpByteArrayValue(NAME_NXP_CORE_STANDBY, (char *) buffer,bufflen, &retlen);
+    if (retlen > 0) {
+        /* NXP ACT Proprietary Ext */
+        status = phNxpNciHal_send_ext_cmd(retlen, buffer);
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("Stand by mode enable failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+    }
+    retlen = 0;
+
+    isfound =  GetNxpByteArrayValue(NAME_NXP_CORE_CONF,(char *)buffer,bufflen,&retlen);
+    if(retlen > 0)
+    {
+        /* NXP ACT Proprietary Ext */
+        status = phNxpNciHal_send_ext_cmd(retlen,buffer);
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("Core Set Config failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+    }
+
+    config_access = FALSE;
+    //if length of last command is 0 then only reset the P2P listen mode routing.
+    if(p_core_init_rsp_params[35] == 0)
+    {
+        /* P2P listen mode routing */
+        status = phNxpNciHal_send_ext_cmd (sizeof (p2p_listen_mode_routing_cmd), p2p_listen_mode_routing_cmd);
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("P2P listen mode routing failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+    }
+
+    retlen = 0;
+
+    /* SWP FULL PWR MODE SETTING ON */
+    if(GetNxpNumValue(NAME_NXP_SWP_FULL_PWR_ON, (void *)&retlen, sizeof(retlen)))
+    {
+        if(1 == retlen)
+        {
+            status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
+                                                      swp_full_pwr_mode_on_cmd);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+               NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING ON CMD FAILED");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        else
+        {
+            swp_full_pwr_mode_on_cmd[7]=0x00;
+            status = phNxpNciHal_send_ext_cmd (sizeof(swp_full_pwr_mode_on_cmd),
+                                                      swp_full_pwr_mode_on_cmd);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("SWP FULL PWR MODE SETTING OFF CMD FAILED");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+    }
+
+    /* Android L AID Matching Platform Setting*/
+    if(GetNxpNumValue(NAME_AID_MATCHING_PLATFORM, (void *)&retlen, sizeof(retlen)))
+    {
+        if(1 == retlen)
+        {
+            status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
+                    android_l_aid_matching_mode_on_cmd);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+               NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+        else if (2 == retlen)
+        {
+            android_l_aid_matching_mode_on_cmd[7]=0x00;
+            status = phNxpNciHal_send_ext_cmd (sizeof(android_l_aid_matching_mode_on_cmd),
+                    android_l_aid_matching_mode_on_cmd);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("Android L AID Matching Platform Setting Failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+        }
+    }
+
+    if((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4))
+    {
+        static phLibNfc_Message_t msg;
+        uint16_t tmp_len = 0;
+        uint8_t uicc_set_mode[] = {0x22, 0x01, 0x02, 0x02, 0x01};
+        uint8_t set_screen_state[] = {0x2F, 0x15, 01, 00};      //SCREEN ON
+        uint8_t nfcc_core_conn_create[] = {0x20, 0x04, 0x06, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01};
+        uint8_t nfcc_mode_set_on[] = {0x22, 0x01, 0x02, 0x01, 0x01};
+
+        NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!!");
+        status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_core_conn_create), nfcc_core_conn_create);
+
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("Sending DH and NFCC core connection command as raw packet!! Failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+
+        NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!!");
+        status = phNxpNciHal_send_ext_cmd (sizeof(nfcc_mode_set_on), nfcc_mode_set_on);
+
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("Sending DH and NFCC mode set as raw packet!! Failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+
+        NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!!");
+        status = phNxpNciHal_send_ext_cmd (sizeof(uicc_set_mode),
+                                      uicc_set_mode);
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("Sending UICC Select Command as raw packet!! Failed");
+            retry_core_init_cnt++;
+            goto retry_core_init;
+        }
+
+        if(*(p_core_init_rsp_params + 1) == 1) // RF state is Discovery!!
+        {
+            NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!!");
+            status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
+                                          set_screen_state);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("Sending Set Screen ON State Command as raw packet!! Failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+
+            NXPLOG_NCIHAL_E("Sending discovery as raw packet!!");
+            status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[2],
+                                                      (uint8_t *)&p_core_init_rsp_params[3]);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("Sending discovery as raw packet Failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!!");
+            set_screen_state[3] = 0x01; //Screen OFF
+            status = phNxpNciHal_send_ext_cmd (sizeof(set_screen_state),
+                                          set_screen_state);
+            if (status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("Sending Set Screen OFF State Command as raw packet!! Failed");
+                retry_core_init_cnt++;
+                goto retry_core_init;
+            }
+
+        }
+        NXPLOG_NCIHAL_E("Sending last command for Recovery ");
+
+        if(p_core_init_rsp_params[35] > 0)
+        {  //if length of last command is 0 then it doesn't need to send last command.
+            if( !(((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x03))
+                && (*(p_core_init_rsp_params + 1) == 1))&&
+                    !((p_core_init_rsp_params[36] == 0x21) && (p_core_init_rsp_params[37] == 0x06)))
+                //if last command is discovery and RF staus is also discovery state, then it doesn't need to execute.
+            {
+                tmp_len = p_core_init_rsp_params[35];
+
+                /* Check for NXP ext before sending write */
+                status = phNxpNciHal_write_ext(&tmp_len,
+                        (uint8_t *)&p_core_init_rsp_params[36], &nxpncihal_ctrl.rsp_len,
+                        nxpncihal_ctrl.p_rsp_data);
+                if (status != NFCSTATUS_SUCCESS)
+                {
+                    /* Do not send packet to PN54X, send response directly */
+                    msg.eMsgType = NCI_HAL_RX_MSG;
+                    msg.pMsgData = NULL;
+                    msg.Size = 0;
+
+                    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+                            (phLibNfc_Message_t *) &msg);
+                    return NFCSTATUS_SUCCESS;
+                }
+
+                p_core_init_rsp_params[35] = (uint8_t)tmp_len;
+
+                status = phNxpNciHal_send_ext_cmd (p_core_init_rsp_params[35],
+                                                          (uint8_t *)&p_core_init_rsp_params[36]);
+                if (status != NFCSTATUS_SUCCESS)
+                {
+                    NXPLOG_NCIHAL_E("Sending last command for Recovery Failed");
+                    retry_core_init_cnt++;
+                    goto retry_core_init;
+                }
+            }
+        }
+    }
+
+    retry_core_init_cnt = 0;
+
+    if(buffer)
+    {
+        free(buffer);
+    }
+
+    if(!((*p_core_init_rsp_params > 0) && (*p_core_init_rsp_params < 4)))
+        phNxpNciHal_core_initialized_complete(status);
+    else
+    {
+invoke_callback:
+        config_access = FALSE;
+        if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
+        {
+            *p_core_init_rsp_params = 0;
+            NXPLOG_NCIHAL_E("Invoking data callback!!");
+            (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+                    nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+        }
+    }
+
+#ifdef PN547C2_CLOCK_SETTING
+    if (isNxpConfigModified())
+    {
+        updateNxpConfigTimestamp();
+    }
+#endif
+    return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_core_initialized_complete
+ *
+ * Description      This function is called when phNxpNciHal_core_initialized
+ *                  complete all proprietary command exchanges. This function
+ *                  informs libnfc-nci about completion of core initialize
+ *                  and result of that through callback.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_core_initialized_complete(NFCSTATUS status)
+{
+    static phLibNfc_Message_t msg;
+
+    if (status == NFCSTATUS_SUCCESS)
+    {
+        msg.eMsgType = NCI_HAL_POST_INIT_CPLT_MSG;
+    }
+    else
+    {
+        msg.eMsgType = NCI_HAL_ERROR_MSG;
+    }
+    msg.pMsgData = NULL;
+    msg.Size = 0;
+
+    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+            (phLibNfc_Message_t *) &msg);
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_pre_discover
+ *
+ * Description      This function is called by libnfc-nci to perform any
+ *                  proprietary exchange before RF discovery. When proprietary
+ *                  exchange is over completion is informed to libnfc-nci
+ *                  through phNxpNciHal_pre_discover_complete function.
+ *
+ * Returns          It always returns NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_pre_discover(void)
+{
+    /* Nothing to do here for initial version */
+    return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_pre_discover_complete
+ *
+ * Description      This function informs libnfc-nci about completion and
+ *                  status of phNxpNciHal_pre_discover through callback.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_pre_discover_complete(NFCSTATUS status)
+{
+    static phLibNfc_Message_t msg;
+
+    if (status == NFCSTATUS_SUCCESS)
+    {
+        msg.eMsgType = NCI_HAL_PRE_DISCOVER_CPLT_MSG;
+    }
+    else
+    {
+        msg.eMsgType = NCI_HAL_ERROR_MSG;
+    }
+    msg.pMsgData = NULL;
+    msg.Size = 0;
+
+    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+            &msg);
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_close
+ *
+ * Description      This function close the NFCC interface and free all
+ *                  resources.This is called by libnfc-nci on NFC service stop.
+ *
+ * Returns          Always return NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_close(void)
+{
+    NFCSTATUS status;
+    /*NCI_RESET_CMD*/
+    static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x00};
+
+    static uint8_t cmd_ce_disc_nci[] = {0x21,0x03,0x07,0x03,0x80,0x01,0x81,0x01,0x82,0x01};
+
+    CONCURRENCY_LOCK();
+
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_ce_disc_nci),cmd_ce_disc_nci);
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("CMD_CE_DISC_NCI: Failed");
+    }
+
+    nxpncihal_ctrl.halStatus = HAL_STATUS_CLOSE;
+
+    status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+    }
+
+    if (NULL != gpphTmlNfc_Context->pDevHandle)
+    {
+        phNxpNciHal_close_complete(NFCSTATUS_SUCCESS);
+        /* Abort any pending read and write */
+        status = phTmlNfc_ReadAbort();
+        status = phTmlNfc_WriteAbort();
+
+        phOsalNfc_Timer_Cleanup();
+
+        status = phTmlNfc_Shutdown();
+
+        phDal4Nfc_msgrelease(nxpncihal_ctrl.gDrvCfg.nClientId);
+
+
+        memset (&nxpncihal_ctrl, 0x00, sizeof (nxpncihal_ctrl));
+
+        NXPLOG_NCIHAL_D("phNxpNciHal_close - phOsalNfc_DeInit completed");
+    }
+
+    CONCURRENCY_UNLOCK();
+
+    phNxpNciHal_cleanup_monitor();
+
+    /* Return success always */
+    return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_close_complete
+ *
+ * Description      This function inform libnfc-nci about result of
+ *                  phNxpNciHal_close.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_close_complete(NFCSTATUS status)
+{
+    static phLibNfc_Message_t msg;
+
+    if (status == NFCSTATUS_SUCCESS)
+    {
+        msg.eMsgType = NCI_HAL_CLOSE_CPLT_MSG;
+    }
+    else
+    {
+        msg.eMsgType = NCI_HAL_ERROR_MSG;
+    }
+    msg.pMsgData = NULL;
+    msg.Size = 0;
+
+    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+            &msg);
+
+    return;
+}
+/******************************************************************************
+ * Function         phNxpNciHal_notify_i2c_fragmentation
+ *
+ * Description      This function can be used by HAL to inform
+ *                 libnfc-nci that i2c fragmentation is enabled/disabled
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_notify_i2c_fragmentation(void)
+{
+    if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+    {
+        /*inform libnfc-nci that i2c fragmentation is enabled/disabled */
+        (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT,
+                HAL_NFC_STATUS_OK);
+    }
+}
+/******************************************************************************
+ * Function         phNxpNciHal_control_granted
+ *
+ * Description      Called by libnfc-nci when NFCC control is granted to HAL.
+ *
+ * Returns          Always returns NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_control_granted(void)
+{
+    /* Take the concurrency lock so no other calls from upper layer
+     * will be allowed
+     */
+    CONCURRENCY_LOCK();
+
+    if(NULL != nxpncihal_ctrl.p_control_granted_cback)
+    {
+        (*nxpncihal_ctrl.p_control_granted_cback)();
+    }
+    /* At the end concurrency unlock so calls from upper layer will
+     * be allowed
+     */
+    CONCURRENCY_UNLOCK();
+    return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_request_control
+ *
+ * Description      This function can be used by HAL to request control of
+ *                  NFCC to libnfc-nci. When control is provided to HAL it is
+ *                  notified through phNxpNciHal_control_granted.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_request_control(void)
+{
+    if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+    {
+        /* Request Control of NCI Controller from NCI NFC Stack */
+        (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_REQUEST_CONTROL_EVT,
+                HAL_NFC_STATUS_OK);
+    }
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_release_control
+ *
+ * Description      This function can be used by HAL to release the control of
+ *                  NFCC back to libnfc-nci.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_release_control(void)
+{
+    if (nxpncihal_ctrl.p_nfc_stack_cback != NULL)
+    {
+        /* Release Control of NCI Controller to NCI NFC Stack */
+        (*nxpncihal_ctrl.p_nfc_stack_cback)(HAL_NFC_RELEASE_CONTROL_EVT,
+                HAL_NFC_STATUS_OK);
+    }
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_power_cycle
+ *
+ * Description      This function is called by libnfc-nci when power cycling is
+ *                  performed. When processing is complete it is notified to
+ *                  libnfc-nci through phNxpNciHal_power_cycle_complete.
+ *
+ * Returns          Always return NFCSTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+int phNxpNciHal_power_cycle(void)
+{
+    NXPLOG_NCIHAL_D("Power Cycle");
+
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+
+    if(NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_NCIHAL_D("PN54X Reset - SUCCESS\n");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("PN54X Reset - FAILED\n");
+    }
+
+    phNxpNciHal_power_cycle_complete(NFCSTATUS_SUCCESS);
+
+    return NFCSTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_power_cycle_complete
+ *
+ * Description      This function is called to provide the status of
+ *                  phNxpNciHal_power_cycle to libnfc-nci through callback.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_power_cycle_complete(NFCSTATUS status)
+{
+    static phLibNfc_Message_t msg;
+
+    if (status == NFCSTATUS_SUCCESS)
+    {
+        msg.eMsgType = NCI_HAL_OPEN_CPLT_MSG;
+    }
+    else
+    {
+        msg.eMsgType = NCI_HAL_ERROR_MSG;
+    }
+    msg.pMsgData = NULL;
+    msg.Size = 0;
+
+    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+            &msg);
+
+    return;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_set_clock
+ *
+ * Description      This function is called after successfull download
+ *                  to apply the clock setting provided in config file
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_set_clock(void)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    int retryCount = 0;
+
+retrySetclock:
+    phNxpNciClock.isClockSet = TRUE;
+    if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
+    {
+        static uint8_t set_clock_cmd[] = {0x20, 0x02,0x09, 0x02, 0xA0, 0x03, 0x01, 0x11,
+                                                               0xA0, 0x04, 0x01, 0x01};
+        uint8_t param_clock_src = CLK_SRC_PLL;
+        param_clock_src = param_clock_src << 3;
+
+        if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
+        {
+            param_clock_src |= 0x00;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
+        {
+            param_clock_src |= 0x01;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
+        {
+            param_clock_src |= 0x02;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
+        {
+            param_clock_src |= 0x03;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
+        {
+            param_clock_src |= 0x04;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
+        {
+            param_clock_src |= 0x05;
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
+            param_clock_src = 0x11;
+        }
+
+        set_clock_cmd[7] = param_clock_src;
+        set_clock_cmd[11] = nxpprofile_ctrl.bTimeout;
+        status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("PLL colck setting failed !!");
+        }
+    }
+    else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
+    {
+        static uint8_t set_clock_cmd[] = {0x20, 0x02, 0x05, 0x01, 0xA0, 0x03, 0x01, 0x08};
+        status = phNxpNciHal_send_ext_cmd(sizeof(set_clock_cmd), set_clock_cmd);
+        if (status != NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_E("XTAL colck setting failed !!");
+        }
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
+    }
+
+   // Checking for SET CONFG SUCCESS, re-send the command  if not.
+    phNxpNciClock.isClockSet = FALSE;
+    if(phNxpNciClock.p_rx_data[3]   != NFCSTATUS_SUCCESS )
+    {
+        if(retryCount++  < 3)
+        {
+            NXPLOG_NCIHAL_E("Set-clk failed retry again ");
+            goto retrySetclock;
+        }
+        else
+        {
+            NXPLOG_NCIHAL_D("Set clk  failed -  max count = 0x%x exceeded ", retryCount);
+//            NXPLOG_NCIHAL_E("Set Config is failed for Clock Due to elctrical disturbances, aborting the NFC process");
+//            abort ();
+       }
+    }
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_check_clock_config
+ *
+ * Description      This function is called after successfull download
+ *                  to check if clock settings in config file and chip
+ *                  is same
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_check_clock_config(void)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint8_t param_clock_src;
+    static uint8_t get_clock_cmd[] = {0x20, 0x03,0x07, 0x03, 0xA0, 0x02,
+            0xA0, 0x03, 0xA0, 0x04};
+    phNxpNciClock.isClockSet = TRUE;
+    phNxpNciHal_get_clk_freq();
+    status = phNxpNciHal_send_ext_cmd(sizeof(get_clock_cmd),get_clock_cmd);
+
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("unable to retrieve get_clk_src_sel");
+        return status;
+    }
+    param_clock_src = check_config_parameter();
+    if( phNxpNciClock.p_rx_data[12] == param_clock_src &&  phNxpNciClock.p_rx_data[16] == nxpprofile_ctrl.bTimeout)
+    {
+        phNxpNciClock.issetConfig = FALSE;
+    }else {
+        phNxpNciClock.issetConfig = TRUE;
+    }
+    phNxpNciClock.isClockSet = FALSE;
+
+    return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_china_tianjin_rf_setting
+ *
+ * Description      This function is called to check RF Setting
+ *
+ * Returns          Status.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_china_tianjin_rf_setting(void)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    int isfound = 0;
+    int rf_enable = FALSE;
+    int rf_val = 0;
+    int send_flag;
+    uint8_t retry_cnt =0;
+    int enable_bit =0;
+    static uint8_t get_rf_cmd[] = {0x20, 0x03,0x03, 0x01, 0xA0, 0x85};
+
+retry_send_ext:
+    if(retry_cnt > 3)
+    {
+        return NFCSTATUS_FAILED;
+    }
+    send_flag = TRUE;
+    phNxpNciRfSet.isGetRfSetting = TRUE;
+    status = phNxpNciHal_send_ext_cmd(sizeof(get_rf_cmd),get_rf_cmd);
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("unable to get the RF setting");
+        phNxpNciRfSet.isGetRfSetting = FALSE;
+        retry_cnt++;
+        goto retry_send_ext;
+    }
+    phNxpNciRfSet.isGetRfSetting = FALSE;
+    if(phNxpNciRfSet.p_rx_data[3] != 0x00)
+    {
+        NXPLOG_NCIHAL_E("GET_CONFIG_RSP is FAILED for CHINA TIANJIN");
+        return status;
+    }
+    rf_val = phNxpNciRfSet.p_rx_data[10];
+    isfound = (GetNxpNumValue(NAME_NXP_CHINA_TIANJIN_RF_ENABLED, (void *)&rf_enable, sizeof(rf_enable)));
+    if(isfound >0)
+    {
+        enable_bit = rf_val & 0x40;
+        if((enable_bit != 0x40) && (rf_enable == 1))
+        {
+            phNxpNciRfSet.p_rx_data[10] |= 0x40;   // Enable if it is disabled
+        }
+        else if((enable_bit == 0x40) && (rf_enable == 0))
+        {
+            phNxpNciRfSet.p_rx_data[10] &= 0xBF;  // Disable if it is Enabled
+        }
+        else
+        {
+            send_flag = FALSE;  // No need to change in RF setting
+        }
+
+        if(send_flag == TRUE)
+        {
+            static uint8_t set_rf_cmd[] = {0x20, 0x02, 0x08, 0x01, 0xA0, 0x85, 0x04, 0x50, 0x08, 0x68, 0x00};
+            memcpy(&set_rf_cmd[4],&phNxpNciRfSet.p_rx_data[5],7);
+            status = phNxpNciHal_send_ext_cmd(sizeof(set_rf_cmd),set_rf_cmd);
+            if(status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E("unable to set the RF setting");
+                retry_cnt++;
+                goto retry_send_ext;
+            }
+        }
+    }
+
+    return status;
+}
+
+int  check_config_parameter()
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    uint8_t param_clock_src = CLK_SRC_PLL;
+    if (nxpprofile_ctrl.bClkSrcVal == CLK_SRC_PLL)
+    {
+        param_clock_src = param_clock_src << 3;
+
+        if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_13MHZ)
+        {
+            param_clock_src |= 0x00;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_19_2MHZ)
+        {
+            param_clock_src |= 0x01;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_24MHZ)
+        {
+            param_clock_src |= 0x02;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_26MHZ)
+        {
+            param_clock_src |= 0x03;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_38_4MHZ)
+        {
+            param_clock_src |= 0x04;
+        }
+        else if (nxpprofile_ctrl.bClkFreqVal == CLK_FREQ_52MHZ)
+        {
+            param_clock_src |= 0x05;
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("Wrong clock freq, send default PLL@19.2MHz");
+            param_clock_src = 0x11;
+        }
+    }
+    else if(nxpprofile_ctrl.bClkSrcVal == CLK_SRC_XTAL)
+    {
+        param_clock_src = 0x08;
+
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Wrong clock source. Dont apply any modification")
+    }
+    return param_clock_src;
+}
+/******************************************************************************
+ * Function         phNxpNciHal_enable_i2c_fragmentation
+ *
+ * Description      This function is called to process the response status
+ *                  and print the status byte.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+void phNxpNciHal_enable_i2c_fragmentation()
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    static uint8_t fragmentation_enable_config_cmd[] = { 0x20, 0x02, 0x05, 0x01, 0xA0, 0x05, 0x01, 0x10};
+    int isfound = 0;
+    long i2c_status = 0x00;
+    long config_i2c_vlaue = 0xff;
+    /*NCI_RESET_CMD*/
+    static uint8_t cmd_reset_nci[] = {0x20,0x00,0x01,0x01};
+    /*NCI_INIT_CMD*/
+    static uint8_t cmd_init_nci[] = {0x20,0x01,0x00};
+    static uint8_t get_i2c_fragmentation_cmd[] = {0x20, 0x03, 0x03, 0x01 ,0xA0 ,0x05};
+    isfound = (GetNxpNumValue(NAME_NXP_I2C_FRAGMENTATION_ENABLED, (void *)&i2c_status, sizeof(i2c_status)));
+    status = phNxpNciHal_send_ext_cmd(sizeof(get_i2c_fragmentation_cmd),get_i2c_fragmentation_cmd);
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("unable to retrieve  get_i2c_fragmentation_cmd");
+    }
+    else
+    {
+        if(nxpncihal_ctrl.p_rx_data[8] == 0x10)
+        {
+            config_i2c_vlaue = 0x01;
+            phNxpNciHal_notify_i2c_fragmentation();
+            phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
+        }
+        else if(nxpncihal_ctrl.p_rx_data[8] == 0x00)
+        {
+            config_i2c_vlaue = 0x00;
+        }
+        if( config_i2c_vlaue == i2c_status)
+        {
+            NXPLOG_NCIHAL_E("i2c_fragmentation_status existing");
+        }
+        else
+        {
+            if (i2c_status == 0x01)
+            {
+                /* NXP I2C fragmenation enabled*/
+                status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
+                if (status != NFCSTATUS_SUCCESS)
+                {
+                    NXPLOG_NCIHAL_E("NXP fragmentation enable failed");
+                }
+            }
+            else if (i2c_status == 0x00 || config_i2c_vlaue == 0xff)
+            {
+                fragmentation_enable_config_cmd[7] = 0x00;
+                /* NXP I2C fragmentation disabled*/
+                status = phNxpNciHal_send_ext_cmd(sizeof(fragmentation_enable_config_cmd), fragmentation_enable_config_cmd);
+                if (status != NFCSTATUS_SUCCESS)
+                {
+                    NXPLOG_NCIHAL_E("NXP fragmentation disable failed");
+                }
+            }
+            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_reset_nci),cmd_reset_nci);
+            if(status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E ("NCI_CORE_RESET: Failed");
+            }
+            status = phNxpNciHal_send_ext_cmd(sizeof(cmd_init_nci),cmd_init_nci);
+            if(status != NFCSTATUS_SUCCESS)
+            {
+                NXPLOG_NCIHAL_E ("NCI_CORE_INIT : Failed");
+            }
+            else if(i2c_status == 0x01)
+            {
+                phNxpNciHal_notify_i2c_fragmentation();
+                phTmlNfc_set_fragmentation_enabled(I2C_FRAGMENTATION_ENABLED);
+            }
+        }
+    }
+}
+/******************************************************************************
+ * Function         phNxpNciHal_check_factory_reset
+ *
+ * Description      This function is called at init time to check
+ *                  the presence of ese related info. If file are not
+ *                  present set the SWP_INT_SESSION_ID_CFG to FF to
+ *                  force the NFCEE to re-run its initialization sequence.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_check_factory_reset(void)
+{
+    struct stat st;
+    int ret = 0;
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    const char config_eseinfo_path[] = "/data/nfc/nfaStorage.bin1";
+    static uint8_t reset_ese_session_identity_set[] = { 0x20, 0x02, 0x17, 0x02,
+                                      0xA0, 0xEA, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                                      0xA0, 0xEB, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+    static uint8_t reset_ese_session_identity[] = { 0x20, 0x03, 0x05, 0x02,
+                                          0xA0, 0xEA, 0xA0, 0xEB};
+#endif
+    if (stat(config_eseinfo_path, &st) == -1)
+    {
+        NXPLOG_NCIHAL_D("%s file not present = %s", __FUNCTION__, config_eseinfo_path);
+        ret = -1;
+    }
+    else
+    {
+        ret = 0;
+    }
+
+    if(ret == -1)
+    {
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+        /* NXP ACT Proprietary Ext */
+        status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
+                                           reset_ese_session_identity);
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
+        }
+#endif
+        status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity_set),
+                                           reset_ese_session_identity_set);
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("NXP reset_ese_session_identity_set command failed");
+        }
+#ifdef PN547C2_FACTORY_RESET_DEBUG
+        /* NXP ACT Proprietary Ext */
+        status = phNxpNciHal_send_ext_cmd(sizeof(reset_ese_session_identity),
+                                           reset_ese_session_identity);
+        if (status != NFCSTATUS_SUCCESS) {
+            NXPLOG_NCIHAL_E("NXP reset_ese_session_identity command failed");
+        }
+#endif
+
+    }
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_print_res_status
+ *
+ * Description      This function is called to process the response status
+ *                  and print the status byte.
+ *
+ * Returns          void.
+ *
+ ******************************************************************************/
+static void phNxpNciHal_print_res_status( uint8_t *p_rx_data, uint16_t *p_len)
+{
+    static uint8_t response_buf[][30] = {"STATUS_OK",
+                                     "STATUS_REJECTED",
+                                     "STATUS_RF_FRAME_CORRUPTED" ,
+                                     "STATUS_FAILED" ,
+                                     "STATUS_NOT_INITIALIZED" ,
+                                     "STATUS_SYNTAX_ERROR",
+                                     "STATUS_SEMANTIC_ERROR",
+                                     "RFU",
+                                     "RFU",
+                                     "STATUS_INVALID_PARAM",
+                                     "STATUS_MESSAGE_SIZE_EXCEEDED",
+                                     "STATUS_UNDEFINED"};
+    int status_byte;
+    if(p_rx_data[0] == 0x40 && (p_rx_data[1] == 0x02 || p_rx_data[1] == 0x03))
+    {
+        if(p_rx_data[2] &&  p_rx_data[3]<=10)
+        {
+            status_byte = p_rx_data[CORE_RES_STATUS_BYTE];
+            NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[status_byte]);
+        }
+        else
+        {
+            NXPLOG_NCIHAL_D("%s: response status =%s",__FUNCTION__,response_buf[11]);
+        }
+        if(phNxpNciClock.isClockSet)
+        {
+            int i;
+            for(i=0; i<* p_len; i++)
+            {
+                phNxpNciClock.p_rx_data[i] = p_rx_data[i];
+            }
+        }
+
+        if(phNxpNciRfSet.isGetRfSetting)
+        {
+            int i;
+            for(i=0; i<* p_len; i++)
+            {
+                phNxpNciRfSet.p_rx_data[i] = p_rx_data[i];
+                //NXPLOG_NCIHAL_D("%s: response status =0x%x",__FUNCTION__,p_rx_data[i]);
+            }
+
+        }
+    }
+
+if((p_rx_data[2])&&(config_access == TRUE))
+    {
+        if(p_rx_data[3]!=NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_W("Invalid Data from config file . Aborting..");
+            phNxpNciHal_close();
+        }
+    }
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal.h b/halimpl/pn54x/hal/phNxpNciHal.h
new file mode 100644
index 0000000..fa7b637
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2010-2014 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 _PHNXPNCIHAL_H_
+#define _PHNXPNCIHAL_H_
+
+#include <hardware/nfc.h>
+#include <phNxpNciHal_utils.h>
+
+/********************* Definitions and structures *****************************/
+#define MAX_RETRY_COUNT       5
+#define NCI_MAX_DATA_LEN      300
+#define NCI_POLL_DURATION     500
+#define HAL_NFC_ENABLE_I2C_FRAGMENTATION_EVT    0x07
+#undef P2P_PRIO_LOGIC_HAL_IMP
+
+typedef void (phNxpNciHal_control_granted_callback_t)();
+
+/* NCI Data */
+typedef struct nci_data
+{
+    uint16_t len;
+    uint8_t p_data[NCI_MAX_DATA_LEN];
+} nci_data_t;
+
+typedef enum
+{
+   HAL_STATUS_OPEN = 0,
+   HAL_STATUS_CLOSE
+} phNxpNci_HalStatus;
+
+/* Macros to enable and disable extensions */
+#define HAL_ENABLE_EXT()    (nxpncihal_ctrl.hal_ext_enabled = 1)
+#define HAL_DISABLE_EXT()   (nxpncihal_ctrl.hal_ext_enabled = 0)
+
+/* NCI Control structure */
+typedef struct phNxpNciHal_Control
+{
+    phNxpNci_HalStatus   halStatus;      /* Indicate if hal is open or closed */
+    pthread_t client_thread;  /* Integration thread handle */
+    uint8_t   thread_running; /* Thread running if set to 1, else set to 0 */
+    phLibNfc_sConfig_t   gDrvCfg; /* Driver config data */
+
+    /* Rx data */
+    uint8_t  *p_rx_data;
+    uint16_t rx_data_len;
+
+    /* libnfc-nci callbacks */
+    nfc_stack_callback_t *p_nfc_stack_cback;
+    nfc_stack_data_callback_t *p_nfc_stack_data_cback;
+
+    /* control granted callback */
+    phNxpNciHal_control_granted_callback_t *p_control_granted_cback;
+
+    /* HAL open status */
+    bool_t hal_open_status;
+
+    /* HAL extensions */
+    uint8_t hal_ext_enabled;
+
+    /* Waiting semaphore */
+    phNxpNciHal_Sem_t ext_cb_data;
+
+    uint16_t cmd_len;
+    uint8_t p_cmd_data[NCI_MAX_DATA_LEN];
+    uint16_t rsp_len;
+    uint8_t p_rsp_data[NCI_MAX_DATA_LEN];
+
+    /* retry count used to force download */
+    uint16_t retry_cnt;
+    uint8_t read_retry_cnt;
+} phNxpNciHal_Control_t;
+
+typedef struct phNxpNciClock{
+    bool_t  isClockSet;
+    uint8_t  p_rx_data[20];
+    bool_t  issetConfig;
+}phNxpNciClock_t;
+
+typedef struct phNxpNciRfSetting{
+    bool_t  isGetRfSetting;
+    uint8_t  p_rx_data[20];
+}phNxpNciRfSetting_t;
+
+
+typedef enum {
+    NFC_FORUM_PROFILE,
+    EMV_CO_PROFILE,
+    INVALID_PROFILe
+}phNxpNciProfile_t;
+/* NXP Poll Profile control structure */
+typedef struct phNxpNciProfile_Control
+{
+    phNxpNciProfile_t profile_type;
+    uint8_t                      bClkSrcVal;     /* Holds the System clock source read from config file */
+    uint8_t                      bClkFreqVal;    /* Holds the System clock frequency read from config file */
+    uint8_t                      bTimeout;       /* Holds the Timeout Value */
+} phNxpNciProfile_Control_t;
+
+/* Internal messages to handle callbacks */
+#define NCI_HAL_OPEN_CPLT_MSG             0x411
+#define NCI_HAL_CLOSE_CPLT_MSG            0x412
+#define NCI_HAL_POST_INIT_CPLT_MSG        0x413
+#define NCI_HAL_PRE_DISCOVER_CPLT_MSG     0x414
+#define NCI_HAL_ERROR_MSG                 0x415
+#define NCI_HAL_RX_MSG                    0xF01
+
+#define NCIHAL_CMD_CODE_LEN_BYTE_OFFSET         (2U)
+#define NCIHAL_CMD_CODE_BYTE_LEN                (3U)
+
+/******************** NCI HAL exposed functions *******************************/
+
+void phNxpNciHal_request_control (void);
+void phNxpNciHal_release_control (void);
+int phNxpNciHal_write_unlocked (uint16_t data_len, const uint8_t *p_data);
+
+#endif /* _PHNXPNCIHAL_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal_Kovio.c b/halimpl/pn54x/hal/phNxpNciHal_Kovio.c
new file mode 100644
index 0000000..3489b8f
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_Kovio.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2012-2014 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 <phNxpNciHal_Kovio.h>
+#include <phNxpLog.h>
+
+
+#define KOVIO_TIMEOUT 1000    /* Timeout value to wait for RF INTF Activated NTF.*/
+#define KOVIO_ACT_NTF_TEMP_BUFF_LEN 32    /* length of temp buffer to manipulate
+                                    the activated notification to match BCM format*/
+#define MAX_WRITE_RETRY 5
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
+
+int kovio_detected = 0x00;
+int send_to_upper_kovio = 0x01;
+int disable_kovio=0x00;
+static uint8_t rf_deactivate_cmd[]   = { 0x21, 0x06, 0x01, 0x03 }; /* discovery */
+static uint8_t rf_deactivated_ntf[]  = { 0x61, 0x06, 0x02, 0x03, 0x01 };
+static uint8_t reset_ntf[] = {0x60, 0x00, 0x06, 0xA0, 0x00, 0xC7, 0xD4, 0x00, 0x00};
+
+static uint32_t kovio_timer;
+
+/************** Kovio functions ***************************************/
+
+static NFCSTATUS phNxpNciHal_rf_deactivate(void);
+
+/*******************************************************************************
+**
+** Function         hal_write_cb
+**
+** Description      Callback function for hal write.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    UNUSED(pContext);
+    UNUSED(pInfo);
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         kovio_timer_handler
+**
+** Description      Callback function for kovio timer.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void kovio_timer_handler(uint32_t timerId, void *pContext)
+{
+    UNUSED(timerId);
+    UNUSED(pContext);
+    NXPLOG_NCIHAL_D(">> kovio_timer_handler. Did not receive RF_INTF_ACTIVATED_NTF, Kovio TAG must be removed.");
+
+    phOsalNfc_Timer_Delete(kovio_timer);
+
+    kovio_detected = 0x00;
+    send_to_upper_kovio=0x01;
+    disable_kovio=0x00;
+    /*
+     * send kovio deactivated ntf to upper layer.
+    */
+    NXPLOG_NCIHAL_D(">> send kovio deactivated ntf to upper layer.");
+    if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
+    {
+        (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+                sizeof(rf_deactivated_ntf), rf_deactivated_ntf);
+    }
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_rf_deactivate
+**
+** Description      Sends rf deactivate cmd to NFCC
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_rf_deactivate()
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    int cb_data;
+    int retryCnt = 0;
+
+    do
+    {
+        retryCnt++;
+        status = phTmlNfc_Write(rf_deactivate_cmd,
+                sizeof(rf_deactivate_cmd),
+                (pphTmlNfc_TransactCompletionCb_t) &hal_write_cb, &cb_data);
+    } while(status != NFCSTATUS_PENDING && retryCnt <= MAX_WRITE_RETRY);
+
+    if(status != NFCSTATUS_PENDING)
+    {
+        //phNxpNciHal_emergency_recovery();
+        if (nxpncihal_ctrl.p_nfc_stack_data_cback!= NULL &&
+            nxpncihal_ctrl.hal_open_status == TRUE)
+        {
+            NXPLOG_NCIHAL_D("Send the Core Reset NTF to upper layer, which will trigger the recovery\n");
+            //Send the Core Reset NTF to upper layer, which will trigger the recovery.
+            nxpncihal_ctrl.rx_data_len = sizeof(reset_ntf);
+            memcpy(nxpncihal_ctrl.p_rx_data, reset_ntf, sizeof(reset_ntf));
+            (*nxpncihal_ctrl.p_nfc_stack_data_cback)(nxpncihal_ctrl.rx_data_len, nxpncihal_ctrl.p_rx_data);
+        }
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_kovio_rsp_ext
+**
+** Description      Implements kovio presence check. In BCM controller this is
+**                  managed by NFCC. But since PN54X does not handle this, the
+**                  presence check is mimiced here.
+**                  For the very first time Kovio is detected, NTF has to be
+**                  passed on to upper layer. for every NTF, DH send a deactivated
+**                  command to NFCC and NFCC follows this up with another activated
+**                  notification. When the tag is removed, activated notification
+**                  stops coming and this is indicated to upper layer with a HAL
+**                  generated deactivated notification.
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_kovio_rsp_ext(uint8_t *p_ntf, uint16_t *p_len)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint8_t tBuff[KOVIO_ACT_NTF_TEMP_BUFF_LEN];
+
+    send_to_upper_kovio = 1;
+    if((p_ntf[0]==0x61)&&(p_ntf[1]==0x05))
+    {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+        if((p_ntf[5]==0x81)&&(p_ntf[6]==0x70))
+#else
+        if((p_ntf[5]==0x8A)&&(p_ntf[6]==0x77))
+#endif
+        {
+            if (kovio_detected == 0)
+            {
+                if((*p_len-9)<KOVIO_ACT_NTF_TEMP_BUFF_LEN)
+                {
+                    p_ntf[2]+=1;
+                    memcpy(tBuff, &p_ntf[9], *p_len-9);
+                    p_ntf[9]=p_ntf[9]+1;
+                    memcpy(&p_ntf[10], tBuff, *p_len-9);
+                    *p_len+=1;
+                }else
+                {
+                    NXPLOG_NCIHAL_D("Kovio Act ntf payload exceeded temp buffer size");
+                }
+                kovio_detected = 1;
+                kovio_timer = phOsalNfc_Timer_Create();
+                NXPLOG_NCIHAL_D("custom kovio timer Created - %d", kovio_timer);
+            }
+            else
+            {
+                send_to_upper_kovio = 0;
+            }
+            NXPLOG_NCIHAL_D("Send RF deactivate command to NFCC");
+            status = phNxpNciHal_rf_deactivate();
+            status = phOsalNfc_Timer_Start(kovio_timer,
+                    KOVIO_TIMEOUT,
+                    &kovio_timer_handler,
+                    NULL);
+            if (NFCSTATUS_SUCCESS == status)
+            {
+                NXPLOG_NCIHAL_D("kovio timer started");
+            }
+            else
+            {
+                NXPLOG_NCIHAL_E("kovio timer not started!!!");
+                status  = NFCSTATUS_FAILED;
+            }
+        }
+        else
+        {
+            if (kovio_detected == 1)
+            {
+                phNxpNciHal_clean_Kovio_Ext();
+                NXPLOG_NCIHAL_D ("Disabling Kovio detection logic as another tag type detected");
+            }
+        }
+    }
+    else if((p_ntf[0]==0x41)&&(p_ntf[1]==0x06)&&(p_ntf[2]==0x01)&&(p_ntf[3]==0x00))
+    {
+        if(kovio_detected == 1)
+            send_to_upper_kovio = 0;
+        if((kovio_detected == 1)&&(disable_kovio==0x01))
+        {
+            NXPLOG_NCIHAL_D ("Disabling Kovio detection logic");
+            phNxpNciHal_clean_Kovio_Ext();
+            disable_kovio=0x00;
+        }
+    }
+    else if((p_ntf[0]==0x61)&&(p_ntf[1]==0x06)&&(p_ntf[2]==0x02)&&(p_ntf[3]==0x03)&&(p_ntf[4]==0x00))
+    {
+        if(kovio_detected == 1)
+            send_to_upper_kovio = 0;
+    }
+    else if((p_ntf[0]==0x61)&&(p_ntf[1]==0x03))
+    {
+        if(kovio_detected == 1)
+            send_to_upper_kovio = 0;
+    }
+    return status;
+}
+/*******************************************************************************
+**
+** Function         phNxpNciHal_clean_Kovio_Ext
+**
+** Description      Clean up Kovio extension state machine.
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+void phNxpNciHal_clean_Kovio_Ext()
+{
+    NXPLOG_NCIHAL_D(">> Cleaning up Kovio State machine and timer.");
+    phOsalNfc_Timer_Delete(kovio_timer);
+    kovio_detected = 0x00;
+    send_to_upper_kovio=0x01;
+    disable_kovio=0x00;
+    /*
+     * send kovio deactivated ntf to upper layer.
+    */
+    NXPLOG_NCIHAL_D(">> send kovio deactivated ntf to upper layer.");
+    if (nxpncihal_ctrl.p_nfc_stack_data_cback != NULL)
+    {
+        (*nxpncihal_ctrl.p_nfc_stack_data_cback)(
+                sizeof(rf_deactivated_ntf), rf_deactivated_ntf);
+    }
+    return;
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_Kovio.h b/halimpl/pn54x/hal/phNxpNciHal_Kovio.h
new file mode 100644
index 0000000..d630e37
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_Kovio.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_KOVIO_H_
+#define _PHNXPNCIHAL_KOVIO_H_
+
+#include <phNxpNciHal.h>
+#include <phTmlNfc.h>
+#include <string.h>
+
+extern NFCSTATUS  phNxpNciHal_kovio_rsp_ext(uint8_t *p_ntf, uint16_t *p_len);
+extern void phNxpNciHal_clean_Kovio_Ext();
+
+#endif /* _PHNXPNCIHAL_KOVIO_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c
new file mode 100644
index 0000000..a2f51be
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (C) 2012-2014 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 <phNxpNciHal_NfcDepSWPrio.h>
+#include <phNxpLog.h>
+#include <phNxpNciHal.h>
+
+#define CUSTOM_POLL_TIMEOUT 160    /* Timeout value to wait for NFC-DEP detection.*/
+#define CLEAN_UP_TIMEOUT 250
+#define MAX_WRITE_RETRY 5
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
+static uint8_t cmd_stop_rf_discovery[] = { 0x21, 0x06, 0x01, 0x00 }; /* IDLE */
+static uint8_t cmd_resume_rf_discovery[] = { 0x21, 0x06, 0x01, 0x03 }; /* RF_DISCOVER */
+
+/*RF_DISCOVER_SELECT_CMD*/
+static uint8_t cmd_select_rf_discovery[] = {0x21,0x04,0x03,0x01,0x04,0x02 };
+
+static uint8_t cmd_poll[64];
+static uint8_t cmd_poll_len = 0;
+int discover_type = 0xFF;
+uint32_t cleanup_timer;
+
+/*PRIO LOGIC related dead functions undefined*/
+#ifdef P2P_PRIO_LOGIC_HAL_IMP
+
+static int iso_dep_detected = 0x00;
+static int poll_timer_fired = 0x00;
+static uint8_t bIgnorep2plogic = 0;
+static uint8_t *p_iso_ntf_buff = NULL; /* buffer to store second notification */
+static uint8_t bIgnoreIsoDep = 0;
+static uint32_t custom_poll_timer;
+
+/************** NFC-DEP SW PRIO functions ***************************************/
+
+static NFCSTATUS phNxpNciHal_start_polling_loop(void);
+static NFCSTATUS phNxpNciHal_stop_polling_loop(void);
+static NFCSTATUS phNxpNciHal_resume_polling_loop(void);
+static void phNxpNciHal_NfcDep_store_ntf(uint8_t *p_cmd_data, uint16_t cmd_len);
+
+
+/*******************************************************************************
+**
+** Function         cleanup_timer_handler
+**
+** Description      Callback function for cleanup timer.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void cleanup_timer_handler(uint32_t timerId, void *pContext)
+{
+    NXPLOG_NCIHAL_D(">> cleanup_timer_handler.");
+
+    NXPLOG_NCIHAL_D(">> cleanup_timer_handler. ISO_DEP not detected second time.");
+
+    phOsalNfc_Timer_Delete(cleanup_timer);
+    cleanup_timer=0;
+    iso_dep_detected = 0x00;
+    EnableP2P_PrioLogic = FALSE;
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         custom_poll_timer_handler
+**
+** Description      Callback function for custom poll timer.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void custom_poll_timer_handler(uint32_t timerId, void *pContext)
+{
+    NXPLOG_NCIHAL_D(">> custom_poll_timer_handler.");
+
+    NXPLOG_NCIHAL_D(">> custom_poll_timer_handler. NFC_DEP not detected. so giving early chance to ISO_DEP.");
+
+    phOsalNfc_Timer_Delete(custom_poll_timer);
+
+    if (iso_dep_detected == 0x01)
+    {
+        poll_timer_fired = 0x01;
+
+        /*
+         * Restart polling loop.
+         * When the polling loop is stopped, polling will be restarted.
+         */
+        NXPLOG_NCIHAL_D(">> custom_poll_timer_handler - restart polling loop.");
+
+        phNxpNciHal_stop_polling_loop();
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E(">> custom_poll_timer_handler - invalid flag state (iso_dep_detected)");
+    }
+
+    return;
+}
+/*******************************************************************************
+**
+** Function         phNxpNciHal_stop_polling_loop
+**
+** Description      Sends stop polling cmd to NFCC
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_stop_polling_loop()
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    pthread_t pthread;
+    discover_type = STOP_POLLING;
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    if(pthread_create(&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
+    {
+        NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop");
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_resume_polling_loop
+**
+** Description      Sends resume polling cmd to NFCC
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_resume_polling_loop()
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    pthread_t pthread;
+    discover_type = RESUME_POLLING;
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    if(pthread_create(&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
+    {
+        NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop");
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_start_polling_loop
+**
+** Description      Sends start polling cmd to NFCC
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_start_polling_loop()
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    phNxpNciHal_Sem_t cb_data;
+    pthread_t pthread;
+    discover_type = START_POLLING;
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    if(pthread_create(&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
+    {
+        NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop");
+    }
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_NfcDep_rsp_ext
+**
+** Description      Implements algorithm for NFC-DEP protocol priority over
+**                  ISO-DEP protocol.
+**                  Following the algorithm:
+**                  IF ISO-DEP detected first time,set the ISO-DEP detected flag
+**                  and resume polling loop with 60ms timeout value.
+**                      a) if than NFC-DEP detected than send the response to
+**                       libnfc-nci stack and stop the timer.
+**                      b) if NFC-DEP not detected with in 60ms, than restart the
+**                          polling loop to give early chance to ISO-DEP with a
+**                          cleanup timer.
+**                      c) if ISO-DEP detected second time send the response to
+**                          libnfc-nci stack and stop the cleanup timer.
+**                      d) if ISO-DEP not detected with in cleanup timeout, than
+**                          clear the ISO-DEP detection flag.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_NfcDep_rsp_ext(uint8_t *p_ntf, uint16_t *p_len)
+{
+    NFCSTATUS status = NFCSTATUS_INVALID_PARAMETER;
+
+    NXPLOG_NCIHAL_D(">> p_ntf[0]=%02x , p_ntf[1]=%02x",p_ntf[0],p_ntf[1]);
+
+    if(p_ntf[0] == 0x41 && p_ntf[1] == 0x04)
+    {
+        //Tag selected, Disable P2P Prio logic.
+        bIgnoreIsoDep = 1;
+        NXPLOG_NCIHAL_D(">> Tag selected, Disable P2P Prio logic.");
+
+    }
+    else if( ((p_ntf[0] == 0x61 && p_ntf[1] == 0x06) ||
+            (p_ntf[0] == 0x41 && p_ntf[1] == 0x06) ) && bIgnoreIsoDep == 1
+            )
+    {
+        //Tag deselected, enable P2P Prio logic.
+        bIgnoreIsoDep = 0x00;
+        NXPLOG_NCIHAL_D(">> Tag deselected, enable P2P Prio logic.");
+
+    }
+    if (bIgnoreIsoDep == 0x00 &&
+            p_ntf[0] == 0x61 &&
+            p_ntf[1] == 0x05 && *p_len > 5)
+    {
+        if (p_ntf[5] == 0x04 && p_ntf[6] < 0x80)
+        {
+            NXPLOG_NCIHAL_D(">> ISO DEP detected.");
+
+            if (iso_dep_detected == 0x00)
+            {
+                NXPLOG_NCIHAL_D(
+                        ">> ISO DEP detected first time. Resume polling loop");
+
+                iso_dep_detected = 0x01;
+                status = phNxpNciHal_resume_polling_loop();
+
+                custom_poll_timer = phOsalNfc_Timer_Create();
+                NXPLOG_NCIHAL_D("custom poll timer started - %d", custom_poll_timer);
+
+                status = phOsalNfc_Timer_Start(custom_poll_timer,
+                        CUSTOM_POLL_TIMEOUT,
+                        &custom_poll_timer_handler,
+                        NULL);
+
+                if (NFCSTATUS_SUCCESS == status)
+                {
+                    NXPLOG_NCIHAL_D("custom poll timer started");
+                }
+                else
+                {
+                    NXPLOG_NCIHAL_E("custom poll timer not started!!!");
+                    status  = NFCSTATUS_FAILED;
+                }
+
+                status = NFCSTATUS_FAILED;
+            }
+            else
+            {
+                NXPLOG_NCIHAL_D(">> ISO DEP detected second time.");
+                /* Store notification */
+                phNxpNciHal_NfcDep_store_ntf(p_ntf, *p_len);
+
+                /* Stop Cleanup_timer */
+                phOsalNfc_Timer_Stop(cleanup_timer);
+                phOsalNfc_Timer_Delete(cleanup_timer);
+                cleanup_timer=0;
+                EnableP2P_PrioLogic = FALSE;
+                iso_dep_detected = 0;
+                status = NFCSTATUS_SUCCESS;
+            }
+        }
+        else if (p_ntf[5] == 0x05)
+        {
+            NXPLOG_NCIHAL_D(">> NFC-DEP Detected - stopping the custom poll timer");
+
+            phOsalNfc_Timer_Stop(custom_poll_timer);
+            phOsalNfc_Timer_Delete(custom_poll_timer);
+            EnableP2P_PrioLogic = FALSE;
+            iso_dep_detected = 0;
+            status = NFCSTATUS_SUCCESS;
+        }
+        else
+        {
+            NXPLOG_NCIHAL_D(">>  detected other technology- stopping the custom poll timer");
+            phOsalNfc_Timer_Stop(custom_poll_timer);
+            phOsalNfc_Timer_Delete(custom_poll_timer);
+            EnableP2P_PrioLogic = FALSE;
+            iso_dep_detected = 0;
+            status = NFCSTATUS_INVALID_PARAMETER;
+        }
+    }
+    else if( bIgnoreIsoDep == 0x00 &&
+            ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x61
+            && p_ntf[1] == 0x06))
+            )
+    {
+        NXPLOG_NCIHAL_D(">> RF disabled");
+        if (poll_timer_fired == 0x01)
+        {
+            poll_timer_fired = 0x00;
+
+            NXPLOG_NCIHAL_D(">>restarting polling loop.");
+
+            /* start polling loop */
+            phNxpNciHal_start_polling_loop();
+            EnableP2P_PrioLogic = FALSE;
+            NXPLOG_NCIHAL_D (">> NFC DEP NOT  detected - custom poll timer expired - RF disabled");
+
+            cleanup_timer = phOsalNfc_Timer_Create();
+
+            /* Start cleanup_timer */
+            NFCSTATUS status = phOsalNfc_Timer_Start(cleanup_timer,
+                    CLEAN_UP_TIMEOUT,
+                    &cleanup_timer_handler,
+                    NULL);
+
+            if (NFCSTATUS_SUCCESS == status)
+            {
+                NXPLOG_NCIHAL_D("cleanup timer started");
+            }
+            else
+            {
+                NXPLOG_NCIHAL_E("cleanup timer not started!!!");
+                status  = NFCSTATUS_FAILED;
+            }
+
+            status = NFCSTATUS_FAILED;
+        }
+        else
+        {
+            status = NFCSTATUS_SUCCESS;
+        }
+    }
+    if (bIgnoreIsoDep == 0x00 &&
+            iso_dep_detected == 1)
+    {
+        if ((p_ntf[0] == 0x41 && p_ntf[1] == 0x06) || (p_ntf[0] == 0x61
+                && p_ntf[1] == 0x06))
+        {
+            NXPLOG_NCIHAL_D(">>iso_dep_detected Disconnect related notification");
+            status = NFCSTATUS_FAILED;
+        }
+        else
+        {
+            NXPLOG_NCIHAL_W("Never come here");
+        }
+    }
+
+    return status;
+}
+/*******************************************************************************
+**
+** Function         phNxpNciHal_NfcDep_store_ntf
+**
+** Description      Stores the iso dep notification locally.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phNxpNciHal_NfcDep_store_ntf(uint8_t *p_cmd_data, uint16_t cmd_len)
+{
+    p_iso_ntf_buff = NULL;
+
+    p_iso_ntf_buff = malloc(sizeof (uint8_t) * cmd_len);
+    if (p_iso_ntf_buff == NULL)
+    {
+        NXPLOG_NCIHAL_E("Error allocating memory (p_iso_ntf_buff)");
+        return;
+    }
+    memcpy(p_iso_ntf_buff, p_cmd_data, cmd_len);
+    bIgnorep2plogic = 1;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_NfcDep_comapre_ntf
+**
+** Description      Compare the notification with previous iso dep notification.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_NfcDep_comapre_ntf(uint8_t *p_cmd_data, uint16_t cmd_len)
+{
+   NFCSTATUS status = NFCSTATUS_FAILED;
+   int32_t ret_val = -1;
+
+   if (bIgnorep2plogic == 1)
+   {
+        ret_val = memcmp(p_cmd_data,p_iso_ntf_buff, cmd_len);
+        if(ret_val != 0)
+        {
+            NXPLOG_NCIHAL_E("Third notification is not equal to last");
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("Third notification is equal to last (disable p2p logic)");
+            status = NFCSTATUS_SUCCESS;
+        }
+        bIgnorep2plogic = 0;
+    }
+    if (p_iso_ntf_buff != NULL)
+    {
+        free(p_iso_ntf_buff);
+        p_iso_ntf_buff = NULL;
+    }
+
+    return status;
+}
+
+
+extern NFCSTATUS phNxpNciHal_clean_P2P_Prio()
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    iso_dep_detected = 0x00;
+    EnableP2P_PrioLogic = FALSE;
+    poll_timer_fired = 0x00;
+    bIgnorep2plogic = 0x00;
+    bIgnoreIsoDep = 0x00;
+
+    status = phOsalNfc_Timer_Stop(cleanup_timer);
+    status |= phOsalNfc_Timer_Delete(cleanup_timer);
+
+    status |= phOsalNfc_Timer_Stop(custom_poll_timer);
+    status |= phOsalNfc_Timer_Delete(custom_poll_timer);
+    cleanup_timer=0;
+    return status;
+}
+
+#endif
+/*******************************************************************************
+**
+** Function         hal_write_cb
+**
+** Description      Callback function for hal write.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+    if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("hal_write_cb: write successful status = 0x%x", pInfo->wStatus);
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("hal_write_cb: write error status = 0x%x", pInfo->wStatus);
+    }
+
+    p_cb_data->status = pInfo->wStatus;
+
+    SEM_POST(p_cb_data);
+    return;
+}
+
+/*******************************************************************************
+ **
+ ** Function         tmp_thread
+ **
+ ** Description      Thread to execute custom poll commands .
+ **
+ ** Returns          None
+ **
+ *******************************************************************************/
+void *tmp_thread(void *tmp)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint16_t data_len;
+    NXPLOG_NCIHAL_E("tmp_thread: enter type=0x0%x",  *((int*)tmp));
+    usleep(10*1000);
+
+    switch( *((int*)tmp) )
+    {
+    case START_POLLING:
+    {
+        CONCURRENCY_LOCK();
+        data_len = phNxpNciHal_write_unlocked(cmd_poll_len, cmd_poll);
+        CONCURRENCY_UNLOCK();
+
+        if(data_len != cmd_poll_len)
+        {
+            NXPLOG_NCIHAL_E("phNxpNciHal_start_polling_loop: data len mismatch");
+            status = NFCSTATUS_FAILED;
+        }
+    }
+    break;
+
+    case RESUME_POLLING:
+    {
+        CONCURRENCY_LOCK();
+        data_len = phNxpNciHal_write_unlocked(sizeof(cmd_resume_rf_discovery),
+                cmd_resume_rf_discovery);
+        CONCURRENCY_UNLOCK();
+
+        if(data_len != sizeof(cmd_resume_rf_discovery))
+        {
+            NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch");
+            status = NFCSTATUS_FAILED;
+        }
+    }
+    break;
+
+    case STOP_POLLING:
+    {
+        CONCURRENCY_LOCK();
+        data_len = phNxpNciHal_write_unlocked(sizeof(cmd_stop_rf_discovery),
+                cmd_stop_rf_discovery);
+        CONCURRENCY_UNLOCK();
+
+        if(data_len != sizeof(cmd_stop_rf_discovery))
+        {
+            NXPLOG_NCIHAL_E("phNxpNciHal_stop_polling_loop: data len mismatch");
+            status = NFCSTATUS_FAILED;
+        }
+    }
+    break;
+
+    case DISCOVER_SELECT:
+    {
+        CONCURRENCY_LOCK();
+        data_len = phNxpNciHal_write_unlocked(sizeof(cmd_select_rf_discovery),
+                cmd_select_rf_discovery);
+        CONCURRENCY_UNLOCK();
+
+        if(data_len != sizeof(cmd_resume_rf_discovery))
+        {
+            NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop: data len mismatch");
+            status = NFCSTATUS_FAILED;
+        }
+    }
+    break;
+
+    default:
+        NXPLOG_NCIHAL_E("No Matching case");
+        status = NFCSTATUS_FAILED;
+        break;
+    }
+
+    NXPLOG_NCIHAL_E("tmp_thread: exit");
+    return NULL;
+}
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_select_RF_Discovery
+ **
+ ** Description     Sends RF_DISCOVER_SELECT_CMD
+ ** Parameters    RfID ,  RfProtocolType
+ ** Returns          NFCSTATUS_PENDING if success
+ **
+ *******************************************************************************/
+NFCSTATUS phNxpNciHal_select_RF_Discovery(unsigned int RfID,unsigned int RfProtocolType)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    pthread_t pthread;
+    discover_type = DISCOVER_SELECT;
+    cmd_select_rf_discovery[3]=RfID;
+    cmd_select_rf_discovery[4]=RfProtocolType;
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    if(pthread_create(&pthread, &attr, tmp_thread, (void*) &discover_type) != 0)
+    {
+        NXPLOG_NCIHAL_E("phNxpNciHal_resume_polling_loop");
+    }
+
+    return status;
+}
+/*******************************************************************************
+**
+** Function         phNxpNciHal_NfcDep_cmd_ext
+**
+** Description      Stores the polling loop configuration locally.
+**
+** Returns          None
+**
+*******************************************************************************/
+void phNxpNciHal_NfcDep_cmd_ext(uint8_t *p_cmd_data, uint16_t *cmd_len)
+{
+    if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03)
+    {
+        if (*cmd_len == 6 && p_cmd_data[3] == 0x01 && p_cmd_data[4] == 0x02
+                && p_cmd_data[5] == 0x01)
+        {
+            /* DO NOTHING */
+        }
+        else
+        {
+            /* Store the polling loop configuration */
+            cmd_poll_len = *cmd_len;
+            memset(&cmd_poll, 0, cmd_poll_len);
+            memcpy(&cmd_poll, p_cmd_data, cmd_poll_len);
+        }
+    }
+
+    return;
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h
new file mode 100644
index 0000000..4e56084
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_NfcDepSWPrio.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_NFCDEPSWPRIO_H_
+#define _PHNXPNCIHAL_NFCDEPSWPRIO_H_
+
+#include <phNxpNciHal.h>
+#include <phTmlNfc.h>
+#include <string.h>
+
+#define START_POLLING    0x00
+#define RESUME_POLLING   0x01
+#define STOP_POLLING     0x02
+#define DISCOVER_SELECT  0x03
+#define CLEAR_PIPE_RSP   0x04
+
+extern uint8_t EnableP2P_PrioLogic;
+
+extern NFCSTATUS  phNxpNciHal_NfcDep_rsp_ext(uint8_t *p_ntf, uint16_t *p_len);
+extern void  phNxpNciHal_NfcDep_cmd_ext(uint8_t *p_cmd_data, uint16_t *cmd_len);
+extern NFCSTATUS phNxpNciHal_NfcDep_comapre_ntf(uint8_t *p_cmd_data, uint16_t cmd_len);
+extern NFCSTATUS phNxpNciHal_select_RF_Discovery(unsigned int RfID,unsigned int RfProtocolType);
+extern NFCSTATUS phNxpNciHal_clean_P2P_Prio();
+extern NFCSTATUS phNxpNciHal_send_clear_pipe_rsp(void);
+
+#endif /* _PHNXPNCIHAL_NFCDEPSWPRIO_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal_dta.c b/halimpl/pn54x/hal/phNxpNciHal_dta.c
new file mode 100644
index 0000000..46b7604
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_dta.c
@@ -0,0 +1,260 @@
+ /*
+ * Copyright (C) 2012-2014 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 <phNxpLog.h>
+#include <phNxpNciHal_dta.h>
+#include <phNxpConfig.h>
+
+/*********************** Global Variables *************************************/
+static phNxpDta_Control_t nxpdta_ctrl = {0,0,0};
+
+/*******************************************************************************
+**
+** Function         phNxpEnable_DtaMode
+**
+** Description      This function configures
+**                  HAL in DTA mode
+**
+*******************************************************************************/
+void phNxpEnable_DtaMode (uint16_t pattern_no)
+{
+    nxpdta_ctrl.dta_ctrl_flag = FALSE;
+    nxpdta_ctrl.dta_t1t_flag = FALSE;
+    nxpdta_ctrl.dta_pattern_no = pattern_no;
+    ALOGD(">>>>DTA - Mode is enabled");
+    nxpdta_ctrl.dta_ctrl_flag = TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpDisable_DtaMode
+**
+** Description      This function disable DTA mode
+**
+*******************************************************************************/
+void phNxpDisable_DtaMode (void)
+{
+    nxpdta_ctrl.dta_ctrl_flag = FALSE;
+    nxpdta_ctrl.dta_t1t_flag = FALSE;
+    NXPLOG_NCIHAL_D(">>>>DTA - Mode is Disabled");
+}
+
+/******************************************************************************
+ * Function         phNxpDta_IsEnable
+ *
+ * Description      This function checks the DTA mode is enable or not.
+ *
+ * Returns          It returns TRUE if DTA enabled otherwise FALSE
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpDta_IsEnable(void)
+{
+    return nxpdta_ctrl.dta_ctrl_flag;
+}
+
+/******************************************************************************
+ * Function         phNxpDta_T1TEnable
+ *
+ * Description      This function  enables  DTA mode for T1T tag.
+ *
+ *
+ ******************************************************************************/
+void phNxpDta_T1TEnable(void)
+{
+    nxpdta_ctrl.dta_t1t_flag = TRUE;
+}
+/******************************************************************************
+ * Function         phNxpNHal_DtaUpdate
+ *
+ * Description      This function changes the command and responses specific
+ *                  to make DTA application success
+ *
+ * Returns          It return NFCSTATUS_SUCCESS then continue with send else
+ *                  sends NFCSTATUS_FAILED direct response is prepared and
+ *                  do not send anything to NFCC.
+ *
+ ******************************************************************************/
+
+NFCSTATUS phNxpNHal_DtaUpdate(uint16_t *cmd_len, uint8_t *p_cmd_data,
+        uint16_t *rsp_len, uint8_t *p_rsp_data)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    if (nxpdta_ctrl.dta_ctrl_flag == TRUE)
+    {
+        // Workaround for DTA, block the set config command with general bytes */
+        if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
+             p_cmd_data[2] == 0x17 && p_cmd_data[3] == 0x01 &&
+             p_cmd_data[4] == 0x29 && p_cmd_data[5] == 0x14 )
+        {
+            *rsp_len = 5;
+            NXPLOG_NCIHAL_D(">>>>DTA - Block set config command");
+            phNxpNciHal_print_packet("DTASEND", p_cmd_data, *cmd_len);
+
+            p_rsp_data[0] = 0x40;
+            p_rsp_data[1] = 0x02;
+            p_rsp_data[2] = 0x02;
+            p_rsp_data[3] = 0x00;
+            p_rsp_data[4] = 0x00;
+
+            phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5);
+
+            status = NFCSTATUS_FAILED;
+            NXPLOG_NCIHAL_D("Going through DTA workaround - Block set config command END");
+
+        }
+        else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x08 && p_cmd_data[2] == 0x04
+                 && p_cmd_data[3] == 0xFF && p_cmd_data[4] == 0xFF)
+        {
+            NXPLOG_NCIHAL_D(">>>>DTA Change Felica system code");
+            *rsp_len = 4;
+            p_rsp_data[0] = 0x41;
+            p_rsp_data[1] = 0x08;
+            p_rsp_data[2] = 0x01;
+            p_rsp_data[3] = 0x00;
+            status = NFCSTATUS_FAILED;
+
+            phNxpNciHal_print_packet("DTARECV", p_rsp_data, 4);
+        }
+        else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
+             p_cmd_data[2] == 0x10 && p_cmd_data[3] == 0x05 &&
+             p_cmd_data[10] == 0x32 && p_cmd_data[12] == 0x00)
+        {
+            NXPLOG_NCIHAL_D(">>>>DTA Update LA_SEL_INFO param");
+
+            p_cmd_data[12] = 0x40;
+            p_cmd_data[18] = 0x02;
+        status = NFCSTATUS_SUCCESS;
+        }
+       else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
+                p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04 &&
+                p_cmd_data[10] == 0x32 && p_cmd_data[12] == 0x00)
+        {
+            NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config");
+            *rsp_len = 5;
+            p_rsp_data[0] = 0x40;
+            p_rsp_data[1] = 0x02;
+            p_rsp_data[2] = 0x02;
+            p_rsp_data[3] = 0x00;
+            p_rsp_data[4] = 0x00;
+            status = NFCSTATUS_FAILED;
+            phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5);
+        }
+       else if(p_cmd_data[0] == 0x21 &&
+            p_cmd_data[1] == 0x03 )
+       {
+           NXPLOG_NCIHAL_D(">>>>DTA Add NFC-F listen tech params");
+           p_cmd_data[2] += 6;
+           p_cmd_data[3] += 3;
+           p_cmd_data[*cmd_len] = 0x80;
+           p_cmd_data[*cmd_len + 1] = 0x01;
+           p_cmd_data[*cmd_len + 2] = 0x82;
+           p_cmd_data[*cmd_len + 3] = 0x01;
+           p_cmd_data[*cmd_len + 4] = 0x85;
+           p_cmd_data[*cmd_len + 5] = 0x01;
+
+           *cmd_len += 6;
+           status = NFCSTATUS_SUCCESS;
+        }
+        else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
+                 p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04 &&
+                 p_cmd_data[10] == 0x32 && p_cmd_data[12] == 0x20 &&
+                 nxpdta_ctrl.dta_pattern_no == 0x1000)
+        {
+            NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config for analog testing");
+            *rsp_len = 5;
+            p_rsp_data[0] = 0x40;
+            p_rsp_data[1] = 0x02;
+            p_rsp_data[2] = 0x02;
+            p_rsp_data[3] = 0x00;
+            p_rsp_data[4] = 0x00;
+            status = NFCSTATUS_FAILED;
+            phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5);
+        }
+        else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
+                 p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04 &&
+                 p_cmd_data[4] == 0x32 && p_cmd_data[5] == 0x01 &&
+                 p_cmd_data[6] == 0x00)
+        {
+            NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config");
+            *rsp_len = 5;
+            p_rsp_data[0] = 0x40;
+            p_rsp_data[1] = 0x02;
+            p_rsp_data[2] = 0x02;
+            p_rsp_data[3] = 0x00;
+            p_rsp_data[4] = 0x00;
+            status = NFCSTATUS_FAILED;
+            phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5);
+        }
+        else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
+                 p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0x01 &&
+                 p_cmd_data[4] == 0x50 && p_cmd_data[5] == 0x01 &&
+                 p_cmd_data[6] == 0x00 && nxpdta_ctrl.dta_pattern_no == 0x1000)
+        {
+            NXPLOG_NCIHAL_D(">>>>DTA Blocking dirty set config for analog testing");
+            *rsp_len = 5;
+            p_rsp_data[0] = 0x40;
+            p_rsp_data[1] = 0x02;
+            p_rsp_data[2] = 0x02;
+            p_rsp_data[3] = 0x00;
+            p_rsp_data[4] = 0x00;
+            status = NFCSTATUS_FAILED;
+            phNxpNciHal_print_packet("DTARECV", p_rsp_data, 5);
+        }
+        else
+        {
+
+        }
+        if (nxpdta_ctrl.dta_t1t_flag == TRUE)
+        {
+
+           if (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x78 && p_cmd_data[4] ==0x00 &&  p_cmd_data[5] == 0x00)
+           {
+             /*if (nxpdta_ctrl.dta_pattern_no == 0)
+             {
+               NXPLOG_NCIHAL_D(">>>>DTA - T1T modification block RID command Custom Response (pattern 0)");
+               phNxpNciHal_print_packet("DTASEND", p_cmd_data, *cmd_len);
+               *rsp_len = 10;
+               p_rsp_data[0] = 0x00;
+               p_rsp_data[1] = 0x00;
+               p_rsp_data[2] = 0x07;
+               p_rsp_data[3] = 0x12;
+               p_rsp_data[4] = 0x49;
+               p_rsp_data[5] = 0x00;
+               p_rsp_data[6] = 0x00;
+               p_rsp_data[7] = 0x00;
+               p_rsp_data[8] = 0x00;
+               p_rsp_data[9] = 0x00;
+
+               status = NFCSTATUS_FAILED;
+
+               phNxpNciHal_print_packet("DTARECV", p_rsp_data, *rsp_len);
+             }
+             else
+             {*/
+               NXPLOG_NCIHAL_D("Change RID command's UID echo bytes to 0");
+
+               nxpdta_ctrl.dta_t1t_flag = FALSE;
+               p_cmd_data[6] = 0x00;
+               p_cmd_data[7] = 0x00;
+               p_cmd_data[8] = 0x00;
+               p_cmd_data[9] = 0x00;
+               status = NFCSTATUS_SUCCESS;
+             /*}*/
+          }
+      }
+    }
+    return status;
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_dta.h b/halimpl/pn54x/hal/phNxpNciHal_dta.h
new file mode 100644
index 0000000..7a649a1
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_dta.h
@@ -0,0 +1,36 @@
+ /*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_DTA_H_
+#define _PHNXPNCIHAL_DTA_H_
+
+#include <phNxpNciHal_utils.h>
+/* DTA Control structure */
+typedef struct phNxpDta_Control
+{
+    uint8_t dta_ctrl_flag;
+    uint16_t dta_pattern_no;
+    uint8_t dta_t1t_flag;
+}phNxpDta_Control_t;
+
+void phNxpEnable_DtaMode (uint16_t pattern_no);
+void phNxpDisable_DtaMode (void);
+NFCSTATUS phNxpDta_IsEnable(void);
+void phNxpDta_T1TEnable(void);
+NFCSTATUS phNxpNHal_DtaUpdate(uint16_t *cmd_len, uint8_t *p_cmd_data,
+        uint16_t *rsp_len, uint8_t *p_rsp_data);
+
+#endif /* _PHNXPNICHAL_DTA_H_ */
diff --git a/halimpl/pn54x/hal/phNxpNciHal_ext.c b/halimpl/pn54x/hal/phNxpNciHal_ext.c
new file mode 100644
index 0000000..d8f5bf6
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.c
@@ -0,0 +1,871 @@
+/*
+ * Copyright (C) 2012-2014 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 <phNxpNciHal_ext.h>
+#include <phNxpNciHal.h>
+#include <phTmlNfc.h>
+#include <phDal4Nfc_messageQueueLib.h>
+#include <phNxpNciHal_NfcDepSWPrio.h>
+#include <phNxpNciHal_Kovio.h>
+#include <phNxpLog.h>
+#include <phNxpConfig.h>
+
+#define HAL_EXTNS_WRITE_RSP_TIMEOUT   (1000)                /* Timeout value to wait for response from PN548AD */
+
+#undef P2P_PRIO_LOGIC_HAL_IMP
+
+/******************* Global variables *****************************************/
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+extern phNxpNciProfile_Control_t nxpprofile_ctrl;
+
+extern int kovio_detected;
+extern int disable_kovio;
+extern int send_to_upper_kovio;
+extern uint32_t cleanup_timer;
+static uint8_t icode_detected = 0x00;
+uint8_t icode_send_eof = 0x00;
+static uint8_t ee_disc_done = 0x00;
+uint8_t EnableP2P_PrioLogic = FALSE;
+static uint32_t RfDiscID = 1;
+static uint32_t RfProtocolType = 4;
+/* NFCEE Set mode */
+static uint8_t setEEModeDone = 0x00;
+static uint8_t cmd_nfcee_setmode_enable[] = { 0x22, 0x01, 0x02, 0x01, 0x01 };
+
+/* External global variable to get FW version from NCI response*/
+extern uint32_t wFwVerRsp;
+/* External global variable to get FW version from FW file*/
+extern uint16_t wFwVer;
+
+/* local buffer to store CORE_INIT response */
+static uint32_t bCoreInitRsp[40];
+static uint32_t iCoreInitRspLen;
+
+extern uint32_t timeoutTimerId;
+
+extern NFCSTATUS read_retry();
+/************** HAL extension functions ***************************************/
+static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void *pContext);
+
+/*Proprietary cmd sent to HAL to send reader mode flag
+ * Last byte of 4 byte proprietary cmd data contains ReaderMode flag
+ * If this flag is enabled, NFC-DEP protocol is modified to T3T protocol
+ * if FrameRF interface is selected. This needs to be done as the FW
+ * always sends Ntf for FrameRF with NFC-DEP even though FrameRF with T3T is
+ * previously selected with DISCOVER_SELECT_CMD
+ */
+#define PROPRIETARY_CMD_FELICA_READER_MODE 0xFE
+static uint8_t gFelicaReaderMode;
+
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_ext_init
+**
+** Description      initialize extension function
+**
+*******************************************************************************/
+void phNxpNciHal_ext_init (void)
+{
+    icode_detected = 0x00;
+    icode_send_eof = 0x00;
+    setEEModeDone = 0x00;
+    kovio_detected = 0x00;
+    disable_kovio = 0x00;
+    send_to_upper_kovio = 0x01;
+    EnableP2P_PrioLogic = FALSE;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_process_ext_rsp
+**
+** Description      Process extension function response
+**
+** Returns          NFCSTATUS_SUCCESS if success
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_process_ext_rsp (uint8_t *p_ntf, uint16_t *p_len)
+{
+
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint16_t rf_technology_length_param = 0;
+
+    if (p_ntf[0] == 0x61 &&
+        p_ntf[1] == 0x05 &&
+        p_ntf[4] == 0x03 &&
+        p_ntf[5] == 0x05 &&
+        nxpprofile_ctrl.profile_type == EMV_CO_PROFILE)
+    {
+        p_ntf[4] = 0xFF;
+        p_ntf[5] = 0xFF;
+        p_ntf[6] = 0xFF;
+        NXPLOG_NCIHAL_D("Nfc-Dep Detect in EmvCo profile - Restart polling");
+    }
+
+    if (p_ntf[0] == 0x61 &&
+        p_ntf[1] == 0x05 &&
+        p_ntf[4] == 0x01 &&
+        p_ntf[5] == 0x05 &&
+        p_ntf[6] == 0x02 &&
+        gFelicaReaderMode)
+    {
+     /*If FelicaReaderMode is enabled,Change Protocol to T3T from NFC-DEP
+          * when FrameRF interface is selected*/
+        p_ntf[5] = 0x03;
+        NXPLOG_NCIHAL_D("FelicaReaderMode:Activity 1.1");
+    }
+
+#ifdef P2P_PRIO_LOGIC_HAL_IMP
+    if(p_ntf[0] == 0x61 &&
+       p_ntf[1] == 0x05 &&
+       p_ntf[4] == 0x02 &&
+       p_ntf[5] == 0x04 &&
+       nxpprofile_ctrl.profile_type == NFC_FORUM_PROFILE)
+    {
+        EnableP2P_PrioLogic = TRUE;
+    }
+
+    NXPLOG_NCIHAL_D("Is EnableP2P_PrioLogic: 0x0%X",  EnableP2P_PrioLogic);
+    if(phNxpDta_IsEnable() == FALSE)
+    {
+        if ((icode_detected != 1)&&(kovio_detected != 1) && (EnableP2P_PrioLogic == TRUE))
+        {
+            if (phNxpNciHal_NfcDep_comapre_ntf(p_ntf, *p_len) == NFCSTATUS_FAILED)
+            {
+                status = phNxpNciHal_NfcDep_rsp_ext(p_ntf,p_len);
+                if(status != NFCSTATUS_INVALID_PARAMETER)
+                {
+                    return status;
+                }
+            }
+        }
+    }
+#endif
+
+    status = NFCSTATUS_SUCCESS;
+    status = phNxpNciHal_kovio_rsp_ext(p_ntf,p_len);
+
+    if (p_ntf[0] == 0x61 &&
+            p_ntf[1] == 0x05)
+    {
+        switch (p_ntf[4])
+        {
+        case 0x00:
+            NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFCEE Direct RF");
+            break;
+        case 0x01:
+            NXPLOG_NCIHAL_D("NxpNci: RF Interface = Frame RF");
+            break;
+        case 0x02:
+            NXPLOG_NCIHAL_D("NxpNci: RF Interface = ISO-DEP");
+            break;
+        case 0x03:
+            NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFC-DEP");
+            break;
+        case 0x80:
+            NXPLOG_NCIHAL_D("NxpNci: RF Interface = MIFARE");
+            break;
+        default:
+            NXPLOG_NCIHAL_D("NxpNci: RF Interface = Unknown");
+            break;
+        }
+
+        switch (p_ntf[5])
+        {
+        case 0x01:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = T1T");
+            phNxpDta_T1TEnable();
+            break;
+        case 0x02:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = T2T");
+            break;
+        case 0x03:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = T3T");
+            break;
+        case 0x04:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = ISO-DEP");
+            break;
+        case 0x05:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = NFC-DEP");
+            break;
+        case 0x06:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = 15693");
+            break;
+        case 0x80:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = MIFARE");
+            break;
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+        case 0x81:
+#else
+        case 0x8A:
+#endif
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = Kovio");
+            break;
+        default:
+            NXPLOG_NCIHAL_D("NxpNci: Protocol = Unknown");
+            break;
+        }
+
+        switch (p_ntf[6])
+        {
+        case 0x00:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Poll");
+            break;
+        case 0x01:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Poll");
+            break;
+        case 0x02:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Poll");
+            break;
+        case 0x03:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Poll");
+            break;
+        case 0x05:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Poll");
+            break;
+        case 0x06:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Poll");
+            break;
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+        case 0x70:
+#else
+        case 0x77:
+#endif
+            NXPLOG_NCIHAL_D("NxpNci: Mode = Kovio");
+            break;
+        case 0x80:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Listen");
+            break;
+        case 0x81:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Listen");
+            break;
+        case 0x82:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Listen");
+            break;
+        case 0x83:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Listen");
+            break;
+        case 0x85:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Listen");
+            break;
+        case 0x86:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Listen");
+            break;
+        default:
+            NXPLOG_NCIHAL_D("NxpNci: Mode = Unknown");
+            break;
+        }
+    }
+
+    if (p_ntf[0] == 0x61 &&
+            p_ntf[1] == 0x05 &&
+            p_ntf[2] == 0x15 &&
+            p_ntf[4] == 0x01 &&
+            p_ntf[5] == 0x06 &&
+            p_ntf[6] == 0x06)
+    {
+        NXPLOG_NCIHAL_D ("> Going through workaround - notification of ISO 15693");
+        icode_detected = 0x01;
+        p_ntf[21] = 0x01;
+        p_ntf[22] = 0x01;
+    }
+    else if (icode_detected == 1 &&
+            icode_send_eof == 2)
+    {
+        icode_send_eof = 3;
+        status = NFCSTATUS_FAILED;
+        return status;
+    }
+    else if (p_ntf[0] == 0x00 &&
+                p_ntf[1] == 0x00 &&
+                icode_detected == 1)
+    {
+        if (icode_send_eof == 3)
+        {
+            icode_send_eof = 0;
+        }
+        if (p_ntf[p_ntf[2]+ 2] == 0x00)
+        {
+            NXPLOG_NCIHAL_D ("> Going through workaround - data of ISO 15693");
+            p_ntf[2]--;
+            (*p_len)--;
+        }
+    }
+    else if (p_ntf[2] == 0x02 &&
+            p_ntf[1] == 0x00 && icode_detected == 1)
+    {
+        NXPLOG_NCIHAL_D ("> ICODE EOF response do not send to upper layer");
+    }
+    else if(p_ntf[0] == 0x61 &&
+            p_ntf[1] == 0x06 && icode_detected == 1)
+    {
+        NXPLOG_NCIHAL_D ("> Polling Loop Re-Started");
+        icode_detected = 0;
+        icode_send_eof = 0;
+    }
+    else if(*p_len == 4 &&
+                p_ntf[0] == 0x40 &&
+                p_ntf[1] == 0x02 &&
+                p_ntf[2] == 0x01 &&
+                p_ntf[3] == 0x06 )
+    {
+        NXPLOG_NCIHAL_D ("> Deinit workaround for LLCP set_config 0x%x 0x%x 0x%x", p_ntf[21], p_ntf[22], p_ntf[23]);
+        p_ntf[0] = 0x40;
+        p_ntf[1] = 0x02;
+        p_ntf[2] = 0x02;
+        p_ntf[3] = 0x00;
+        p_ntf[4] = 0x00;
+        *p_len = 5;
+    }
+    else if ((p_ntf[0] == 0x40) && (p_ntf[1] == 0x01))
+    {
+        int len = p_ntf[2] + 2; /*include 2 byte header*/
+        wFwVerRsp= (((uint32_t)p_ntf[len - 2])<< 16U)|(((uint32_t)p_ntf[len - 1])<< 8U)|p_ntf[len];
+        if(wFwVerRsp == 0)
+            status = NFCSTATUS_FAILED;
+        iCoreInitRspLen = *p_len;
+        memcpy(bCoreInitRsp, p_ntf, *p_len);
+        NXPLOG_NCIHAL_D ("NxpNci> FW Version: %x.%x.%x", p_ntf[len-2], p_ntf[len-1], p_ntf[len]);
+    }
+    //4200 02 00 01
+    else if(p_ntf[0] == 0x42 && p_ntf[1] == 0x00 && ee_disc_done == 0x01)
+    {
+        NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP");
+        if(p_ntf[4] == 0x01)
+        {
+            p_ntf[4] = 0x00;
+
+            ee_disc_done = 0x00;
+        }
+        NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP - END");
+
+    }
+    else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x03 /*&& cleanup_timer!=0*/)
+    {
+        if(cleanup_timer!=0)
+        {
+            /* if RF Notification Type of RF_DISCOVER_NTF is Last Notification */
+            if(0== (*(p_ntf + 2 + (*(p_ntf+2)))))
+            {
+                phNxpNciHal_select_RF_Discovery(RfDiscID,RfProtocolType);
+                status = NFCSTATUS_FAILED;
+                return status;
+            }
+            else
+            {
+                RfDiscID=p_ntf[3];
+                RfProtocolType=p_ntf[4];
+            }
+            status = NFCSTATUS_FAILED;
+            return status;
+
+        }
+
+    }
+    else if(p_ntf[0] == 0x41 && p_ntf[1] == 0x04 && cleanup_timer!=0)
+    {
+        status = NFCSTATUS_FAILED;
+        return status;
+    }
+    else if(p_ntf[0] == 0x60 && p_ntf[1] == 0x00)
+    {
+        NXPLOG_NCIHAL_E("CORE_RESET_NTF received!");
+        phNxpNciHal_emergency_recovery();
+    }
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+    else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05
+            && p_ntf[4] == 0x02 && p_ntf[5] == 0x80
+            && p_ntf[6] == 0x00 )
+    {
+        NXPLOG_NCIHAL_D("Going through workaround - iso-dep  interface  mifare protocol with sak value not equal to 0x20");
+        rf_technology_length_param = p_ntf[9];
+        if((p_ntf[ 9 + rf_technology_length_param] & 0x20) != 0x20)
+        {
+            p_ntf[4] = 0x80;
+        }
+    }
+#endif
+    /*
+    else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 && p_ntf[5] == 0x00 && p_ntf[6] == 0x01)
+    {
+        NXPLOG_NCIHAL_D("Picopass type 3-B with undefined protocol is not supported, disabling");
+        p_ntf[4] = 0xFF;
+        p_ntf[5] = 0xFF;
+        p_ntf[6] = 0xFF;
+    }*/
+
+    return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_process_ext_cmd_rsp
+ *
+ * Description      This function process the extension command response. It
+ *                  also checks the received response to expected response.
+ *
+ * Returns          returns NFCSTATUS_SUCCESS if response is as expected else
+ *                  returns failure.
+ *
+ ******************************************************************************/
+static NFCSTATUS phNxpNciHal_process_ext_cmd_rsp(uint16_t cmd_len, uint8_t *p_cmd)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    uint16_t data_written = 0;
+
+    /* Create the local semaphore */
+    if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL)
+            != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("Create ext_cb_data failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS;
+
+    /* Send ext command */
+    data_written = phNxpNciHal_write_unlocked(cmd_len, p_cmd);
+    if (data_written != cmd_len)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_write failed for hal ext");
+        goto clean_and_return;
+    }
+
+    /* Start timer */
+    status = phOsalNfc_Timer_Start(timeoutTimerId,
+            HAL_EXTNS_WRITE_RSP_TIMEOUT,
+            &hal_extns_write_rsp_timeout_cb,
+            NULL);
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_NCIHAL_D("Response timer started");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Response timer not started!!!");
+        status  = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* Wait for rsp */
+    NXPLOG_NCIHAL_D("Waiting after ext cmd sent");
+    if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data))
+    {
+        NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
+        goto clean_and_return;
+    }
+
+    /* Stop Timer */
+    status = phOsalNfc_Timer_Stop(timeoutTimerId);
+
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_NCIHAL_D("Response timer stopped");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
+        status  = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if(nxpncihal_ctrl.ext_cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("Callback Status is failed!! Timer Expired!! Couldn't read it! 0x%x", nxpncihal_ctrl.ext_cb_data.status);
+        status  = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    NXPLOG_NCIHAL_D("Checking response");
+    status = NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
+
+    return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_write_ext
+ *
+ * Description      This function inform the status of phNxpNciHal_open
+ *                  function to libnfc-nci.
+ *
+ * Returns          It return NFCSTATUS_SUCCESS then continue with send else
+ *                  sends NFCSTATUS_FAILED direct response is prepared and
+ *                  do not send anything to NFCC.
+ *
+ ******************************************************************************/
+
+NFCSTATUS phNxpNciHal_write_ext(uint16_t *cmd_len, uint8_t *p_cmd_data,
+        uint16_t *rsp_len, uint8_t *p_rsp_data)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    unsigned long retval = 0;
+    int isfound =  GetNxpNumValue(NAME_MIFARE_READER_ENABLE, &retval, sizeof(unsigned long));
+
+    phNxpNciHal_NfcDep_cmd_ext(p_cmd_data, cmd_len);
+
+    if(phNxpDta_IsEnable() == TRUE)
+    {
+        status = phNxpNHal_DtaUpdate(cmd_len, p_cmd_data,rsp_len, p_rsp_data);
+    }
+
+    if (p_cmd_data[0] == PROPRIETARY_CMD_FELICA_READER_MODE &&
+        p_cmd_data[1] == PROPRIETARY_CMD_FELICA_READER_MODE &&
+        p_cmd_data[2] == PROPRIETARY_CMD_FELICA_READER_MODE)
+    {
+        NXPLOG_NCIHAL_D ("Received proprietary command to set Felica Reader mode:%d",p_cmd_data[3]);
+        gFelicaReaderMode = p_cmd_data[3];
+        /* frame the dummy response */
+        *rsp_len = 4;
+        p_rsp_data[0] = 0x00;
+        p_rsp_data[1] = 0x00;
+        p_rsp_data[2] = 0x00;
+        p_rsp_data[3] = 0x00;
+        status = NFCSTATUS_FAILED;
+    }
+    else if (p_cmd_data[0] == 0x20 &&
+            p_cmd_data[1] == 0x02 &&
+            p_cmd_data[2] == 0x05 &&
+            p_cmd_data[3] == 0x01 &&
+            p_cmd_data[4] == 0xA0 &&
+            p_cmd_data[5] == 0x44 &&
+            p_cmd_data[6] == 0x01 &&
+            p_cmd_data[7] == 0x01)
+    {
+        nxpprofile_ctrl.profile_type = EMV_CO_PROFILE;
+        NXPLOG_NCIHAL_D ("EMV_CO_PROFILE mode - Enabled");
+        status = NFCSTATUS_SUCCESS;
+    }
+    else if (p_cmd_data[0] == 0x20 &&
+            p_cmd_data[1] == 0x02 &&
+            p_cmd_data[2] == 0x05 &&
+            p_cmd_data[3] == 0x01 &&
+            p_cmd_data[4] == 0xA0 &&
+            p_cmd_data[5] == 0x44 &&
+            p_cmd_data[6] == 0x01 &&
+            p_cmd_data[7] == 0x00)
+    {
+        NXPLOG_NCIHAL_D ("NFC_FORUM_PROFILE mode - Enabled");
+        nxpprofile_ctrl.profile_type = NFC_FORUM_PROFILE;
+        status = NFCSTATUS_SUCCESS;
+    }
+
+    if (nxpprofile_ctrl.profile_type == EMV_CO_PROFILE)
+    {
+        if (p_cmd_data[0] == 0x21 &&
+                p_cmd_data[1] == 0x06 &&
+                p_cmd_data[2] == 0x01 &&
+                p_cmd_data[3] == 0x03)
+        {
+#if 0
+            //Needs clarification whether to keep it or not
+            NXPLOG_NCIHAL_D ("EmvCo Poll mode - RF Deactivate discard");
+            phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+            *rsp_len = 4;
+            p_rsp_data[0] = 0x41;
+            p_rsp_data[1] = 0x06;
+            p_rsp_data[2] = 0x01;
+            p_rsp_data[3] = 0x00;
+            phNxpNciHal_print_packet("RECV", p_rsp_data, 4);
+            status = NFCSTATUS_FAILED;
+#endif
+        }
+        else if(p_cmd_data[0] == 0x21 &&
+                p_cmd_data[1] == 0x03 )
+        {
+            NXPLOG_NCIHAL_D ("EmvCo Poll mode - Discover map only for A and B");
+            p_cmd_data[2] = 0x05;
+            p_cmd_data[3] = 0x02;
+            p_cmd_data[4] = 0x00;
+            p_cmd_data[5] = 0x01;
+            p_cmd_data[6] = 0x01;
+            p_cmd_data[7] = 0x01;
+            *cmd_len = 8;
+        }
+    }
+#if(NFC_NXP_CHIP_TYPE == PN547C2)
+    if (retval == 0x01 &&
+        p_cmd_data[0] == 0x21 &&
+        p_cmd_data[1] == 0x00)
+    {
+        NXPLOG_NCIHAL_D ("Going through extns - Adding Mifare in RF Discovery");
+        p_cmd_data[2] += 3;
+        p_cmd_data[3] += 1;
+        p_cmd_data[*cmd_len] = 0x80;
+        p_cmd_data[*cmd_len + 1] = 0x01;
+        p_cmd_data[*cmd_len + 2] = 0x80;
+        *cmd_len += 3;
+        status = NFCSTATUS_SUCCESS;
+        NXPLOG_NCIHAL_D ("Going through extns - Adding Mifare in RF Discovery - END");
+    }
+    else
+#endif
+    if (p_cmd_data[3] == 0x81 &&
+            p_cmd_data[4] == 0x01 &&
+            p_cmd_data[5] == 0x03)
+    {
+        NXPLOG_NCIHAL_D("> Going through workaround - set host list");
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+        *cmd_len = 8;
+
+        p_cmd_data[2] = 0x05;
+        p_cmd_data[6] = 0x02;
+        p_cmd_data[7] = 0xC0;
+#else
+        *cmd_len = 7;
+
+        p_cmd_data[2] = 0x04;
+        p_cmd_data[6] = 0xC0;
+#endif
+
+        NXPLOG_NCIHAL_D("> Going through workaround - set host list - END");
+        status = NFCSTATUS_SUCCESS;
+    }
+    else if(icode_detected)
+    {
+        if ((p_cmd_data[3] & 0x40) == 0x40 &&
+            (p_cmd_data[4] == 0x21 ||
+             p_cmd_data[4] == 0x22 ||
+             p_cmd_data[4] == 0x24 ||
+             p_cmd_data[4] == 0x27 ||
+             p_cmd_data[4] == 0x28 ||
+             p_cmd_data[4] == 0x29 ||
+             p_cmd_data[4] == 0x2a))
+        {
+            NXPLOG_NCIHAL_D ("> Send EOF set");
+            icode_send_eof = 1;
+        }
+
+        if(p_cmd_data[3]  == 0x20 || p_cmd_data[3]  == 0x24 ||
+           p_cmd_data[3]  == 0x60)
+        {
+            NXPLOG_NCIHAL_D ("> NFC ISO_15693 Proprietary CMD ");
+            p_cmd_data[3] += 0x02;
+        }
+    }
+    else if(p_cmd_data[0] == 0x21 &&
+            p_cmd_data[1] == 0x03 )
+    {
+        NXPLOG_NCIHAL_D ("> Polling Loop Started");
+        icode_detected = 0;
+        icode_send_eof = 0;
+    }
+    //22000100
+    else if (p_cmd_data[0] == 0x22 &&
+            p_cmd_data[1] == 0x00 &&
+            p_cmd_data[2] == 0x01 &&
+            p_cmd_data[3] == 0x00
+            )
+    {
+        //ee_disc_done = 0x01;//Reader Over SWP event getting
+        *rsp_len = 0x05;
+        p_rsp_data[0] = 0x42;
+        p_rsp_data[1] = 0x00;
+        p_rsp_data[2] = 0x02;
+        p_rsp_data[3] = 0x00;
+        p_rsp_data[4] = 0x00;
+        phNxpNciHal_print_packet("RECV", p_rsp_data,5);
+        status = NFCSTATUS_FAILED;
+    }
+    //2002 0904 3000 3100 3200 5000
+    else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
+            ( (p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) /*||
+              (p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
+            )
+    )
+    {
+        *cmd_len += 0x01;
+        p_cmd_data[2] += 0x01;
+        p_cmd_data[9] = 0x01;
+        p_cmd_data[10] = 0x40;
+        p_cmd_data[11] = 0x50;
+        p_cmd_data[12] = 0x00;
+
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
+//        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
+    }
+//    20020703300031003200
+//    2002 0301 3200
+    else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
+            (
+              (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x03) ||
+              (p_cmd_data[2] == 0x03 && p_cmd_data[3] == 0x01 && p_cmd_data[4] == 0x32)
+            )
+    )
+    {
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
+        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+        *rsp_len = 5;
+        p_rsp_data[0] = 0x40;
+        p_rsp_data[1] = 0x02;
+        p_rsp_data[2] = 0x02;
+        p_rsp_data[3] = 0x00;
+        p_rsp_data[4] = 0x00;
+
+        phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
+        status = NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
+    }
+
+    //2002 0D04 300104 310100 320100 500100
+    //2002 0401 320100
+    else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
+            (
+              /*(p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
+                (p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0x01 && p_cmd_data[4] == 0x32 && p_cmd_data[5] == 0x00)
+            )
+    )
+    {
+//        p_cmd_data[12] = 0x40;
+
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
+        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+        p_cmd_data[6] = 0x60;
+
+        phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
+//        status = NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
+    }
+
+#if 0
+    else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
+                 ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) ||
+                     (p_cmd_data[2] == 0x0B && p_cmd_data[3] == 0x05) ||
+                     (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x02) ||
+                     (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x03) ||
+                     (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x04) ||
+                     (p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x02))
+             )
+    {
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
+        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+        *rsp_len = 5;
+        p_rsp_data[0] = 0x40;
+        p_rsp_data[1] = 0x02;
+        p_rsp_data[2] = 0x02;
+        p_rsp_data[3] = 0x00;
+        p_rsp_data[4] = 0x00;
+
+        phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
+        status = NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
+    }
+
+    else if((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
+           ((p_cmd_data[3] == 0x00) ||
+           ((*cmd_len >= 0x06) && (p_cmd_data[5] == 0x00)))) /*If the length of the first param id is zero don't allow*/
+    {
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
+        phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
+        *rsp_len = 5;
+        p_rsp_data[0] = 0x40;
+        p_rsp_data[1] = 0x02;
+        p_rsp_data[2] = 0x02;
+        p_rsp_data[3] = 0x00;
+        p_rsp_data[4] = 0x00;
+
+        phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
+        status = NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
+    }
+#endif
+    else if ((wFwVerRsp & 0x0000FFFF) == wFwVer)
+    {
+        /* skip CORE_RESET and CORE_INIT from Brcm */
+        if (p_cmd_data[0] == 0x20 &&
+            p_cmd_data[1] == 0x00 &&
+            p_cmd_data[2] == 0x01 &&
+            p_cmd_data[3] == 0x01
+            )
+        {
+//            *rsp_len = 6;
+//
+//            NXPLOG_NCIHAL_D("> Going - core reset optimization");
+//
+//            p_rsp_data[0] = 0x40;
+//            p_rsp_data[1] = 0x00;
+//            p_rsp_data[2] = 0x03;
+//            p_rsp_data[3] = 0x00;
+//            p_rsp_data[4] = 0x10;
+//            p_rsp_data[5] = 0x01;
+//
+//            status = NFCSTATUS_FAILED;
+//            NXPLOG_NCIHAL_D("> Going - core reset optimization - END");
+        }
+        /* CORE_INIT */
+        else if (
+            p_cmd_data[0] == 0x20 &&
+            p_cmd_data[1] == 0x01 &&
+            p_cmd_data[2] == 0x00
+            )
+        {
+//            NXPLOG_NCIHAL_D("> Going - core init optimization");
+//            *rsp_len = iCoreInitRspLen;
+//            memcpy(p_rsp_data, bCoreInitRsp, iCoreInitRspLen);
+//            status = NFCSTATUS_FAILED;
+//            NXPLOG_NCIHAL_D("> Going - core init optimization - END");
+        }
+    }
+    return status;
+}
+
+/******************************************************************************
+ * Function         phNxpNciHal_send_ext_cmd
+ *
+ * Description      This function send the extension command to NFCC. No
+ *                  response is checked by this function but it waits for
+ *                  the response to come.
+ *
+ * Returns          Returns NFCSTATUS_SUCCESS if sending cmd is successful and
+ *                  response is received.
+ *
+ ******************************************************************************/
+NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    HAL_ENABLE_EXT();
+    nxpncihal_ctrl.cmd_len = cmd_len;
+    memcpy(nxpncihal_ctrl.p_cmd_data, p_cmd, cmd_len);
+    status = phNxpNciHal_process_ext_cmd_rsp(nxpncihal_ctrl.cmd_len, nxpncihal_ctrl.p_cmd_data);
+    HAL_DISABLE_EXT();
+
+    return status;
+}
+
+/******************************************************************************
+ * Function         hal_extns_write_rsp_timeout_cb
+ *
+ * Description      Timer call back function
+ *
+ * Returns          None
+ *
+ ******************************************************************************/
+static void hal_extns_write_rsp_timeout_cb(uint32_t timerId, void *pContext)
+{
+    UNUSED(timerId);
+    UNUSED(pContext);
+    NXPLOG_NCIHAL_E("hal_extns_write_rsp_timeout_cb - write timeout!!!");
+    nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
+    usleep(1);
+    SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
+
+    return;
+}
diff --git a/halimpl/pn54x/hal/phNxpNciHal_ext.h b/halimpl/pn54x/hal/phNxpNciHal_ext.h
new file mode 100644
index 0000000..b2d7a17
--- /dev/null
+++ b/halimpl/pn54x/hal/phNxpNciHal_ext.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_EXT_H_
+#define _PHNXPNCIHAL_EXT_H_
+
+#include <phNxpNciHal.h>
+#include <string.h>
+#include <phNxpNciHal_dta.h>
+
+void phNxpNciHal_ext_init (void);
+NFCSTATUS phNxpNciHal_process_ext_rsp (uint8_t *p_ntf, uint16_t *p_len);
+NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t *p_cmd);
+NFCSTATUS phNxpNciHal_write_ext(uint16_t *cmd_len, uint8_t *p_cmd_data,
+        uint16_t *rsp_len, uint8_t *p_rsp_data);
+
+#endif /* _PHNXPNICHAL_EXT_H_ */
diff --git a/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
new file mode 100644
index 0000000..ba5f8f5
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_Adaptation.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_ADAPTATION_H_
+#define _PHNXPNCIHAL_ADAPTATION_H_
+
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+
+typedef struct
+{
+    struct nfc_nci_device nci_device;
+
+    /* Local definitions */
+} pn547_dev_t;
+
+/* NXP HAL functions */
+
+int phNxpNciHal_open(nfc_stack_callback_t *p_cback,
+        nfc_stack_data_callback_t *p_data_cback);
+int phNxpNciHal_write(uint16_t data_len, const uint8_t *p_data);
+int phNxpNciHal_core_initialized(uint8_t* p_core_init_rsp_params);
+int phNxpNciHal_pre_discover(void);
+int phNxpNciHal_close(void);
+int phNxpNciHal_control_granted(void);
+int phNxpNciHal_power_cycle(void);
+
+#endif /* _PHNXPNCIHAL_ADAPTATION_H_ */
diff --git a/halimpl/pn54x/inc/phNxpNciHal_Api.h b/halimpl/pn54x/inc/phNxpNciHal_Api.h
new file mode 100644
index 0000000..8497e05
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_Api.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_API_H_
+#define _PHNXPNCIHAL_API_H_
+
+#include <phNfcStatus.h>
+#include <phNxpNciHal.h>
+#include <phTmlNfc.h>
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_get_version
+ **
+ ** Description      Function to get the HW, FW and SW versions.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_get_version (uint32_t *hw_ver, uint32_t *fw_ver, uint32_t *sw_ver);
+
+#endif /* _PHNXPNCIHAL_API_H_ */
diff --git a/halimpl/pn54x/inc/phNxpNciHal_SelfTest.h b/halimpl/pn54x/inc/phNxpNciHal_SelfTest.h
new file mode 100644
index 0000000..711e505
--- /dev/null
+++ b/halimpl/pn54x/inc/phNxpNciHal_SelfTest.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2012-2014 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 _PHNXPNCIHAL_SELFTEST_H_
+#define _PHNXPNCIHAL_SELFTEST_H_
+
+#ifdef NXP_HW_SELF_TEST
+
+#include <phNfcStatus.h>
+#include <phNxpNciHal.h>
+#include <phTmlNfc.h>
+
+/* PRBS Generation type  */
+typedef enum
+{
+    NFC_FW_PRBS, /* FW software would generate the PRBS */
+    NFC_HW_PRBS /* Hardware would generate the PRBS */
+} phNxpNfc_PrbsType_t;
+
+/* Different HW PRBS types */
+typedef enum
+{
+    NFC_HW_PRBS9,
+    NFC_HW_PRBS15
+} phNxpNfc_PrbsHwType_t;
+/* RF Technology */
+typedef enum
+{
+    NFC_RF_TECHNOLOGY_A,
+    NFC_RF_TECHNOLOGY_B,
+    NFC_RF_TECHNOLOGY_F,
+} phNxpNfc_Tech_t;
+
+/* Bit rates */
+typedef enum
+{
+    NFC_BIT_RATE_106,
+    NFC_BIT_RATE_212,
+    NFC_BIT_RATE_424,
+    NFC_BIT_RATE_848,
+} phNxpNfc_Bitrate_t;
+
+typedef struct phAntenna_St_Resp
+{
+     /* Txdo Raw Value*/
+    uint16_t            wTxdoRawValue;
+    uint16_t            wTxdoMeasuredRangeMin;    /*Txdo Measured Range Max */
+    uint16_t            wTxdoMeasuredRangeMax;    /*Txdo Measured Range Min */
+    uint16_t            wTxdoMeasuredTolerance;    /*Txdo Measured Range Tolerance */
+     /* Agc Values */
+    uint16_t            wAgcValue;    /*Agc Min Value*/
+    uint16_t            wAgcValueTolerance;    /*Txdo Measured Range*/
+     /* Agc value with NFCLD */
+    uint16_t            wAgcValuewithfixedNFCLD;    /*Agc Value with Fixed NFCLD Max */
+    uint16_t            wAgcValuewithfixedNFCLDTolerance;    /*Agc Value with Fixed NFCLD Tolerance */
+     /* Agc Differential Values With Open/Short RM */
+    uint16_t            wAgcDifferentialWithOpen1;    /*Agc Differential With Open 1*/
+    uint16_t            wAgcDifferentialWithOpenTolerance1;    /*Agc Differential With Open Tolerance 1*/
+    uint16_t            wAgcDifferentialWithOpen2;    /*Agc Differential With Open 2*/
+    uint16_t            wAgcDifferentialWithOpenTolerance2;    /*Agc Differential With Open Tolerance 2*/
+}phAntenna_St_Resp_t;           /* Instance of Transaction structure */
+
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_TestMode_open
+ **
+ ** Description      It opens the physical connection with NFCC (pn547) and
+ **                  creates required client thread for operation.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_TestMode_open (void);
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_TestMode_close
+ **
+ ** Description      This function close the NFCC interface and free all
+ **                  resources.
+ **
+ ** Returns          None.
+ **
+ *******************************************************************************/
+
+void phNxpNciHal_TestMode_close (void);
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_SwpTest
+ **
+ ** Description      Test function to validate the SWP line. SWP line number is
+ **                  is sent as parameter to the API.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_SwpTest (uint8_t swp_line);
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_PrbsTestStart
+ **
+ ** Description      Test function start RF generation for RF technology and bit
+ **                  rate. RF technology and bit rate are sent as parameter to
+ **                  the API.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if RF generation successful,
+ **                  otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+        phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate);
+#else
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate);
+#endif
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_PrbsTestStop
+ **
+ ** Description      Test function stop RF generation for RF technology started
+ **                  by phNxpNciHal_PrbsTestStart.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if operation successful,
+ **                  otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_PrbsTestStop ();
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_AntennaSelfTest
+**
+** Description      Test function to validate the Antenna's discrete
+**                  components connection.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+
+NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t * phAntenna_St_Resp );
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_RfFieldTest
+**
+** Description      Test function performs RF filed test.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+
+NFCSTATUS phNxpNciHal_RfFieldTest (uint8_t on);
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_DownloadPinTest
+ **
+ ** Description      Test function to validate the FW download pin connection.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_DownloadPinTest (void);
+
+#endif /* _NXP_HW_SELF_TEST_H_ */
+#endif /* _PHNXPNCIHAL_SELFTEST_H_ */
diff --git a/halimpl/pn54x/libnfc-brcm.conf b/halimpl/pn54x/libnfc-brcm.conf
new file mode 100644
index 0000000..22dffb5
--- /dev/null
+++ b/halimpl/pn54x/libnfc-brcm.conf
@@ -0,0 +1,385 @@
+###################### Start of libnfc-brcm.conf #######################
+
+###############################################################################
+# Application options
+APPL_TRACE_LEVEL=0xFF
+PROTOCOL_TRACE_LEVEL=0xFFFFFFFF
+
+###############################################################################
+# performance measurement
+# Change this setting to control how often USERIAL log the performance (throughput)
+# data on read/write/poll
+# defailt is to log performance dara for every 100 read or write
+#REPORT_PERFORMANCE_MEASURE=100
+
+###############################################################################
+# File used for NFA storage
+NFA_STORAGE="/data/nfc"
+
+###############################################################################
+# Snooze Mode Settings
+#
+#  By default snooze mode is enabled.  Set SNOOZE_MODE_CFG byte[0] to 0
+#  to disable.
+#
+#  If SNOOZE_MODE_CFG is not provided, the default settings are used:
+#  They are as follows:
+#       8             Sleep Mode (0=Disabled 1=UART 8=SPI/I2C)
+#       0             Idle Threshold Host
+#       0             Idle Threshold HC
+#       0             NFC Wake active mode (0=ActiveLow 1=ActiveHigh)
+#       1             Host Wake active mode (0=ActiveLow 1=ActiveHigh)
+#
+#SNOOZE_MODE_CFG={08:00:00:00:01}
+
+###############################################################################
+# Insert a delay in milliseconds after NFC_WAKE and before write to NFCC
+#NFC_WAKE_DELAY=20
+
+###############################################################################
+# Various Delay settings (in ms) used in USERIAL
+#  POWER_ON_DELAY
+#    Delay after turning on chip, before writing to transport (default 300)
+#  PRE_POWER_OFF_DELAY
+#    Delay after deasserting NFC-Wake before turn off chip (default 0)
+#  POST_POWER_OFF_DELAY
+#    Delay after turning off chip, before USERIAL_close returns (default 0)
+#
+#POWER_ON_DELAY=300
+#PRE_POWER_OFF_DELAY=0
+#POST_POWER_OFF_DELAY=0
+
+###############################################################################
+# Maximum time (ms) to wait for RESET NTF after setting REG_PU to high
+# The default is 1000.
+#NFCC_ENABLE_TIMEOUT=0
+
+###############################################################################
+# LPTD mode configuration
+#  byte[0] is the length of the remaining bytes in this value
+#     if set to 0, LPTD params will NOT be sent to NFCC (i.e. disabled).
+#  byte[1] is the param id it should be set to B9.
+#  byte[2] is the length of the LPTD parameters
+#  byte[3] indicates if LPTD is enabled
+#     if set to 0, LPTD will be disabled (parameters will still be sent).
+#  byte[4-n] are the LPTD parameters.
+#  By default, LPTD is enabled and default settings are used.
+#  See nfc_hal_dm_cfg.c for defaults
+#LPTD_CFG={23:B9:21:01:02:FF:FF:04:A0:0F:40:00:80:02:02:10:00:00:00:31:0C:30:00:00:00:00:00:00:00:00:00:00:00:00:00:00}
+
+###############################################################################
+# Startup Configuration (100 bytes maximum)
+#
+# For the 0xCA parameter, byte[9] (marked by 'AA') is for UICC0, and byte[10] (marked by BB) is
+#    for UICC1.  The values are defined as:
+#   0 : UICCx only supports ISO_DEP in low power mode.
+#   2 : UICCx only supports Mifare in low power mode.
+#   3 : UICCx supports both ISO_DEP and Mifare in low power mode.
+#
+#                                                                          AA BB
+#NFA_DM_START_UP_CFG={1F:CB:01:01:A5:01:01:CA:14:00:00:00:00:06:E8:03:00:00:00:00:00:00:00:00:00:00:00:00:00:80:01:01}
+
+###############################################################################
+# Startup Vendor Specific Configuration (100 bytes maximum);
+#  byte[0] TLV total len = 0x5
+#  byte[1] NCI_MTS_CMD|NCI_GID_PROP = 0x2f
+#  byte[2] NCI_MSG_FRAME_LOG = 0x9
+#  byte[3] 2
+#  byte[4] 0=turn off RF frame logging; 1=turn on
+#  byte[5] 0=turn off SWP frame logging; 1=turn on
+#  NFA_DM_START_UP_VSC_CFG={05:2F:09:02:01:01}
+
+###############################################################################
+# Antenna Configuration - This data is used when setting 0xC8 config item
+# at startup (before discovery is started).  If not used, no value is sent.
+#
+# The settings for this value are documented here:
+# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/
+#   Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx
+# This document is maintained by Paul Forshaw.
+#
+# The values marked as ?? should be tweaked per antenna or customer/app:
+# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04}
+# array[0] = 0x20 is length of the payload from array[1] to the end
+# array[1] = 0xC8 is PREINIT_DSP_CFG
+#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04}
+
+###############################################################################
+# Configure crystal frequency when internal LPO can't detect the frequency.
+#XTAL_FREQUENCY=0
+###############################################################################
+# Configure the default Destination Gate used by HCI (the default is 4, which
+# is the ETSI loopback gate.
+NFA_HCI_DEFAULT_DEST_GATE=0xF0
+
+###############################################################################
+# Configure the single default SE to use.  The default is to use the first
+# SE that is detected by the stack.  This value might be used when the phone
+# supports multiple SE (e.g. 0xF3 and 0xF4) but you want to force it to use
+# one of them (e.g. 0xF4).
+#ACTIVE_SE=0xF3
+
+###############################################################################
+# Configure the default NfcA/IsoDep techology and protocol route. Can be
+# either a secure element (e.g. 0xF4) or the host (0x00)
+#DEFAULT_ISODEP_ROUTE=0x00
+
+###############################################################################
+# Configure the NFC Extras to open and use a static pipe.  If the value is
+# not set or set to 0, then the default is use a dynamic pipe based on a
+# destination gate (see NFA_HCI_DEFAULT_DEST_GATE).  Note there is a value
+# for each UICC (where F3="UICC0" and F4="UICC1")
+#NFA_HCI_STATIC_PIPE_ID_F3=0x70
+#NFA_HCI_STATIC_PIPE_ID_01=0x19
+NFA_HCI_STATIC_PIPE_ID_C0=0x19
+###############################################################################
+# When disconnecting from Oberthur secure element, perform a warm-reset of
+# the secure element to deselect the applet.
+# The default hex value of the command is 0x3.  If this variable is undefined,
+# then this feature is not used.
+#OBERTHUR_WARM_RESET_COMMAND=0x03
+
+###############################################################################
+# Force UICC to only listen to the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B | NFA_TECHNOLOGY_MASK_F
+UICC_LISTEN_TECH_MASK=0x07
+
+###############################################################################
+# Force HOST listen feature enable or disable.
+# 0: Disable
+# 1: Enable
+HOST_LISTEN_ENABLE=0x01
+
+###############################################################################
+# Enabling/Disabling Forward functionality
+# Disable           0x00
+# Enable            0x01
+NXP_FWD_FUNCTIONALITY_ENABLE=0x01
+
+###############################################################################
+# Allow UICC to be powered off if there is no traffic.
+# Timeout is in ms. If set to 0, then UICC will not be powered off.
+#UICC_IDLE_TIMEOUT=30000
+UICC_IDLE_TIMEOUT=0
+
+###############################################################################
+# AID for Empty Select command
+# If specified, this AID will be substituted when an Empty SELECT command is
+# detected.  The first byte is the length of the AID.  Maximum length is 16.
+AID_FOR_EMPTY_SELECT={08:A0:00:00:01:51:00:00:00}
+###############################################################################
+# Maximum Number of Credits to be allowed by the NFCC
+#   This value overrides what the NFCC specifices allowing the host to have
+#   the control to work-around transport limitations.  If this value does
+#   not exist or is set to 0, the NFCC will provide the number of credits.
+MAX_RF_DATA_CREDITS=1
+
+###############################################################################
+# This setting allows you to disable registering the T4t Virtual SE that causes
+# the NFCC to send PPSE requests to the DH.
+# The default setting is enabled (i.e. T4t Virtual SE is registered).
+#REGISTER_VIRTUAL_SE=1
+
+###############################################################################
+# When screen is turned off, specify the desired power state of the controller.
+# 0: power-off-sleep state; DEFAULT
+# 1: full-power state
+# 2: screen-off card-emulation (CE4/CE3/CE1 modes are used)
+SCREEN_OFF_POWER_STATE=1
+
+###############################################################################
+# Firmware patch file
+#  If the value is not set then patch download is disabled.
+#FW_PATCH="/vendor/firmware/bcm2079x_firmware.ncd"
+
+###############################################################################
+# Firmware pre-patch file (sent before the above patch file)
+#  If the value is not set then pre-patch is not used.
+#FW_PRE_PATCH="/vendor/firmware/bcm2079x_pre_firmware.ncd"
+
+###############################################################################
+# Firmware patch format
+#   1 = HCD
+#   2 = NCD (default)
+#NFA_CONFIG_FORMAT=2
+
+###############################################################################
+# SPD Debug mode
+#  If set to 1, any failure of downloading a patch will trigger a hard-stop
+#SPD_DEBUG=0
+
+###############################################################################
+# SPD Max Retry Count
+#  The number of attempts to download a patch before giving up (defualt is 3).
+#  Note, this resets after a power-cycle.
+#SPD_MAX_RETRY_COUNT=3
+
+###############################################################################
+# transport driver
+#
+# TRANSPORT_DRIVER=<driver>
+#
+#  where <driver> can be, for example:
+#    "/dev/ttyS"        (UART)
+#    "/dev/bcmi2cnfc"   (I2C)
+#    "hwtun"            (HW Tunnel)
+#    "/dev/bcmspinfc"   (SPI)
+#    "/dev/btusb0"      (BT USB)
+#TRANSPORT_DRIVER="/dev/bcm2079x-i2c"
+
+###############################################################################
+# power control driver
+# Specify a kernel driver that support ioctl commands to control NFC_EN and
+# NFC_WAKE gpio signals.
+#
+# POWER_CONTRL_DRIVER=<driver>
+#  where <driver> can be, for example:
+#    "/dev/nfcpower"
+#    "/dev/bcmi2cnfc"   (I2C)
+#    "/dev/bcmspinfc"   (SPI)
+#    i2c and spi driver may be used to control NFC_EN and NFC_WAKE signal
+#POWER_CONTROL_DRIVER="/dev/bcm2079x-i2c"
+
+###############################################################################
+# I2C transport driver options
+# Mako does not support 10-bit I2C addresses
+# Revert to 7-bit address
+#BCMI2CNFC_ADDRESS=0x77
+
+###############################################################################
+# I2C transport driver try to read multiple packets in read() if data is available
+# remove the comment below to enable this feature
+#READ_MULTIPLE_PACKETS=1
+
+###############################################################################
+# SPI transport driver options
+#SPI_NEGOTIATION={0A:F0:00:01:00:00:00:FF:FF:00:00}
+
+###############################################################################
+# UART transport driver options
+#
+# PORT=1,2,3,...
+# BAUD=115200, 19200, 9600, 4800,
+# DATABITS=8, 7, 6, 5
+# PARITY="even" | "odd" | "none"
+# STOPBITS="0" | "1" | "1.5" | "2"
+
+#UART_PORT=2
+#UART_BAUD=115200
+#UART_DATABITS=8
+#UART_PARITY="none"
+#UART_STOPBITS="1"
+
+###############################################################################
+# Insert a delay in microseconds per byte after a write to NFCC.
+# after writing a block of data to the NFCC, delay this an amopunt of time before
+# writing next block of data.  the delay is calculated as below
+#   NFC_WRITE_DELAY * (number of byte written) / 1000 milliseconds
+# e.g. after 259 bytes is written, delay (259 * 20 / 1000) 5 ms before next write
+#NFC_WRITE_DELAY=20
+
+###############################################################################
+# Maximum Number of Credits to be allowed by the NFCC
+#   This value overrides what the NFCC specifices allowing the host to have
+#   the control to work-around transport limitations.  If this value does
+#   not exist or is set to 0, the NFCC will provide the number of credits.
+MAX_RF_DATA_CREDITS=1
+
+###############################################################################
+# Default poll duration (in ms)
+#  The defualt is 500ms if not set (see nfc_target.h)
+#NFA_DM_DISC_DURATION_POLL=333
+###############################################################################
+# Antenna Configuration - This data is used when setting 0xC8 config item
+# at startup (before discovery is started).  If not used, no value is sent.
+#
+# The settings for this value are documented here:
+# http://wcgbu.broadcom.com/wpan/PM/Project%20Document%20Library/bcm20791B0/
+#   Design/Doc/PHY%20register%20settings/BCM20791-B2-1027-02_PHY_Recommended_Reg_Settings.xlsx
+# This document is maintained by Paul Forshaw.
+#
+# The values marked as ?? should be tweaked per antenna or customer/app:
+# {20:C8:1E:06:??:00:??:??:??:00:??:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:??:01:00:00:40:04}
+# array[0] = 0x20 is length of the payload from array[1] to the end
+# array[1] = 0xC8 is PREINIT_DSP_CFG
+#PREINIT_DSP_CFG={20:C8:1E:06:1F:00:0F:03:3C:00:04:24:00:1C:00:75:00:77:00:76:00:1C:00:03:00:0A:00:48:01:00:00:40:04}
+
+
+###############################################################################
+# Choose the presence-check algorithm for type-4 tag.  If not defined, the default value is 1.
+# 0  NFA_RW_PRES_CHK_DEFAULT; Let stack selects an algorithm
+# 1  NFA_RW_PRES_CHK_I_BLOCK; ISO-DEP protocol's empty I-block
+# 2  NFA_RW_PRES_CHK_RESET; Deactivate to Sleep, then re-activate
+# 3  NFA_RW_PRES_CHK_RB_CH0; Type-4 tag protocol's ReadBinary command on channel 0
+# 4  NFA_RW_PRES_CHK_RB_CH3; Type-4 tag protocol's ReadBinary command on channel 3
+#PRESENCE_CHECK_ALGORITHM=0
+
+###############################################################################
+# Force tag polling for the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B |
+#            NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_ISO15693 |
+#            NFA_TECHNOLOGY_MASK_B_PRIME | NFA_TECHNOLOGY_MASK_KOVIO |
+#            NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE.
+#
+# Notable bits:
+# NFA_TECHNOLOGY_MASK_A             0x01    /* NFC Technology A             */
+# NFA_TECHNOLOGY_MASK_B             0x02    /* NFC Technology B             */
+# NFA_TECHNOLOGY_MASK_F             0x04    /* NFC Technology F             */
+# NFA_TECHNOLOGY_MASK_ISO15693	    0x08    /* Proprietary Technology       */
+# NFA_TECHNOLOGY_MASK_KOVIO	        0x20    /* Proprietary Technology       */
+# NFA_TECHNOLOGY_MASK_A_ACTIVE      0x40    /* NFC Technology A active mode */
+# NFA_TECHNOLOGY_MASK_F_ACTIVE      0x80    /* NFC Technology F active mode */
+POLLING_TECH_MASK=0xEF
+
+###############################################################################
+# Force P2P to only listen for the following technology(s).
+# The bits are defined as tNFA_TECHNOLOGY_MASK in nfa_api.h.
+# Default is NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F |
+#            NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE
+#
+# Notable bits:
+# NFA_TECHNOLOGY_MASK_A	            0x01    /* NFC Technology A             */
+# NFA_TECHNOLOGY_MASK_F	            0x04    /* NFC Technology F             */
+# NFA_TECHNOLOGY_MASK_A_ACTIVE      0x40    /* NFC Technology A active mode */
+# NFA_TECHNOLOGY_MASK_F_ACTIVE      0x80    /* NFC Technology F active mode */
+P2P_LISTEN_TECH_MASK=0xC5
+
+PRESERVE_STORAGE=0x01
+
+###############################################################################
+# Override the stack default for NFA_EE_MAX_EE_SUPPORTED set in nfc_target.h.
+# The value is set to 3 by default as it assumes we will discover 0xF2,
+# 0xF3, and 0xF4. If a platform will exclude and SE, this value can be reduced
+# so that the stack will not wait any longer than necessary.
+
+# Maximum EE supported number
+# NXP PN547C2 0x02
+# NXP PN65T 0x03
+# NXP PN548C2 0x02
+# NXP PN66T 0x03
+NFA_MAX_EE_SUPPORTED=0x03
+
+###############################################################################
+# NCI Hal Module name
+NCI_HAL_MODULE="nfc_nci"
+
+##############################################################################
+# Deactivate notification wait time out in seconds used in ETSI Reader mode
+# 0 - Infinite wait
+NFA_DM_DISC_NTF_TIMEOUT=100
+
+###############################################################################
+# AID_MATCHING constants
+# AID_MATCHING_EXACT_ONLY 0x00
+# AID_MATCHING_EXACT_OR_PREFIX 0x01
+# AID_MATCHING_PREFIX_ONLY 0x02
+AID_MATCHING_MODE=0x01
+
+###############################################################################
+# Preferred Secure Element for Technology based routing
+# eSE               0x01
+# UICC              0x02
+
+NXP_PRFD_TECH_SE=0x01
diff --git a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
new file mode 100644
index 0000000..b160b11
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
@@ -0,0 +1,219 @@
+## 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/libpn547_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL       1
+#define CLK_SRC_PLL        2
+
+NXP_SYS_CLK_SRC_SEL=0x01
+
+###############################################################################
+# 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=0x00
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x19
+
+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}
+
+###############################################################################
+# Standby enable settings
+#NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+#Atonomous Mode
+#Enable 0x01
+#Disable 0x00
+NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
+
+###############################################################################
+# 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, 16, 04,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 0D, 06, 3E, 2D, 15, 88, 15, 00
+    }
+
+###############################################################################
+# 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=0x02
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=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
+
+###############################################################################
+#Chip type
+#PN547C2            0x01
+#PN65T              0x02
+
+NXP_NFC_CHIP=0x01
+
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+# CE when Screen state is locked
+# Disable           0x00
+# Enable            0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
diff --git a/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf b/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf
new file mode 100644
index 0000000..eca60d8
--- /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=0x03
+
+###############################################################################
+#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-PN65T_example.conf b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
new file mode 100644
index 0000000..21f2c18
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
@@ -0,0 +1,269 @@
+## 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/libpn547_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL       1
+#define CLK_SRC_PLL        2
+
+NXP_SYS_CLK_SRC_SEL=0x01
+
+###############################################################################
+# 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=0x00
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x19
+
+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}
+
+###############################################################################
+# Standby enable settings
+NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+#Atonomous Mode
+#Enable 0x01
+#Disable 0x00
+NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
+
+###############################################################################
+# 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, 1A, 05,
+    A0, EC, 01, 01,
+    A0, ED, 01, 01,
+    A0, 5E, 01, 01,
+    A0, 12, 01, 02,
+    A0, 0D, 06, 3E, 2D, 15, 88, 15, 00
+    }
+
+###############################################################################
+# 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
+        }
+
+###############################################################################
+# 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=0x02
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=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
+
+##############################################################################
+#### Select the CHIP ####
+#PN547C2            0x01
+#PN65T              0x02
+#PN548AD            0x03
+#PN66T              0x04
+
+NXP_NFC_CHIP=0x02
+
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0xFF
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0xFF
+
+###############################################################################
+# CE when Screen state is locked
+# Disable           0x00
+# Enable            0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+
+###############################################################################
+# P61 interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LS_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 LTSM interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LTSM_DEFAULT_INTERFACE=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
+
+###############################################################################
+# P61 interface options for JCOP Download
+# NFC 0x01
+# SPI 0x02
+NXP_P61_JCOP_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 JCOP OS download  options
+# FRAMEWORK API BY APPLICATION 0x00
+# AT BOOT_TIME 0x01
+NXP_JCOPDL_AT_BOOT_ENABLE=0x00
+
+###############################################################################
+# Loader service version
+# NFC service checks for LS version 2.0 or 2.1
+# LS2.0 0x20
+# LS2.1 0x21
+# LS2.2 0x22
+# AT NFC service intialization
+NXP_LOADER_SERVICE_VERSION=0x21
diff --git a/halimpl/pn54x/libnfc-nxp-PN66T_example.conf b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
new file mode 100644
index 0000000..c96fbb3
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
@@ -0,0 +1,301 @@
+## 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=0x1A
+
+###############################################################################
+# 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
+# Clock timeout settings A004
+NXP_CORE_CONF_EXTN={20, 02, 1D, 07,
+    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
+    }
+
+###############################################################################
+# 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
+        }
+
+###############################################################################
+# 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=0x03
+
+###############################################################################
+#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=0x04
+
+###############################################################################
+# 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
+
+###############################################################################
+# P61 interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LS_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 LTSM interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LTSM_DEFAULT_INTERFACE=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
+
+###############################################################################
+# P61 interface options for JCOP Download
+# NFC 0x01
+# SPI 0x02
+NXP_P61_JCOP_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 JCOP OS download  options
+# FRAMEWORK API BY APPLICATION 0x00
+# AT BOOT_TIME 0x01
+NXP_JCOPDL_AT_BOOT_ENABLE=0x00
+
+###############################################################################
+# Loader service version
+# NFC service checks for LS version 2.0 or 2.1
+# LS2.0 0x20
+# LS2.1 0x21
+# LS2.2 0x22
+# AT NFC service intialization
+NXP_LOADER_SERVICE_VERSION=0x21
diff --git a/halimpl/pn54x/log/phNxpLog.c b/halimpl/pn54x/log/phNxpLog.c
new file mode 100644
index 0000000..ad8886c
--- /dev/null
+++ b/halimpl/pn54x/log/phNxpLog.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2010-2014 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 <string.h>
+#if ! defined (NXPLOG__H_INCLUDED)
+#    include "phNxpLog.h"
+#    include "phNxpConfig.h"
+#endif
+#include <cutils/properties.h>
+
+const char * NXPLOG_ITEM_EXTNS   = "NxpExtns";
+const char * NXPLOG_ITEM_NCIHAL  = "NxpHal";
+const char * NXPLOG_ITEM_NCIX    = "NxpNciX";
+const char * NXPLOG_ITEM_NCIR    = "NxpNciR";
+const char * NXPLOG_ITEM_FWDNLD  = "NxpFwDnld";
+const char * NXPLOG_ITEM_TML     = "NxpTml";
+
+#ifdef NXP_HCI_REQ
+const char * NXPLOG_ITEM_HCPX    = "NxpHcpX";
+const char * NXPLOG_ITEM_HCPR    = "NxpHcpR";
+#endif /*NXP_HCI_REQ*/
+
+/* global log level structure */
+nci_log_level_t gLog_level;
+
+
+/*******************************************************************************
+ *
+ * Function         phNxpLog_SetGlobalLogLevel
+ *
+ * Description      Sets the global log level for all modules.
+ *                  This value is set by Android property nfc.nxp_log_level_global.
+ *                  If value can be overridden by module log level.
+ *
+ * Returns          The value of global log level
+ *
+ ******************************************************************************/
+static uint8_t phNxpLog_SetGlobalLogLevel (void)
+{
+    uint8_t level = NXPLOG_DEFAULT_LOGLEVEL;
+    unsigned long num = 0;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    int len = property_get (PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL, valueStr, "");
+    if (len > 0)
+    {
+        /* let Android property override .conf variable */
+        sscanf (valueStr, "%lu", &num);
+        level = (unsigned char) num;
+    }
+    memset(&gLog_level, level, sizeof(nci_log_level_t));
+    return level;
+}
+
+/*******************************************************************************
+ *
+ * Function         phNxpLog_SetHALLogLevel
+ *
+ * Description      Sets the HAL layer log level.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+static void phNxpLog_SetHALLogLevel (uint8_t level)
+{
+    unsigned long num = 0;
+    int len;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+    if (GetNxpNumValue (NAME_NXPLOG_HAL_LOGLEVEL, &num, sizeof(num)))
+    {
+        gLog_level.hal_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;;
+    }
+
+    len = property_get (PROP_NAME_NXPLOG_HAL_LOGLEVEL, valueStr, "");
+    if (len > 0)
+    {
+        /* let Android property override .conf variable */
+        sscanf (valueStr, "%lu", &num);
+        gLog_level.hal_log_level = (unsigned char) num;
+    }
+}
+
+/*******************************************************************************
+ *
+ * Function         phNxpLog_SetExtnsLogLevel
+ *
+ * Description      Sets the Extensions layer log level.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+static void phNxpLog_SetExtnsLogLevel (uint8_t level)
+{
+    unsigned long num = 0;
+    int len;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+    if (GetNxpNumValue (NAME_NXPLOG_EXTNS_LOGLEVEL, &num, sizeof(num)))
+    {
+        gLog_level.extns_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;;
+    }
+
+    len = property_get (PROP_NAME_NXPLOG_EXTNS_LOGLEVEL, valueStr, "");
+    if (len > 0)
+    {
+        /* let Android property override .conf variable */
+        sscanf (valueStr, "%lu", &num);
+        gLog_level.extns_log_level = (unsigned char) num;
+    }
+}
+
+/*******************************************************************************
+ *
+ * Function         phNxpLog_SetTmlLogLevel
+ *
+ * Description      Sets the Tml layer log level.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+static void phNxpLog_SetTmlLogLevel (uint8_t level)
+{
+    unsigned long num = 0;
+    int len;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+    if (GetNxpNumValue (NAME_NXPLOG_TML_LOGLEVEL, &num, sizeof(num)))
+    {
+        gLog_level.tml_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;;
+    }
+
+    len = property_get (PROP_NAME_NXPLOG_TML_LOGLEVEL, valueStr, "");
+    if (len > 0)
+    {
+        /* let Android property override .conf variable */
+        sscanf (valueStr, "%lu", &num);
+        gLog_level.tml_log_level = (unsigned char) num;
+    }
+}
+
+/*******************************************************************************
+ *
+ * Function         phNxpLog_SetDnldLogLevel
+ *
+ * Description      Sets the FW download layer log level.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+static void phNxpLog_SetDnldLogLevel (uint8_t level)
+{
+    unsigned long num = 0;
+    int len;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+    if (GetNxpNumValue (NAME_NXPLOG_FWDNLD_LOGLEVEL, &num, sizeof(num)))
+    {
+        gLog_level.dnld_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;;
+    }
+
+    len = property_get (PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL, valueStr, "");
+    if (len > 0)
+    {
+        /* let Android property override .conf variable */
+        sscanf (valueStr, "%lu", &num);
+        gLog_level.dnld_log_level = (unsigned char) num;
+    }
+}
+
+/*******************************************************************************
+ *
+ * Function         phNxpLog_SetNciTxLogLevel
+ *
+ * Description      Sets the NCI transaction layer log level.
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+static void phNxpLog_SetNciTxLogLevel (uint8_t level)
+{
+    unsigned long num = 0;
+    int len;
+    char valueStr [PROPERTY_VALUE_MAX] = {0};
+    if (GetNxpNumValue (NAME_NXPLOG_NCIX_LOGLEVEL, &num, sizeof(num)))
+    {
+        gLog_level.ncix_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;
+    }
+    if (GetNxpNumValue (NAME_NXPLOG_NCIR_LOGLEVEL, &num, sizeof(num)))
+    {
+        gLog_level.ncir_log_level = (level > (unsigned char) num) ? level : (unsigned char) num;;
+    }
+
+    len = property_get (PROP_NAME_NXPLOG_NCI_LOGLEVEL, valueStr, "");
+    if (len > 0)
+    {
+        /* let Android property override .conf variable */
+        sscanf (valueStr, "%lu", &num);
+        gLog_level.ncix_log_level = (unsigned char) num;
+        gLog_level.ncir_log_level = (unsigned char) num;
+    }
+}
+
+/******************************************************************************
+ * Function         phNxpLog_InitializeLogLevel
+ *
+ * Description      Initialize and get log level of module from libnfc-nxp.conf or
+ *                  Android runtime properties.
+ *                  The Android property nfc.nxp_global_log_level is to
+ *                  define log level for all modules. Modules log level will overwide global level.
+ *                  The Android property will overwide the level
+ *                  in libnfc-nxp.conf
+ *
+ *                  Android property names:
+ *                      nfc.nxp_log_level_global    * defines log level for all modules
+ *                      nfc.nxp_log_level_extns     * extensions module log
+ *                      nfc.nxp_log_level_hal       * Hal module log
+ *                      nfc.nxp_log_level_dnld      * firmware download module log
+ *                      nfc.nxp_log_level_tml       * TML module log
+ *                      nfc.nxp_log_level_nci       * NCI transaction log
+ *
+ *                  Log Level values:
+ *                      NXPLOG_LOG_SILENT_LOGLEVEL  0        * No trace to show
+ *                      NXPLOG_LOG_ERROR_LOGLEVEL   1        * Show Error trace only
+ *                      NXPLOG_LOG_WARN_LOGLEVEL    2        * Show Warning trace and Error trace
+ *                      NXPLOG_LOG_DEBUG_LOGLEVEL   3        * Show all traces
+ *
+ * Returns          void
+ *
+ ******************************************************************************/
+void phNxpLog_InitializeLogLevel(void)
+{
+    uint8_t level = phNxpLog_SetGlobalLogLevel();
+    phNxpLog_SetHALLogLevel(level);
+    phNxpLog_SetExtnsLogLevel(level);
+    phNxpLog_SetTmlLogLevel(level);
+    phNxpLog_SetDnldLogLevel(level);
+    phNxpLog_SetNciTxLogLevel(level);
+
+    ALOGD ("%s: global =%u, Fwdnld =%u, extns =%u, \
+                hal =%u, tml =%u, ncir =%u, \
+                ncix =%u", \
+                __FUNCTION__, gLog_level.global_log_level, gLog_level.dnld_log_level,
+                    gLog_level.extns_log_level, gLog_level.hal_log_level, gLog_level.tml_log_level,
+                    gLog_level.ncir_log_level, gLog_level.ncix_log_level);
+}
diff --git a/halimpl/pn54x/log/phNxpLog.h b/halimpl/pn54x/log/phNxpLog.h
new file mode 100644
index 0000000..22ce7b4
--- /dev/null
+++ b/halimpl/pn54x/log/phNxpLog.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+#if ! defined (NXPLOG__H_INCLUDED)
+#define NXPLOG__H_INCLUDED
+
+#include <cutils/log.h>
+
+typedef struct nci_log_level
+{
+    uint8_t global_log_level;
+    uint8_t extns_log_level;
+    uint8_t hal_log_level;
+    uint8_t dnld_log_level;
+    uint8_t tml_log_level;
+    uint8_t ncix_log_level;
+    uint8_t ncir_log_level;
+} nci_log_level_t;
+
+/* global log level Ref */
+extern nci_log_level_t gLog_level;
+
+/* define log module included when compile */
+#define ENABLE_EXTNS_TRACES   TRUE
+#define ENABLE_HAL_TRACES     TRUE
+#define ENABLE_TML_TRACES     TRUE
+#define ENABLE_FWDNLD_TRACES  TRUE
+#define ENABLE_NCIX_TRACES    TRUE
+#define ENABLE_NCIR_TRACES    TRUE
+
+#define ENABLE_HCPX_TRACES    FALSE
+#define ENABLE_HCPR_TRACES    FALSE
+
+/* ####################### Set the log module name in .conf file ########################## */
+#define NAME_NXPLOG_EXTNS_LOGLEVEL          "NXPLOG_EXTNS_LOGLEVEL"
+#define NAME_NXPLOG_HAL_LOGLEVEL            "NXPLOG_NCIHAL_LOGLEVEL"
+#define NAME_NXPLOG_NCIX_LOGLEVEL           "NXPLOG_NCIX_LOGLEVEL"
+#define NAME_NXPLOG_NCIR_LOGLEVEL           "NXPLOG_NCIR_LOGLEVEL"
+#define NAME_NXPLOG_FWDNLD_LOGLEVEL         "NXPLOG_FWDNLD_LOGLEVEL"
+#define NAME_NXPLOG_TML_LOGLEVEL            "NXPLOG_TML_LOGLEVEL"
+
+/* ####################### Set the log module name by Android property ########################## */
+#define PROP_NAME_NXPLOG_GLOBAL_LOGLEVEL       "nfc.nxp_log_level_global"
+#define PROP_NAME_NXPLOG_EXTNS_LOGLEVEL        "nfc.nxp_log_level_extns"
+#define PROP_NAME_NXPLOG_HAL_LOGLEVEL          "nfc.nxp_log_level_hal"
+#define PROP_NAME_NXPLOG_NCI_LOGLEVEL          "nfc.nxp_log_level_nci"
+#define PROP_NAME_NXPLOG_FWDNLD_LOGLEVEL       "nfc.nxp_log_level_dnld"
+#define PROP_NAME_NXPLOG_TML_LOGLEVEL          "nfc.nxp_log_level_tml"
+
+/* ####################### Set the logging level for EVERY COMPONENT here ######################## :START: */
+#define NXPLOG_LOG_SILENT_LOGLEVEL             0x00
+#define NXPLOG_LOG_ERROR_LOGLEVEL              0x01
+#define NXPLOG_LOG_WARN_LOGLEVEL               0x02
+#define NXPLOG_LOG_DEBUG_LOGLEVEL              0x03
+/* ####################### Set the default logging level for EVERY COMPONENT here ########################## :END: */
+
+
+/* The Default log level for all the modules. */
+#define NXPLOG_DEFAULT_LOGLEVEL                NXPLOG_LOG_ERROR_LOGLEVEL
+
+
+/* ################################################################################################################ */
+/* ############################################### Component Names ################################################ */
+/* ################################################################################################################ */
+
+extern const char * NXPLOG_ITEM_EXTNS;   /* Android logging tag for NxpExtns  */
+extern const char * NXPLOG_ITEM_NCIHAL;  /* Android logging tag for NxpNciHal */
+extern const char * NXPLOG_ITEM_NCIX;    /* Android logging tag for NxpNciX   */
+extern const char * NXPLOG_ITEM_NCIR;    /* Android logging tag for NxpNciR   */
+extern const char * NXPLOG_ITEM_FWDNLD;  /* Android logging tag for NxpFwDnld */
+extern const char * NXPLOG_ITEM_TML;     /* Android logging tag for NxpTml    */
+
+#ifdef NXP_HCI_REQ
+extern const char * NXPLOG_ITEM_HCPX;    /* Android logging tag for NxpHcpX   */
+extern const char * NXPLOG_ITEM_HCPR;    /* Android logging tag for NxpHcpR   */
+#endif /*NXP_HCI_REQ*/
+
+/* ######################################## Defines used for Logging data ######################################### */
+#ifdef NXP_VRBS_REQ
+#define NXPLOG_FUNC_ENTRY(COMP) \
+    LOG_PRI(ANDROID_LOG_VERBOSE,(COMP),"+:%s",(__FUNCTION__))
+#define NXPLOG_FUNC_EXIT(COMP) \
+    LOG_PRI(ANDROID_LOG_VERBOSE,(COMP),"-:%s",(__FUNCTION__))
+#endif /*NXP_VRBS_REQ*/
+
+/* ################################################################################################################ */
+/* ######################################## Logging APIs of actual modules ######################################## */
+/* ################################################################################################################ */
+/* Logging APIs used by NxpExtns module */
+#if (ENABLE_EXTNS_TRACES == TRUE )
+#    define NXPLOG_EXTNS_D(...)  {if(gLog_level.extns_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_EXTNS,__VA_ARGS__);}
+#    define NXPLOG_EXTNS_W(...)  {if(gLog_level.extns_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_EXTNS,__VA_ARGS__);}
+#    define NXPLOG_EXTNS_E(...)  {if(gLog_level.extns_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_EXTNS,__VA_ARGS__);}
+#else
+#    define NXPLOG_EXTNS_D(...)
+#    define NXPLOG_EXTNS_W(...)
+#    define NXPLOG_EXTNS_E(...)
+#endif /* Logging APIs used by NxpExtns module */
+
+/* Logging APIs used by NxpNciHal module */
+#if (ENABLE_HAL_TRACES == TRUE )
+#    define NXPLOG_NCIHAL_D(...)  {if(gLog_level.hal_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_NCIHAL,__VA_ARGS__);}
+#    define NXPLOG_NCIHAL_W(...)  {if(gLog_level.hal_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_NCIHAL,__VA_ARGS__);}
+#    define NXPLOG_NCIHAL_E(...)  {if(gLog_level.hal_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_NCIHAL,__VA_ARGS__);}
+#else
+#    define NXPLOG_NCIHAL_D(...)
+#    define NXPLOG_NCIHAL_W(...)
+#    define NXPLOG_NCIHAL_E(...)
+#endif /* Logging APIs used by HAL module */
+
+/* Logging APIs used by NxpNciX module */
+#if (ENABLE_NCIX_TRACES == TRUE )
+#    define NXPLOG_NCIX_D(...)  {if(gLog_level.ncix_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_NCIX,__VA_ARGS__);}
+#    define NXPLOG_NCIX_W(...)  {if(gLog_level.ncix_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_NCIX,__VA_ARGS__);}
+#    define NXPLOG_NCIX_E(...)  {if(gLog_level.ncix_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_NCIX,__VA_ARGS__);}
+#else
+#    define NXPLOG_NCIX_D(...)
+#    define NXPLOG_NCIX_W(...)
+#    define NXPLOG_NCIX_E(...)
+#endif /* Logging APIs used by NCIx module */
+
+/* Logging APIs used by NxpNciR module */
+#if (ENABLE_NCIR_TRACES == TRUE )
+#    define NXPLOG_NCIR_D(...)  {if(gLog_level.ncir_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_NCIR,__VA_ARGS__);}
+#    define NXPLOG_NCIR_W(...)  {if(gLog_level.ncir_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_NCIR,__VA_ARGS__);}
+#    define NXPLOG_NCIR_E(...)  {if(gLog_level.ncir_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_NCIR,__VA_ARGS__);}
+#else
+#    define NXPLOG_NCIR_D(...)
+#    define NXPLOG_NCIR_W(...)
+#    define NXPLOG_NCIR_E(...)
+#endif /* Logging APIs used by NCIR module */
+
+/* Logging APIs used by NxpFwDnld module */
+#if (ENABLE_FWDNLD_TRACES == TRUE )
+#    define NXPLOG_FWDNLD_D(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#    define NXPLOG_FWDNLD_W(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#    define NXPLOG_FWDNLD_E(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#else
+#    define NXPLOG_FWDNLD_D(...)
+#    define NXPLOG_FWDNLD_W(...)
+#    define NXPLOG_FWDNLD_E(...)
+#endif /* Logging APIs used by NxpFwDnld module */
+
+/* Logging APIs used by NxpTml module */
+#if (ENABLE_TML_TRACES == TRUE )
+#    define NXPLOG_TML_D(...)  {if(gLog_level.tml_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_TML,__VA_ARGS__);}
+#    define NXPLOG_TML_W(...)  {if(gLog_level.tml_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_TML,__VA_ARGS__);}
+#    define NXPLOG_TML_E(...)  {if(gLog_level.tml_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_TML,__VA_ARGS__);}
+#else
+#    define NXPLOG_TML_D(...)
+#    define NXPLOG_TML_W(...)
+#    define NXPLOG_TML_E(...)
+#endif /* Logging APIs used by NxpTml module */
+
+#ifdef NXP_HCI_REQ
+/* Logging APIs used by NxpHcpX module */
+#if (ENABLE_HCPX_TRACES == TRUE )
+#    define NXPLOG_HCPX_D(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#    define NXPLOG_HCPX_W(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#    define NXPLOG_HCPX_E(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#else
+#    define NXPLOG_HCPX_D(...)
+#    define NXPLOG_HCPX_W(...)
+#    define NXPLOG_HCPX_E(...)
+#endif /* Logging APIs used by NxpHcpX module */
+
+/* Logging APIs used by NxpHcpR module */
+#if (ENABLE_HCPR_TRACES == TRUE )
+#    define NXPLOG_HCPR_D(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_DEBUG_LOGLEVEL) LOG_PRI(ANDROID_LOG_DEBUG,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#    define NXPLOG_HCPR_W(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_WARN_LOGLEVEL) LOG_PRI(ANDROID_LOG_WARN,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#    define NXPLOG_HCPR_E(...)  {if(gLog_level.dnld_log_level >= NXPLOG_LOG_ERROR_LOGLEVEL) LOG_PRI(ANDROID_LOG_ERROR,NXPLOG_ITEM_FWDNLD,__VA_ARGS__);}
+#else
+#    define NXPLOG_HCPR_D(...)
+#    define NXPLOG_HCPR_W(...)
+#    define NXPLOG_HCPR_E(...)
+#endif /* Logging APIs used by NxpHcpR module */
+#endif /* NXP_HCI_REQ */
+
+#ifdef NXP_VRBS_REQ
+#if (ENABLE_EXTNS_TRACES == TRUE )
+#    define NXPLOG_EXTNS_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_EXTNS)
+#    define NXPLOG_EXTNS_EXIT()  NXPLOG_FUNC_EXIT(NXPLOG_ITEM_EXTNS)
+#else
+#    define NXPLOG_EXTNS_ENTRY()
+#    define NXPLOG_EXTNS_EXIT()
+#endif
+
+#if (ENABLE_HAL_TRACES == TRUE )
+#    define NXPLOG_NCIHAL_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIHAL)
+#    define NXPLOG_NCIHAL_EXIT()  NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIHAL)
+#else
+#    define NXPLOG_NCIHAL_ENTRY()
+#    define NXPLOG_NCIHAL_EXIT()
+#endif
+
+#if (ENABLE_NCIX_TRACES == TRUE )
+#    define NXPLOG_NCIX_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIX)
+#    define NXPLOG_NCIX_EXIT()  NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIX)
+#else
+#    define NXPLOG_NCIX_ENTRY()
+#    define NXPLOG_NCIX_EXIT()
+#endif
+
+#if (ENABLE_NCIR_TRACES == TRUE )
+#    define NXPLOG_NCIR_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_NCIR)
+#    define NXPLOG_NCIR_EXIT()  NXPLOG_FUNC_EXIT(NXPLOG_ITEM_NCIR)
+#else
+#    define NXPLOG_NCIR_ENTRY()
+#    define NXPLOG_NCIR_EXIT()
+#endif
+
+#ifdef NXP_HCI_REQ
+
+#if (ENABLE_HCPX_TRACES == TRUE )
+#    define NXPLOG_HCPX_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_HCPX)
+#    define NXPLOG_HCPX_EXIT()  NXPLOG_FUNC_EXIT(NXPLOG_ITEM_HCPX)
+#else
+#    define NXPLOG_HCPX_ENTRY()
+#    define NXPLOG_HCPX_EXIT()
+#endif
+
+#if (ENABLE_HCPR_TRACES == TRUE )
+#    define NXPLOG_HCPR_ENTRY() NXPLOG_FUNC_ENTRY(NXPLOG_ITEM_HCPR)
+#    define NXPLOG_HCPR_EXIT()  NXPLOG_FUNC_EXIT(NXPLOG_ITEM_HCPR)
+#else
+#    define NXPLOG_HCPR_ENTRY()
+#    define NXPLOG_HCPR_EXIT()
+#endif
+#endif /* NXP_HCI_REQ */
+
+#endif /* NXP_VRBS_REQ */
+
+void phNxpLog_InitializeLogLevel(void);
+
+#endif /* NXPLOG__H_INCLUDED */
diff --git a/halimpl/pn54x/nfc_nci.c b/halimpl/pn54x/nfc_nci.c
new file mode 100644
index 0000000..4ae45ec
--- /dev/null
+++ b/halimpl/pn54x/nfc_nci.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2012-2014 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.
+ */
+
+#define LOG_TAG "NxpNfcNciHal"
+
+#include <string.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <errno.h>
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+#include <phNxpNciHal_Adaptation.h>
+
+/*****************************************************************************
+ * NXP NCI HAL Function implementations.
+ *****************************************************************************/
+
+/*******************************************************************************
+**
+** Function         hal_open
+**
+** Description      It opens and initialzes the physical connection with NFCC.
+**
+** 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;
+
+    pn547_dev_t *dev = (pn547_dev_t*) p_dev;
+    retval = phNxpNciHal_open(p_hal_cback, p_hal_data_callback);
+
+    return retval;
+}
+
+/*******************************************************************************
+**
+** Function         hal_write
+**
+** Description      Write the data to NFCC.
+**
+** 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;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
+
+    retval = phNxpNciHal_write(data_len, p_data);
+    return retval;
+}
+
+/*******************************************************************************
+**
+** Function         hal_core_initialized
+**
+** Description      Notify NFCC after successful initialization of NFCC.
+**                  All proprietary settings can be done here.
+**
+** 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;
+    pn547_dev_t* dev = (pn547_dev_t*) p_dev;
+
+    retval = phNxpNciHal_core_initialized(p_core_init_rsp_params);
+    return retval;
+}
+
+/*******************************************************************************
+**
+** Function         hal_pre_discover
+**
+** Description      Notify NFCC before start discovery.
+**
+** Returns          0 if successful
+**
+*******************************************************************************/
+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;
+}
+
+/*******************************************************************************
+**
+** Function         hal_close
+**
+** Description      Close the NFCC interface and free all resources.
+**
+** Returns          0 if successful
+**
+*******************************************************************************/
+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;
+}
+
+/*******************************************************************************
+**
+** Function         hal_control_granted
+**
+** Description      Notify NFCC that control is granted to HAL.
+**
+** Returns          0 if successful
+**
+*******************************************************************************/
+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;
+}
+
+/*******************************************************************************
+**
+** Function         hal_power_cycle
+**
+** Description      Notify power cycling has performed.
+**
+** Returns          0 if successful
+**
+*******************************************************************************/
+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;
+}
+
+/*************************************
+ * Generic device handling.
+ *************************************/
+
+/*******************************************************************************
+**
+** Function         nfc_close
+**
+** Description      Close the nfc device instance.
+**
+** Returns          0 if successful
+**
+*******************************************************************************/
+static int nfc_close(hw_device_t *dev)
+{
+    int retval = 0;
+    free(dev);
+    return retval;
+}
+
+/*******************************************************************************
+**
+** Function         nfc_open
+**
+** Description      Open the nfc device instance.
+**
+** Returns          0 if successful
+**
+*******************************************************************************/
+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)
+    {
+        pn547_dev_t *dev = calloc(1, sizeof(pn547_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;
+
+        *device = (hw_device_t*) dev;
+    }
+    else
+    {
+        retval = -EINVAL;
+    }
+
+    ALOGD("%s: exit %d", __FUNCTION__, retval);
+    return retval;
+}
+
+/* Android hardware module definition */
+static struct hw_module_methods_t nfc_module_methods =
+{
+    .open = nfc_open,
+};
+
+/* NFC module definition */
+struct nfc_nci_module_t HAL_MODULE_INFO_SYM =
+{
+    .common =
+    {
+        .tag = HARDWARE_MODULE_TAG,
+        .module_api_version = 0x0100, /* [15:8] major, [7:0] minor (1.0) */
+        .hal_api_version = 0x00, /* 0 is only valid value */
+        .id = NFC_NCI_HARDWARE_MODULE_ID,
+        .name = "NXP PN54X NFC NCI HW HAL",
+        .author = "NXP Semiconductors",
+        .methods = &nfc_module_methods,
+    },
+};
diff --git a/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c b/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
new file mode 100644
index 0000000..c45099f
--- /dev/null
+++ b/halimpl/pn54x/self-test/phNxpNciHal_SelfTest.c
@@ -0,0 +1,1998 @@
+/*
+ * Copyright (C) 2012-2014 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 NXP_HW_SELF_TEST
+
+
+#include <phNxpNciHal_SelfTest.h>
+#include <phNxpLog.h>
+#include <pthread.h>
+#include <phOsalNfc_Timer.h>
+
+#define HAL_WRITE_RSP_TIMEOUT   (2000)   /* Timeout value to wait for response from PN54X */
+#define HAL_WRITE_MAX_RETRY     (10)
+
+/******************* Structures and definitions *******************************/
+
+typedef uint8_t (*st_validator_t)(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+
+phAntenna_St_Resp_t phAntenna_resp;
+
+typedef struct nci_test_data
+{
+    nci_data_t cmd;
+    nci_data_t exp_rsp;
+    nci_data_t exp_ntf;
+    st_validator_t rsp_validator;
+    st_validator_t ntf_validator;
+
+}nci_test_data_t;
+
+/******************* Global variables *****************************************/
+
+static int thread_running = 0;
+static uint32_t timeoutTimerId = 0;
+static int hal_write_timer_fired = 0;
+
+/* TML Context */
+extern phTmlNfc_Context_t *gpphTmlNfc_Context;
+
+/* Global HAL Ref */
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+
+/* Driver parameters */
+phLibNfc_sConfig_t   gDrvCfg;
+
+NFCSTATUS gtxldo_status = NFCSTATUS_FAILED;
+NFCSTATUS gagc_value_status = NFCSTATUS_FAILED;
+NFCSTATUS gagc_nfcld_status = NFCSTATUS_FAILED;
+NFCSTATUS gagc_differential_status = NFCSTATUS_FAILED;
+
+
+static uint8_t st_validator_testEquals(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_null(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testSWP1_vltg(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_Txldo(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_AgcVal(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_AgcVal_FixedNfcLd(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static uint8_t st_validator_testAntenna_AgcVal_Differential(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_getPrbsCmd (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+        uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len);
+#else
+NFCSTATUS phNxpNciHal_getPrbsCmd (uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len);
+#endif
+/* Test data to validate SWP line 2*/
+static nci_test_data_t swp2_test_data[] = {
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x01} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x01} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x01} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+            0x03, {0x20,0x01,0x00}
+#endif
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+            0x4, {0x40,0x01,0x17,0x00 }
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+            0x03, {0x2F,0x02,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+            0x04, {0x2F,0x3E,0x01,0x01} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x3E,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x04, {0x6F,0x3E,0x02,0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_testEquals
+    },
+
+};
+
+/* Test data to validate SWP line 1*/
+static nci_test_data_t swp1_test_data[] = {
+
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x01} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x01} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x01} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+            0x03, {0x20,0x01,0x00}
+#endif
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+            0x4, {0x40,0x01,0x17,0x00 }
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+            0x03, {0x2F,0x02,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+            0x04, {0x2F,0x3E,0x01,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x3E,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x04, {0x6F,0x3E,0x02,0x00} /* ext_ntf */
+        },
+
+        st_validator_testEquals, /* validator */
+        st_validator_testSWP1_vltg
+    },
+};
+
+static nci_test_data_t prbs_test_data[] = {
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x00} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+            0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+            0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    },
+    {
+        {
+            0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#endif
+    }
+};
+
+/* for rf field test, first requires to disable the standby mode */
+static nci_test_data_t rf_field_on_test_data[] = {
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x00} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+            0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+            0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    {
+         {
+            0x03, {0x2F,0x02,0x00} /* cmd */
+         },
+         {
+            0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+         },
+         {
+            0x00, {0x00} /* ext_ntf */
+         },
+         st_validator_testEquals, /* validator */
+         st_validator_null
+    },
+    {
+         {
+            0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+         },
+         {
+            0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+         },
+         {
+            0x00, {0x00} /* ext_ntf */
+         },
+         st_validator_testEquals, /* validator */
+         st_validator_null
+    },
+#endif
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x2F,0x3D,0x02,0x20,0x01} /* cmd */
+#else
+            0x08, {0x2F,0x3D,0x05,0x20,0x01,0x00,0x00,0x00} /* cmd */
+#endif
+        },
+        {
+            0x04, {0x4F,0x3D,0x05,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    },
+    {
+        {
+            0x04, {0x2F,0x00,0x01,0x01} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#endif
+    }
+};
+
+static nci_test_data_t rf_field_off_test_data[] = {
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x00} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+            0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+            0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    {
+        {
+            0x03, {0x2F,0x02,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+     },
+     {
+        {
+             0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+        },
+        {
+             0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+        },
+        {
+             0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+     },
+#endif
+     {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x2F,0x3D,0x02,0x20,0x00} /* cmd */
+#else
+            0x08, {0x2F,0x3D,0x05,0x20,0x00,0x00,0x00,0x00} /* cmd */
+#endif
+        },
+        {
+            0x04, {0x4F,0x3D,0x05,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+     },
+     {
+        {
+            0x04, {0x2F,0x00,0x01,0x01} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#endif
+     }
+};
+
+/* Download pin test data 1 */
+static nci_test_data_t download_pin_test_data1[] = {
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x01} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x01} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x01} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+};
+
+/* Download pin test data 2 */
+static nci_test_data_t download_pin_test_data2[] = {
+    {
+        {
+            0x08, {0x00, 0x04, 0xD0, 0x11, 0x00, 0x00, 0x5B, 0x46} /* cmd */
+        },
+        {
+            0x08, {0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x87, 0x16} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+};
+/* Antenna self test data*/
+static nci_test_data_t antenna_self_test_data[] = {
+    {
+        {
+            0x04, {0x20,0x00,0x01,0x00} /* cmd */
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x06, {0x40,0x00,0x03,0x00,0x11,0x00} /* exp_rsp */
+#else
+            0x06, {0x40,0x00,0x03,0x00,0x10,0x00} /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x05, {0x20,0x01,0x02,0x00,0x00} /* cmd */
+#else
+            0x03, {0x20,0x01,0x00} /* cmd */
+#endif
+        },
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x4, {0x40,0x01,0x19,0x00 } /* exp_rsp */
+#else
+            0x4, {0x40,0x01,0x17,0x00 } /* exp_rsp */
+#endif
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+    {
+        {
+            0x03, {0x2F,0x02,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x02,0x05,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    {
+        {
+            0x04, {0x2F,0x00,0x01,0x00} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+    },
+#endif
+    {
+        {
+            0x05, {0x2F, 0x3D, 0x02, 0x01, 0x80} /* TxLDO cureent measurement cmd */
+        },
+        {
+            0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testAntenna_Txldo,
+        st_validator_null
+    },
+    {
+        {
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            0x07, {0x2F, 0x3D, 0x04, 0x02, 0xC8, 0x60, 0x03} /* AGC measurement cmd */
+#else
+            0x07, {0x2F, 0x3D, 0x04, 0x02, 0xCD, 0x60, 0x03} /* AGC measurement cmd */
+#endif
+        },
+        {
+            0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testAntenna_AgcVal,
+        st_validator_null
+    },
+    {
+        {
+            0x07, {0x2F, 0x3D, 0x04, 0x04, 0x20, 0x08, 0x20} /* AGC with NFCLD measurement cmd */
+        },
+        {
+            0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testAntenna_AgcVal_FixedNfcLd,
+        st_validator_null
+    },
+    {
+        {
+            0x07, {0x2F, 0x3D, 0x04, 0x08, 0x8C, 0x60, 0x03} /* AGC with NFCLD measurement cmd */
+        },
+        {
+            0x03, {0x4F, 0x3D, 05} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testAntenna_AgcVal_Differential,
+        st_validator_null
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    },
+    {
+        {
+            0x04, {0x2F,0x00,0x01,0x01} /* cmd */
+        },
+        {
+            0x04, {0x4F,0x00,0x01,0x00} /* exp_rsp */
+        },
+        {
+            0x00, {0x00} /* ext_ntf */
+        },
+        st_validator_testEquals, /* validator */
+        st_validator_null
+#endif
+    }
+};
+
+
+/************** Self test functions ***************************************/
+
+static uint8_t st_validator_testEquals(nci_data_t *exp, phTmlNfc_TransactInfo_t *act);
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+static void hal_write_rsp_timeout_cb(uint32_t TimerId, void *pContext);
+static void hal_read_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+
+/*******************************************************************************
+**
+** Function         st_validator_null
+**
+** Description      Null Validator
+**
+** Returns          One
+**
+*******************************************************************************/
+static uint8_t st_validator_null(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    UNUSED(exp);
+    UNUSED(act);
+    return 1;
+}
+
+/*******************************************************************************
+**
+** Function         st_validator_testSWP1_vltg
+**
+** Description      Validator function to validate swp1 connection.
+**
+** Returns          One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testSWP1_vltg(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    uint8_t result = 0;
+
+    if(NULL == exp || NULL == act)
+    {
+        return result;
+    }
+
+    if( (act->wLength == 0x05) &&
+            (memcmp(exp->p_data,act->pBuff,exp->len) == 0))
+    {
+        if(act->pBuff[4] == 0x01 || act->pBuff[4] == 0x02)
+        {
+            result = 1;
+        }
+    }
+
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         st_validator_testAntenna_Txldo
+**
+** Description      Validator function to validate Antenna TxLDO current measurement.
+**
+** Returns          One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_Txldo(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    uint8_t result = 0;
+    uint8_t mesuredrange =0;
+    long measured_val = 0;
+    int tolerance = 0;
+
+    if(NULL == exp || NULL == act)
+    {
+        return result;
+    }
+
+    NXPLOG_NCIHAL_D("st_validator_testAntenna_Txldo = 0x%x", act->pBuff[3]);
+    if (0x05 == act->pBuff[2])
+    {
+        if (NFCSTATUS_SUCCESS == act->pBuff[3])
+        {
+            result = 1;
+            NXPLOG_NCIHAL_D("Antenna: TxLDO current measured raw value in mA : 0x%x", act->pBuff[4]);
+            if(0x00 == act->pBuff[5])
+            {
+                NXPLOG_NCIHAL_D("Measured range : 0x00 = 50 - 100 mA");
+                measured_val = ((0.40 * act->pBuff[4]) + 50);
+                NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", measured_val);
+            }
+            else
+            {
+                NXPLOG_NCIHAL_D("Measured range : 0x01 = 20 - 70 mA");
+                measured_val = ((0.40 * act->pBuff[4]) + 20);
+                NXPLOG_NCIHAL_D("TxLDO current absolute value in mA = %ld", measured_val);
+            }
+
+            tolerance = (phAntenna_resp.wTxdoMeasuredRangeMax  *
+                         phAntenna_resp.wTxdoMeasuredTolerance)/100;
+            if ((measured_val <= phAntenna_resp.wTxdoMeasuredRangeMax + tolerance))
+            {
+                tolerance = (phAntenna_resp.wTxdoMeasuredRangeMin *
+                             phAntenna_resp.wTxdoMeasuredTolerance)/100;
+                if((measured_val >= phAntenna_resp.wTxdoMeasuredRangeMin - tolerance))
+                {
+                    gtxldo_status = NFCSTATUS_SUCCESS;
+                    NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement PASS");
+                }
+                else
+                {
+                    gtxldo_status = NFCSTATUS_FAILED;
+                    NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL");
+                }
+            }
+            else
+            {
+                gtxldo_status = NFCSTATUS_FAILED;
+                NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement FAIL");
+            }
+        }
+        else
+        {
+            gtxldo_status = NFCSTATUS_FAILED;
+            NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement failed: Invalid status");
+        }
+
+    }
+    else
+    {
+        gtxldo_status = NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_E("Test Antenna Response for TxLDO measurement failed: Invalid payload length");
+    }
+
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         st_validator_testAntenna_AgcVal
+**
+** Description      Validator function reads AGC value of antenna and print the info
+**
+** Returns          One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_AgcVal(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    uint8_t result = 0;
+    int agc_tolerance = 0;
+    long agc_val = 0;
+
+    if(NULL == exp || NULL == act)
+    {
+        return result;
+    }
+
+    if (0x05 == act->pBuff[2])
+    {
+        if (NFCSTATUS_SUCCESS == act->pBuff[3])
+        {
+            result = 1;
+            agc_tolerance = (phAntenna_resp.wAgcValue * phAntenna_resp.wAgcValueTolerance)/100;
+            agc_val =  ((act->pBuff[5] << 8) | (act->pBuff[4]));
+            NXPLOG_NCIHAL_D("AGC value : %ld", agc_val);
+            if(((phAntenna_resp.wAgcValue - agc_tolerance) <= agc_val) &&
+               (agc_val <= (phAntenna_resp.wAgcValue + agc_tolerance)))
+            {
+                gagc_value_status = NFCSTATUS_SUCCESS;
+                NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values  PASS");
+            }
+            else
+            {
+                gagc_value_status = NFCSTATUS_FAILED;
+                NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values  FAIL");
+            }
+        }
+        else
+        {
+            gagc_value_status = NFCSTATUS_FAILED;
+            NXPLOG_NCIHAL_E("Test Antenna Response for AGC Values  FAIL");
+        }
+    }
+    else
+    {
+        gagc_value_status = NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_E("Test Antenna Response for AGC value failed: Invalid payload length");
+    }
+
+    return result;
+}
+/*******************************************************************************
+**
+** Function         st_validator_testAntenna_AgcVal_FixedNfcLd
+**
+** Description      Validator function reads and print AGC value of
+**                  antenna with fixed NFCLD
+**
+** Returns          One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_AgcVal_FixedNfcLd(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    uint8_t result = 0;
+    int agc_nfcld_tolerance = 0;
+    long agc_nfcld = 0;
+
+    if(NULL == exp || NULL == act)
+    {
+        return result;
+    }
+
+    if(0x05 == act->pBuff[2])
+    {
+        if(NFCSTATUS_SUCCESS == act->pBuff[3])
+        {
+            result = 1;
+            agc_nfcld_tolerance = (phAntenna_resp.wAgcValuewithfixedNFCLD *
+                                   phAntenna_resp.wAgcValuewithfixedNFCLDTolerance)/100;
+            agc_nfcld =  ((act->pBuff[5] << 8) | (act->pBuff[4]));
+            NXPLOG_NCIHAL_D("AGC value with Fixed Nfcld  : %ld", agc_nfcld);
+
+            if(((phAntenna_resp.wAgcValuewithfixedNFCLD - agc_nfcld_tolerance) <= agc_nfcld) &&
+              (agc_nfcld <= (phAntenna_resp.wAgcValuewithfixedNFCLD + agc_nfcld_tolerance)))
+            {
+                gagc_nfcld_status = NFCSTATUS_SUCCESS;
+                NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD PASS");
+            }
+            else
+            {
+                gagc_nfcld_status =  NFCSTATUS_FAILED;
+                NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD FAIL");
+            }
+        }
+        else
+        {
+            gagc_nfcld_status =  NFCSTATUS_FAILED;
+            NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD failed: Invalid status");
+        }
+    }
+    else
+    {
+        gagc_nfcld_status =  NFCSTATUS_FAILED;
+        NXPLOG_NCIHAL_E("Test Antenna Response for AGC value with fixed NFCLD failed: Invalid payload length");
+    }
+
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         st_validator_testAntenna_AgcVal_Differential
+**
+** Description      Reads the AGC value with open/short RM from buffer and print
+**
+** Returns          One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testAntenna_AgcVal_Differential(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    uint8_t result = 0;
+    int agc_toleranceopne1 = 0;
+    int agc_toleranceopne2 = 0;
+    long agc_differentialOpne1 = 0;
+    long agc_differentialOpne2 = 0;
+
+    if(NULL == exp || NULL == act)
+    {
+        return result;
+    }
+
+    if (0x05 == act->pBuff[2])
+    {
+        if (NFCSTATUS_SUCCESS == act->pBuff[3])
+        {
+            result = 1;
+            agc_toleranceopne1=(phAntenna_resp.wAgcDifferentialWithOpen1 *
+                                phAntenna_resp.wAgcDifferentialWithOpenTolerance1)/100;
+            agc_toleranceopne2=(phAntenna_resp.wAgcDifferentialWithOpen2 *
+                                phAntenna_resp.wAgcDifferentialWithOpenTolerance2)/100;
+            agc_differentialOpne1 =  ((act->pBuff[5] << 8) | (act->pBuff[4]));
+            agc_differentialOpne2 =  ((act->pBuff[7] << 8) | (act->pBuff[6]));
+            NXPLOG_NCIHAL_D("AGC value differential Opne 1  : %ld", agc_differentialOpne1);
+            NXPLOG_NCIHAL_D("AGC value differentialOpne  2 : %ld", agc_differentialOpne2);
+
+            if(((agc_differentialOpne1 >= phAntenna_resp.wAgcDifferentialWithOpen1 - agc_toleranceopne1) &&
+               (agc_differentialOpne1 <= phAntenna_resp.wAgcDifferentialWithOpen1 + agc_toleranceopne1)) &&
+               ((agc_differentialOpne2 >= phAntenna_resp.wAgcDifferentialWithOpen2 - agc_toleranceopne2) &&
+               (agc_differentialOpne2 <= phAntenna_resp.wAgcDifferentialWithOpen2 + agc_toleranceopne2)))
+            {
+                gagc_differential_status = NFCSTATUS_SUCCESS;
+                NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential Open PASS");
+            }
+            else
+            {
+                gagc_differential_status = NFCSTATUS_FAILED;
+                NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential Open  FAIL");
+            }
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential failed: Invalid status");
+            gagc_differential_status = NFCSTATUS_FAILED;
+        }
+
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Test Antenna Response for AGC Differential failed: Invalid payload length");
+        gagc_differential_status = NFCSTATUS_FAILED;
+    }
+
+    return result;
+}
+/*******************************************************************************
+**
+** Function         st_validator_testEquals
+**
+** Description      Validator function to validate for equality between actual
+**                  and expected values.
+**
+** Returns          One if successful otherwise Zero.
+**
+*******************************************************************************/
+static uint8_t st_validator_testEquals(nci_data_t *exp, phTmlNfc_TransactInfo_t *act)
+{
+    uint8_t result = 0;
+
+    if(NULL == exp || NULL == act)
+    {
+        return result;
+    }
+    if(exp->len <= act->wLength &&
+            (memcmp(exp->p_data,act->pBuff,exp->len) == 0))
+    {
+        result = 1;
+    }
+
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         hal_write_rsp_timeout_cb
+**
+** Description      Callback function for hal write response timer.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void hal_write_rsp_timeout_cb(uint32_t timerId, void *pContext)
+{
+    UNUSED(timerId);
+    NXPLOG_NCIHAL_E("hal_write_rsp_timeout_cb - write timeout!!!");
+    hal_write_timer_fired = 1;
+    hal_read_cb(pContext,NULL);
+}
+
+/*******************************************************************************
+**
+** Function         hal_write_cb
+**
+** Description      Callback function for hal write.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void hal_write_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+
+    if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("write successful status = 0x%x", pInfo->wStatus);
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("write error status = 0x%x", pInfo->wStatus);
+    }
+
+    p_cb_data->status = pInfo->wStatus;
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         hal_read_cb
+**
+** Description      Callback function for hal read.
+**
+** Returns          None
+**
+*******************************************************************************/
+static void hal_read_cb(void *pContext, phTmlNfc_TransactInfo_t *pInfo)
+{
+    phNxpNciHal_Sem_t *p_cb_data = (phNxpNciHal_Sem_t*) pContext;
+    NFCSTATUS status;
+    if(hal_write_timer_fired == 1)
+    {
+        NXPLOG_NCIHAL_D("hal_read_cb - response timeout occurred");
+
+        hal_write_timer_fired = 0;
+        p_cb_data->status = NFCSTATUS_RESPONSE_TIMEOUT;
+        status = phTmlNfc_ReadAbort();
+    }
+    else
+    {
+        NFCSTATUS status = phOsalNfc_Timer_Stop(timeoutTimerId);
+
+        if (NFCSTATUS_SUCCESS == status)
+        {
+            NXPLOG_NCIHAL_D("Response timer stopped");
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
+            p_cb_data->status  = NFCSTATUS_FAILED;
+        }
+
+        if (pInfo->wStatus == NFCSTATUS_SUCCESS)
+        {
+            NXPLOG_NCIHAL_D("hal_read_cb successful status = 0x%x", pInfo->wStatus);
+            p_cb_data->status = NFCSTATUS_SUCCESS;
+        }
+        else
+        {
+            NXPLOG_NCIHAL_E("hal_read_cb error status = 0x%x", pInfo->wStatus);
+            p_cb_data->status = NFCSTATUS_FAILED;
+        }
+
+        p_cb_data->status = pInfo->wStatus;
+
+        nci_test_data_t *test_data = (nci_test_data_t*) p_cb_data->pContext;
+
+        if(test_data->exp_rsp.len == 0)
+        {
+            /* Compare the actual notification with expected notification.*/
+            if( test_data->ntf_validator(&(test_data->exp_ntf),pInfo) == 1 )
+            {
+                p_cb_data->status = NFCSTATUS_SUCCESS;
+            }
+            else
+            {
+                p_cb_data->status = NFCSTATUS_FAILED;
+
+            }
+        }
+
+        /* Compare the actual response with expected response.*/
+        else if( test_data->rsp_validator(&(test_data->exp_rsp),pInfo) == 1)
+        {
+            p_cb_data->status = NFCSTATUS_SUCCESS;
+        }
+        else
+        {
+            p_cb_data->status = NFCSTATUS_FAILED;
+        }
+        test_data->exp_rsp.len = 0;
+    }
+
+    SEM_POST(p_cb_data);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_test_rx_thread
+**
+** Description      Thread to fetch and process messages from message queue.
+**
+** Returns          NULL
+**
+*******************************************************************************/
+static void *phNxpNciHal_test_rx_thread(void *arg)
+{
+    phLibNfc_Message_t msg;
+    UNUSED(arg);
+    NXPLOG_NCIHAL_D("Self test thread started");
+
+    thread_running = 1;
+
+    while (thread_running == 1)
+    {
+        /* Fetch next message from the NFC stack message queue */
+        if (phDal4Nfc_msgrcv(gDrvCfg.nClientId,
+                &msg, 0, 0) == -1)
+        {
+            NXPLOG_NCIHAL_E("Received bad message");
+            continue;
+        }
+
+        if(thread_running == 0)
+        {
+            break;
+        }
+
+        switch (msg.eMsgType)
+        {
+            case PH_LIBNFC_DEFERREDCALL_MSG:
+            {
+                phLibNfc_DeferredCall_t *deferCall =
+                        (phLibNfc_DeferredCall_t *) (msg.pMsgData);
+
+                REENTRANCE_LOCK();
+                deferCall->pCallback(deferCall->pParameter);
+                REENTRANCE_UNLOCK();
+
+                break;
+            }
+        }
+    }
+
+    NXPLOG_NCIHAL_D("Self test thread stopped");
+
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_readLocked
+**
+** Description      Reads response and notification from NFCC and waits for
+**                  read completion, for a definitive timeout value.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED,
+**                  NFCSTATUS_RESPONSE_TIMEOUT in case of timeout.
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_readLocked(nci_test_data_t *pData )
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    phNxpNciHal_Sem_t cb_data;
+    uint16_t read_len = 16;
+    /* RX Buffer */
+    uint32_t rx_data[NCI_MAX_DATA_LEN];
+
+    /* Create the local semaphore */
+    if (phNxpNciHal_init_cb_data(&cb_data, pData) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phTmlNfc_Read Create cb data failed");
+        status = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* call read pending */
+    status = phTmlNfc_Read(
+            (uint8_t *) rx_data,
+            (uint16_t) read_len,
+            (pphTmlNfc_TransactCompletionCb_t) &hal_read_cb,
+            &cb_data);
+
+    if (status != NFCSTATUS_PENDING)
+    {
+        NXPLOG_NCIHAL_E("TML Read status error status = %x", status);
+        status = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    status = phOsalNfc_Timer_Start(timeoutTimerId,
+            HAL_WRITE_RSP_TIMEOUT,
+            &hal_write_rsp_timeout_cb,
+            &cb_data);
+
+    if (NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_NCIHAL_D("Response timer started");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("Response timer not started");
+        status = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_NCIHAL_E("phTmlNfc_Read semaphore error");
+        status = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if(cb_data.status == NFCSTATUS_RESPONSE_TIMEOUT)
+    {
+        NXPLOG_NCIHAL_E("Response timeout!!!");
+        status = NFCSTATUS_RESPONSE_TIMEOUT;
+        goto clean_and_return;
+
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("phTmlNfc_Read failed  ");
+        status = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_writeLocked
+**
+** Description      Send command to NFCC and waits for cmd write completion, for
+**                  a definitive timeout value.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED,
+**                  NFCSTATUS_RESPONSE_TIMEOUT in case of timeout.
+**
+*******************************************************************************/
+static NFCSTATUS phNxpNciHal_writeLocked(nci_test_data_t *pData )
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    phNxpNciHal_Sem_t cb_data;
+    int retryCnt = 0;
+
+    /* Create the local semaphore */
+    if (phNxpNciHal_init_cb_data(&cb_data, NULL) != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phTmlNfc_Write Create cb data failed");
+        goto clean_and_return;
+    }
+
+retry:
+    status = phTmlNfc_Write(pData->cmd.p_data, pData->cmd.len,
+            (pphTmlNfc_TransactCompletionCb_t) &hal_write_cb, &cb_data);
+
+    if (status != NFCSTATUS_PENDING)
+    {
+        NXPLOG_NCIHAL_E("phTmlNfc_Write status error");
+        goto clean_and_return;
+    }
+
+    /* Wait for callback response */
+    if (SEM_WAIT(cb_data))
+    {
+        NXPLOG_NCIHAL_E("write_unlocked semaphore error");
+        status = NFCSTATUS_FAILED;
+        goto clean_and_return;
+    }
+
+    if (cb_data.status != NFCSTATUS_SUCCESS && retryCnt < HAL_WRITE_MAX_RETRY)
+    {
+        retryCnt++;
+        NXPLOG_NCIHAL_E("write_unlocked failed - PN54X Maybe in Standby Mode - Retry %d",retryCnt);
+        goto retry;
+    }
+
+    status = cb_data.status;
+
+clean_and_return:
+    phNxpNciHal_cleanup_cb_data(&cb_data);
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_performTest
+**
+** Description      Performs a single cycle of command,response and
+**                  notification.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED,
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_performTest(nci_test_data_t *pData )
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    if(NULL == pData)
+    {
+        return NFCSTATUS_FAILED;
+    }
+
+    CONCURRENCY_LOCK();
+
+    status = phNxpNciHal_writeLocked(pData);
+
+    if(status == NFCSTATUS_RESPONSE_TIMEOUT)
+    {
+        goto clean_and_return;
+    }
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        goto clean_and_return;
+    }
+
+    status = phNxpNciHal_readLocked(pData);
+
+    if(status != NFCSTATUS_SUCCESS)
+    {
+        goto clean_and_return;
+    }
+
+    if(0 != pData->exp_ntf.len)
+    {
+        status = phNxpNciHal_readLocked(pData);
+
+        if(status != NFCSTATUS_SUCCESS)
+        {
+            goto clean_and_return;
+        }
+    }
+
+clean_and_return:
+    CONCURRENCY_UNLOCK();
+    return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_TestMode_open
+ **
+ ** Description      It opens the physical connection with NFCC (PN54X) and
+ **                  creates required client thread for operation.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+NFCSTATUS phNxpNciHal_TestMode_open (void)
+{
+    /* Thread */
+    pthread_t test_rx_thread;
+
+    phOsalNfc_Config_t tOsalConfig;
+    phTmlNfc_Config_t tTmlConfig;
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    uint16_t read_len = 255;
+
+    /* initialize trace level */
+    phNxpLog_InitializeLogLevel();
+
+    if (phNxpNciHal_init_monitor() == NULL)
+    {
+        NXPLOG_NCIHAL_E("Init monitor failed");
+        return NFCSTATUS_FAILED;
+    }
+
+    CONCURRENCY_LOCK();
+
+    memset(&tOsalConfig, 0x00, sizeof(tOsalConfig));
+    memset(&tTmlConfig, 0x00, sizeof(tTmlConfig));
+
+    gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
+    gDrvCfg.nLinkType = ENUM_LINK_TYPE_I2C;/* For PN54X */
+    tTmlConfig.pDevName = (int8_t *) "/dev/pn54x";
+    tOsalConfig.dwCallbackThreadId = (uintptr_t) gDrvCfg.nClientId;
+    tOsalConfig.pLogFile = NULL;
+    tTmlConfig.dwGetMsgThreadId = (uintptr_t) gDrvCfg.nClientId;
+    nxpncihal_ctrl.gDrvCfg.nClientId = (uintptr_t) gDrvCfg.nClientId;
+
+    /* Initialize TML layer */
+    status = phTmlNfc_Init(&tTmlConfig);
+    if (status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_E("phTmlNfc_Init Failed");
+        goto clean_and_return;
+    }
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    if (pthread_create(&test_rx_thread, &attr,
+            phNxpNciHal_test_rx_thread, NULL) != 0)
+    {
+        NXPLOG_NCIHAL_E("pthread_create failed");
+        phTmlNfc_Shutdown();
+        goto clean_and_return;
+    }
+
+    timeoutTimerId = phOsalNfc_Timer_Create();
+
+    if(timeoutTimerId == 0xFFFF)
+    {
+        NXPLOG_NCIHAL_E("phOsalNfc_Timer_Create failed");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phOsalNfc_Timer_Create SUCCESS");
+    }
+    CONCURRENCY_UNLOCK();
+
+    return NFCSTATUS_SUCCESS;
+
+clean_and_return:
+    CONCURRENCY_UNLOCK();
+    phNxpNciHal_cleanup_monitor();
+    return NFCSTATUS_FAILED;
+}
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_TestMode_close
+ **
+ ** Description      This function close the NFCC interface and free all
+ **                  resources.
+ **
+ ** Returns          None.
+ **
+ *******************************************************************************/
+
+void phNxpNciHal_TestMode_close ()
+{
+
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    CONCURRENCY_LOCK();
+
+    if (NULL != gpphTmlNfc_Context->pDevHandle)
+    {
+        /* Abort any pending read and write */
+        status = phTmlNfc_ReadAbort();
+        status = phTmlNfc_WriteAbort();
+
+        phOsalNfc_Timer_Cleanup();
+
+        status = phTmlNfc_Shutdown();
+
+        NXPLOG_NCIHAL_D("phNxpNciHal_close return status = %d", status);
+
+        thread_running = 0;
+
+        phDal4Nfc_msgrelease(gDrvCfg.nClientId);
+
+        status = phOsalNfc_Timer_Delete(timeoutTimerId);
+    }
+
+    CONCURRENCY_UNLOCK();
+
+    phNxpNciHal_cleanup_monitor();
+
+    /* Return success always */
+    return;
+}
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_SwpTest
+ **
+ ** Description      Test function to validate the SWP line. SWP line number is
+ **                  is sent as parameter to the API.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_SwpTest(uint8_t swp_line)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    int len = 0;
+    int cnt = 0;
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - start\n");
+
+    if(swp_line == 0x01)
+    {
+        len = (sizeof(swp1_test_data)/sizeof(swp1_test_data[0]));
+
+        for(cnt = 0; cnt < len; cnt++)
+        {
+            status = phNxpNciHal_performTest(&(swp1_test_data[cnt]));
+            if(status == NFCSTATUS_RESPONSE_TIMEOUT ||
+                    status == NFCSTATUS_FAILED
+            )
+            {
+                break;
+            }
+        }
+    }
+    else if(swp_line == 0x02)
+    {
+        len = (sizeof(swp2_test_data)/sizeof(swp2_test_data[0]));
+
+        for(cnt = 0; cnt < len; cnt++)
+        {
+            status = phNxpNciHal_performTest(&(swp2_test_data[cnt]));
+            if(status == NFCSTATUS_RESPONSE_TIMEOUT ||
+                    status == NFCSTATUS_FAILED
+            )
+            {
+                break;
+            }
+        }
+    }
+    else
+    {
+        status = NFCSTATUS_FAILED;
+    }
+
+    if( status == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - SUCCESSS\n");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - FAILED\n");
+    }
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_SwpTest - end\n");
+
+    return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_PrbsTestStart
+ **
+ ** Description      Test function start RF generation for RF technology and bit
+ **                  rate. RF technology and bit rate are sent as parameter to
+ **                  the API.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if RF generation successful,
+ **                  otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+        phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate)
+#else
+NFCSTATUS phNxpNciHal_PrbsTestStart (phNxpNfc_Tech_t tech, phNxpNfc_Bitrate_t bitrate)
+#endif
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    nci_test_data_t prbs_cmd_data;
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00};
+    prbs_cmd_data.cmd.len = 0x09;
+#else
+    uint8_t rsp_cmd_info[] = {0x4F, 0x30, 0x01, 0x00};
+    prbs_cmd_data.cmd.len = 0x07;
+#endif
+
+    memcpy(prbs_cmd_data.exp_rsp.p_data, &rsp_cmd_info[0], sizeof(rsp_cmd_info));
+    prbs_cmd_data.exp_rsp.len = sizeof(rsp_cmd_info);
+
+    //prbs_cmd_data.exp_rsp.len = 0x00;
+    prbs_cmd_data.exp_ntf.len = 0x00;
+    prbs_cmd_data.rsp_validator = st_validator_testEquals;
+    prbs_cmd_data.ntf_validator = st_validator_null;
+
+    uint8_t len = 0;
+    uint8_t cnt = 0;
+
+//    [NCI] -> [0x2F 0x30 0x04 0x00 0x00 0x01 0xFF]
+
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    status = phNxpNciHal_getPrbsCmd(prbs_type, hw_prbs_type, tech, bitrate,
+            prbs_cmd_data.cmd.p_data,prbs_cmd_data.cmd.len);
+#else
+    status = phNxpNciHal_getPrbsCmd(tech, bitrate,prbs_cmd_data.cmd.p_data,prbs_cmd_data.cmd.len);
+#endif
+
+    if( status == NFCSTATUS_FAILED)
+    {
+        //Invalid Param.
+        NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - INVALID_PARAM\n");
+
+        goto clean_and_return;
+    }
+
+    len = (sizeof(prbs_test_data)/sizeof(prbs_test_data[0]));
+
+    for(cnt = 0; cnt < len; cnt++)
+    {
+        status = phNxpNciHal_performTest(&(prbs_test_data[cnt]));
+        if(status == NFCSTATUS_RESPONSE_TIMEOUT ||
+                status == NFCSTATUS_FAILED
+        )
+        {
+            break;
+        }
+    }
+
+    /* Ignoring status, as there will be no response - Applicable till FW version 8.1.1*/
+    status = phNxpNciHal_performTest(&prbs_cmd_data);
+    clean_and_return:
+
+    if( status == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - SUCCESSS\n");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - FAILED\n");
+    }
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStart - end\n");
+
+    return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_PrbsTestStop
+ **
+ ** Description      Test function stop RF generation for RF technology started
+ **                  by phNxpNciHal_PrbsTestStart.
+ **
+ ** Returns          NFCSTATUS_SUCCESS if operation successful,
+ **                  otherwise NFCSTATUS_FAILED.
+ **
+ *******************************************************************************/
+
+NFCSTATUS phNxpNciHal_PrbsTestStop ()
+{
+    NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - Start\n");
+
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+
+    status = phTmlNfc_IoCtl(phTmlNfc_e_ResetDevice);
+
+    if(NFCSTATUS_SUCCESS == status)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - SUCCESS\n");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - FAILED\n");
+
+    }
+    NXPLOG_NCIHAL_D("phNxpNciHal_PrbsTestStop - end\n");
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_getPrbsCmd
+**
+** Description      Test function frames the PRBS command.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+NFCSTATUS phNxpNciHal_getPrbsCmd (phNxpNfc_PrbsType_t prbs_type, phNxpNfc_PrbsHwType_t hw_prbs_type,
+        uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len)
+#else
+NFCSTATUS phNxpNciHal_getPrbsCmd (uint8_t tech, uint8_t bitrate, uint8_t *prbs_cmd, uint8_t prbs_cmd_len)
+#endif
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    int position_tech_param = 0;
+    int position_bit_param = 0;
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - tech 0x%x bitrate = 0x%x", tech, bitrate);
+    if(NULL == prbs_cmd ||
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+            prbs_cmd_len != 0x09)
+#else
+            prbs_cmd_len != 0x07)
+#endif
+    {
+        return status;
+    }
+
+    prbs_cmd[0] = 0x2F;
+    prbs_cmd[1] = 0x30;
+#if(NFC_NXP_CHIP_TYPE != PN547C2)
+    prbs_cmd[2] = 0x06;
+    prbs_cmd[3] = (uint8_t)prbs_type;
+    //0xFF Error value used for validation.
+    prbs_cmd[4] = (uint8_t)hw_prbs_type;
+    prbs_cmd[5] = 0xFF;//TECH
+    prbs_cmd[6] = 0xFF;//BITRATE
+    prbs_cmd[7] = 0x01;
+    prbs_cmd[8] = 0xFF;
+    position_tech_param = 5;
+    position_bit_param = 6;
+#else
+    prbs_cmd[2] = 0x04;
+    //0xFF Error value used for validation.
+    prbs_cmd[3] = 0xFF;//TECH
+    //0xFF Error value used for validation.
+    prbs_cmd[4] = 0xFF;//BITRATE
+    prbs_cmd[5] = 0x01;
+    prbs_cmd[6] = 0xFF;
+    position_tech_param = 3;
+    position_bit_param = 4;
+#endif
+
+    switch (tech) {
+        case NFC_RF_TECHNOLOGY_A:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_A");
+            prbs_cmd[position_tech_param] = 0x00;
+            break;
+        case NFC_RF_TECHNOLOGY_B:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_B");
+            prbs_cmd[position_tech_param] = 0x01;
+            break;
+        case NFC_RF_TECHNOLOGY_F:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_RF_TECHNOLOGY_F");
+            prbs_cmd[position_tech_param] = 0x02;
+            break;
+        default:
+            break;
+    }
+
+    switch (bitrate)
+    {
+        case NFC_BIT_RATE_106:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_106");
+            if(prbs_cmd[position_tech_param] != 0x02)
+            {
+                prbs_cmd[position_bit_param] = 0x00;
+            }
+            break;
+        case NFC_BIT_RATE_212:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_212");
+            prbs_cmd[position_bit_param] = 0x01;
+            break;
+        case NFC_BIT_RATE_424:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_424");
+            prbs_cmd[position_bit_param] = 0x02;
+            break;
+        case NFC_BIT_RATE_848:
+            NXPLOG_NCIHAL_D("phNxpNciHal_getPrbsCmd - NFC_BIT_RATE_848");
+            if(prbs_cmd[position_tech_param] != 0x02)
+            {
+                prbs_cmd[position_bit_param] = 0x03;
+            }
+            break;
+        default:
+            break;
+    }
+
+    if(prbs_cmd[position_tech_param] == 0xFF || prbs_cmd[position_bit_param] == 0xFF)
+    {
+        //Invalid Param.
+        status = NFCSTATUS_FAILED;
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_RfFieldTest
+**
+** Description      Test function performs RF filed test.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_RfFieldTest (uint8_t on)
+{
+    NFCSTATUS status = NFCSTATUS_SUCCESS;
+    int len = 0;
+    int cnt = 0;
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - start %x\n",on);
+
+    if(on == 0x01)
+    {
+        len = (sizeof(rf_field_on_test_data)/sizeof(rf_field_on_test_data[0]));
+
+        for(cnt = 0; cnt < len; cnt++)
+        {
+            status = phNxpNciHal_performTest(&(rf_field_on_test_data[cnt]));
+            if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+            {
+                break;
+            }
+        }
+    }
+    else if(on == 0x00)
+    {
+        len = (sizeof(rf_field_off_test_data)/sizeof(rf_field_off_test_data[0]));
+
+        for(cnt = 0; cnt < len; cnt++)
+        {
+            status = phNxpNciHal_performTest(&(rf_field_off_test_data[cnt]));
+            if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+            {
+                break;
+            }
+        }
+    }
+    else
+    {
+        status = NFCSTATUS_FAILED;
+    }
+
+    if( status == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - SUCCESSS\n");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - FAILED\n");
+    }
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_RfFieldTest - end\n");
+
+    return status;
+}
+
+/*******************************************************************************
+ **
+ ** Function         phNxpNciHal_AntennaTest
+ **
+ ** Description
+ **
+ ** Returns
+ **
+ *******************************************************************************/
+NFCSTATUS phNxpNciHal_AntennaTest ()
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_DownloadPinTest
+**
+** Description      Test function to validate the FW download pin connection.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_DownloadPinTest(void)
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    int len = 0;
+    int cnt = 0;
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - start\n");
+
+    len = (sizeof(download_pin_test_data1)/sizeof(download_pin_test_data1[0]));
+
+    for(cnt = 0; cnt < len; cnt++)
+    {
+        status = phNxpNciHal_performTest(&(download_pin_test_data1[cnt]));
+        if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+        {
+            break;
+        }
+    }
+
+    if (status != NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n");
+        return status;
+    }
+
+    status = NFCSTATUS_FAILED;
+    status = phTmlNfc_IoCtl(phTmlNfc_e_EnableDownloadMode);
+    if (NFCSTATUS_SUCCESS != status)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n");
+        return status;
+    }
+
+    status = NFCSTATUS_FAILED;
+    len = (sizeof(download_pin_test_data2)/sizeof(download_pin_test_data2[0]));
+
+     for(cnt = 0; cnt < len; cnt++)
+     {
+         status = phNxpNciHal_performTest(&(download_pin_test_data2[cnt]));
+         if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+         {
+             break;
+         }
+     }
+
+    if( status == NFCSTATUS_SUCCESS)
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - SUCCESSS\n");
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - FAILED\n");
+    }
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_DownloadPinTest - end\n");
+
+    return status;
+}
+/*******************************************************************************
+**
+** Function         phNxpNciHal_AntennaSelfTest
+**
+** Description      Test function to validate the Antenna's discrete
+**                  components connection.
+**
+** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
+**
+*******************************************************************************/
+NFCSTATUS phNxpNciHal_AntennaSelfTest(phAntenna_St_Resp_t * phAntenna_St_Resp )
+{
+    NFCSTATUS status = NFCSTATUS_FAILED;
+    NFCSTATUS antenna_st_status = NFCSTATUS_FAILED;
+    int len = 0;
+    int cnt = 0;
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - start\n");
+    memcpy(&phAntenna_resp, phAntenna_St_Resp, sizeof(phAntenna_St_Resp_t));
+    len = (sizeof(antenna_self_test_data)/sizeof(antenna_self_test_data[0]));
+
+    for(cnt = 0; cnt < len; cnt++)
+    {
+        status = phNxpNciHal_performTest(&(antenna_self_test_data[cnt]));
+        if(status == NFCSTATUS_RESPONSE_TIMEOUT || status == NFCSTATUS_FAILED)
+        {
+            NXPLOG_NCIHAL_E("phNxpNciHal_AntennaSelfTest: commnad execution - FAILED\n");
+            break;
+        }
+    }
+
+    if(status == NFCSTATUS_SUCCESS)
+    {
+        if((gtxldo_status == NFCSTATUS_SUCCESS) && (gagc_value_status == NFCSTATUS_SUCCESS) &&
+           (gagc_nfcld_status == NFCSTATUS_SUCCESS) && (gagc_differential_status == NFCSTATUS_SUCCESS))
+        {
+            antenna_st_status = NFCSTATUS_SUCCESS;
+            NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - SUCESS\n");
+        }
+        else
+        {
+            NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n");
+        }
+    }
+    else
+    {
+        NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - FAILED\n");
+    }
+
+    NXPLOG_NCIHAL_D("phNxpNciHal_AntennaSelfTest - end\n");
+
+    return antenna_st_status;
+}
+
+#endif /*#ifdef NXP_HW_SELF_TEST*/
diff --git a/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c
new file mode 100644
index 0000000..e19eaca
--- /dev/null
+++ b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * DAL independent message queue implementation for Android (can be used under Linux too)
+ */
+
+#include <pthread.h>
+#include <phNxpLog.h>
+#include <linux/ipc.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <phDal4Nfc_messageQueueLib.h>
+
+
+typedef struct phDal4Nfc_message_queue_item
+{
+    phLibNfc_Message_t nMsg;
+    struct phDal4Nfc_message_queue_item * pPrev;
+    struct phDal4Nfc_message_queue_item * pNext;
+} phDal4Nfc_message_queue_item_t;
+
+typedef struct phDal4Nfc_message_queue
+{
+    phDal4Nfc_message_queue_item_t * pItems;
+    pthread_mutex_t nCriticalSectionMutex;
+    sem_t nProcessSemaphore;
+
+} phDal4Nfc_message_queue_t;
+
+/*******************************************************************************
+**
+** Function         phDal4Nfc_msgget
+**
+** Description      Allocates message queue
+**
+** Parameters       Ignored, included only for Linux queue API compatibility
+**
+** Returns          (int) value of pQueue if successful
+**                  -1, if failed to allocate memory or to init mutex
+**
+*******************************************************************************/
+intptr_t phDal4Nfc_msgget(key_t key, int msgflg)
+{
+    phDal4Nfc_message_queue_t * pQueue;
+    UNUSED(key);
+    UNUSED(msgflg);
+    pQueue = (phDal4Nfc_message_queue_t *) malloc(sizeof(phDal4Nfc_message_queue_t));
+    if (pQueue == NULL)
+        return -1;
+    memset(pQueue, 0, sizeof(phDal4Nfc_message_queue_t));
+    if (pthread_mutex_init(&pQueue->nCriticalSectionMutex, NULL) == -1)
+    {
+        free (pQueue);
+        return -1;
+    }
+    if (sem_init(&pQueue->nProcessSemaphore, 0, 0) == -1)
+    {
+        free (pQueue);
+        return -1;
+    }
+
+    return ((intptr_t) pQueue);
+}
+
+/*******************************************************************************
+**
+** Function         phDal4Nfc_msgrelease
+**
+** Description      Releases message queue
+**
+** Parameters       msqid - message queue handle
+**
+** Returns          None
+**
+*******************************************************************************/
+void phDal4Nfc_msgrelease(intptr_t msqid)
+{
+    phDal4Nfc_message_queue_t * pQueue = (phDal4Nfc_message_queue_t*)msqid;
+
+    if(pQueue != NULL)
+    {
+        sem_post(&pQueue->nProcessSemaphore);
+        usleep(300000);
+        if (sem_destroy(&pQueue->nProcessSemaphore))
+        {
+            NXPLOG_TML_E("Failed to destroy semaphore (errno=0x%08x)", errno);
+        }
+        pthread_mutex_destroy (&pQueue->nCriticalSectionMutex);
+
+        free(pQueue);
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phDal4Nfc_msgctl
+**
+** Description      Destroys message queue
+**
+** Parameters       msqid - message queue handle
+**                  cmd, buf - ignored, included only for Linux queue API compatibility
+**
+** Returns          0,  if successful
+**                  -1, if invalid handle is passed
+**
+*******************************************************************************/
+int phDal4Nfc_msgctl(intptr_t msqid, int cmd, void *buf)
+{
+    phDal4Nfc_message_queue_t * pQueue;
+    phDal4Nfc_message_queue_item_t * p;
+    UNUSED(cmd);
+    UNUSED(buf);
+    if (msqid == 0)
+        return -1;
+
+    pQueue = (phDal4Nfc_message_queue_t *) msqid;
+    pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
+    if (pQueue->pItems != NULL)
+    {
+        p = pQueue->pItems;
+        while (p->pNext != NULL)
+        {
+            p = p->pNext;
+        }
+        while (p->pPrev != NULL)
+        {
+            p = p->pPrev;
+            free(p->pNext);
+            p->pNext = NULL;
+        }
+        free(p);
+    }
+    pQueue->pItems = NULL;
+    pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
+    pthread_mutex_destroy(&pQueue->nCriticalSectionMutex);
+    free(pQueue);
+
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function         phDal4Nfc_msgsnd
+**
+** Description      Sends a message to the queue. The message will be added at the end of
+**                  the queue as appropriate for FIFO policy
+**
+** Parameters       msqid  - message queue handle
+**                  msgp   - message to be sent
+**                  msgsz  - message size
+**                  msgflg - ignored
+**
+** Returns          0,  if successful
+**                  -1, if invalid parameter passed or failed to allocate memory
+**
+*******************************************************************************/
+intptr_t phDal4Nfc_msgsnd(intptr_t msqid, phLibNfc_Message_t * msg, int msgflg)
+{
+    phDal4Nfc_message_queue_t * pQueue;
+    phDal4Nfc_message_queue_item_t * p;
+    phDal4Nfc_message_queue_item_t * pNew;
+    UNUSED(msgflg);
+    if ((msqid == 0) || (msg == NULL) )
+        return -1;
+
+
+    pQueue = (phDal4Nfc_message_queue_t *) msqid;
+    pNew = (phDal4Nfc_message_queue_item_t *) malloc(sizeof(phDal4Nfc_message_queue_item_t));
+    if (pNew == NULL)
+        return -1;
+    memset(pNew, 0, sizeof(phDal4Nfc_message_queue_item_t));
+    memcpy(&pNew->nMsg, msg, sizeof(phLibNfc_Message_t));
+    pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
+
+    if (pQueue->pItems != NULL)
+    {
+        p = pQueue->pItems;
+        while (p->pNext != NULL)
+        {
+            p = p->pNext;
+        }
+        p->pNext = pNew;
+        pNew->pPrev = p;
+    }
+    else
+    {
+        pQueue->pItems = pNew;
+    }
+    pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
+
+    sem_post(&pQueue->nProcessSemaphore);
+
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function         phDal4Nfc_msgrcv
+**
+** Description      Gets the oldest message from the queue.
+**                  If the queue is empty the function waits (blocks on a mutex)
+**                  until a message is posted to the queue with phDal4Nfc_msgsnd.
+**
+** Parameters       msqid  - message queue handle
+**                  msgp   - message to be received
+**                  msgsz  - message size
+**                  msgtyp - ignored
+**                  msgflg - ignored
+**
+** Returns          0,  if successful
+**                  -1, if invalid parameter passed
+**
+*******************************************************************************/
+int phDal4Nfc_msgrcv(intptr_t msqid, phLibNfc_Message_t * msg, long msgtyp, int msgflg)
+{
+    phDal4Nfc_message_queue_t * pQueue;
+    phDal4Nfc_message_queue_item_t * p;
+    UNUSED(msgflg);
+    UNUSED(msgtyp);
+    if ((msqid == 0) || (msg == NULL))
+        return -1;
+
+    pQueue = (phDal4Nfc_message_queue_t *) msqid;
+
+    sem_wait(&pQueue->nProcessSemaphore);
+
+    pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
+
+    if (pQueue->pItems != NULL)
+    {
+        memcpy(msg, &(pQueue->pItems)->nMsg, sizeof(phLibNfc_Message_t));
+        p = pQueue->pItems->pNext;
+        free(pQueue->pItems);
+        pQueue->pItems = p;
+    }
+    pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
+
+    return 0;
+}
diff --git a/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h
new file mode 100644
index 0000000..e121223
--- /dev/null
+++ b/halimpl/pn54x/tml/phDal4Nfc_messageQueueLib.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * DAL independent message queue implementation for Android
+ */
+
+#ifndef PHDAL4NFC_MESSAGEQUEUE_H
+#define PHDAL4NFC_MESSAGEQUEUE_H
+
+#include <linux/ipc.h>
+#include <phNfcTypes.h>
+
+intptr_t phDal4Nfc_msgget(key_t key, int msgflg);
+void phDal4Nfc_msgrelease(intptr_t msqid);
+int phDal4Nfc_msgctl(intptr_t msqid, int cmd, void *buf);
+intptr_t phDal4Nfc_msgsnd(intptr_t msqid, phLibNfc_Message_t * msg, int msgflg);
+int phDal4Nfc_msgrcv(intptr_t msqid, phLibNfc_Message_t * msg, long msgtyp, int msgflg);
+
+#endif /*  PHDAL4NFC_MESSAGEQUEUE_H  */
diff --git a/halimpl/pn54x/tml/phOsalNfc_Timer.c b/halimpl/pn54x/tml/phOsalNfc_Timer.c
new file mode 100644
index 0000000..bdd4cba
--- /dev/null
+++ b/halimpl/pn54x/tml/phOsalNfc_Timer.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * OSAL Implementation for Timers.
+ */
+
+#include <signal.h>
+#include <phNfcTypes.h>
+#include <phOsalNfc_Timer.h>
+#include <phNfcCommon.h>
+#include <phNxpNciHal.h>
+#include <phNxpLog.h>
+
+#define PH_NFC_MAX_TIMER (5U)
+static phOsalNfc_TimerHandle_t         apTimerInfo[PH_NFC_MAX_TIMER];
+
+extern phNxpNciHal_Control_t nxpncihal_ctrl;
+
+
+/*
+ * Defines the base address for generating timerid.
+ */
+#define PH_NFC_TIMER_BASE_ADDRESS                   (100U)
+
+/*
+ *  Defines the value for invalid timerid returned during timeSetEvent
+ */
+#define PH_NFC_TIMER_ID_ZERO                        (0x00)
+
+
+/*
+ * Invalid timer ID type. This ID used indicate timer creation is failed */
+#define PH_NFC_TIMER_ID_INVALID                     (0xFFFF)
+
+/* Forward declarations */
+static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg);
+static void phOsalNfc_DeferredCall (void *pParams);
+static void phOsalNfc_Timer_Expired(union sigval sv);
+
+/*
+ *************************** Function Definitions ******************************
+ */
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_Timer_Create
+**
+** Description      Creates a timer which shall call back the specified function when the timer expires
+**                  Fails if OSAL module is not initialized or timers are already occupied
+**
+** Parameters       None
+**
+** Returns          TimerId
+**                  TimerId value of PH_OSALNFC_TIMER_ID_INVALID indicates that timer is not created                -
+**
+*******************************************************************************/
+uint32_t phOsalNfc_Timer_Create(void)
+{
+    /* dwTimerId is also used as an index at which timer object can be stored */
+    uint32_t dwTimerId = PH_OSALNFC_TIMER_ID_INVALID;
+    static struct sigevent se;
+    phOsalNfc_TimerHandle_t *pTimerHandle;
+    /* Timer needs to be initialized for timer usage */
+
+        se.sigev_notify = SIGEV_THREAD;
+        se.sigev_notify_function = phOsalNfc_Timer_Expired;
+        se.sigev_notify_attributes = NULL;
+        dwTimerId = phUtilNfc_CheckForAvailableTimer();
+
+        /* Check whether timers are available, if yes create a timer handle structure */
+        if( (PH_NFC_TIMER_ID_ZERO != dwTimerId) && (dwTimerId <= PH_NFC_MAX_TIMER) )
+        {
+            pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwTimerId-1];
+            /* Build the Timer Id to be returned to Caller Function */
+            dwTimerId += PH_NFC_TIMER_BASE_ADDRESS;
+            se.sigev_value.sival_int = (int)dwTimerId;
+            /* Create POSIX timer */
+            if(timer_create(CLOCK_REALTIME, &se, &(pTimerHandle->hTimerHandle)) == -1)
+            {
+                dwTimerId = PH_NFC_TIMER_ID_INVALID;
+            }
+            else
+            {
+                /* Set the state to indicate timer is ready */
+                pTimerHandle->eState = eTimerIdle;
+                /* Store the Timer Id which shall act as flag during check for timer availability */
+                pTimerHandle->TimerId = dwTimerId;
+            }
+        }
+        else
+        {
+            dwTimerId = PH_NFC_TIMER_ID_INVALID;
+        }
+
+    /* Timer ID invalid can be due to Uninitialized state,Non availability of Timer */
+    return dwTimerId;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_Timer_Start
+**
+** Description      Starts the requested, already created, timer
+**                  If the timer is already running, timer stops and restarts with the new timeout value
+**                  and new callback function in case any ??????
+**                  Creates a timer which shall call back the specified function when the timer expires
+**
+** Parameters       dwTimerId             - valid timer ID obtained during timer creation
+**                  dwRegTimeCnt          - requested timeout in milliseconds
+**                  pApplication_callback - application callback interface to be called when timer expires
+**                  pContext              - caller context, to be passed to the application callback function
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS            - the operation was successful
+**                  NFCSTATUS_NOT_INITIALISED    - OSAL Module is not initialized
+**                  NFCSTATUS_INVALID_PARAMETER  - invalid parameter passed to the function
+**                  PH_OSALNFC_TIMER_START_ERROR - timer could not be created due to system error
+**
+*******************************************************************************/
+NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, pphOsalNfc_TimerCallbck_t pApplication_callback, void *pContext)
+{
+    NFCSTATUS wStartStatus= NFCSTATUS_SUCCESS;
+
+    struct itimerspec its;
+    uint32_t dwIndex;
+    phOsalNfc_TimerHandle_t *pTimerHandle;
+    /* Retrieve the index at which the timer handle structure is stored */
+    dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
+    pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
+    /* OSAL Module needs to be initialized for timer usage */
+        /* Check whether the handle provided by user is valid */
+        if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
+                (NULL != pApplication_callback) )
+        {
+            its.it_interval.tv_sec  = 0;
+            its.it_interval.tv_nsec = 0;
+            its.it_value.tv_sec     = dwRegTimeCnt / 1000;
+            its.it_value.tv_nsec    = 1000000 * (dwRegTimeCnt % 1000);
+            if(its.it_value.tv_sec == 0 && its.it_value.tv_nsec == 0)
+            {
+                /* This would inadvertently stop the timer*/
+                its.it_value.tv_nsec = 1;
+            }
+            pTimerHandle->Application_callback = pApplication_callback;
+            pTimerHandle->pContext = pContext;
+            pTimerHandle->eState = eTimerRunning;
+            /* Arm the timer */
+            if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
+            {
+                wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_START_ERROR);
+            }
+        }
+        else
+        {
+            wStartStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
+        }
+
+    return wStartStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_Timer_Stop
+**
+** Description      Stops already started timer
+**                  Allows to stop running timer. In case timer is stopped, timer callback
+**                  will not be notified any more
+**
+** Parameters       dwTimerId             - valid timer ID obtained during timer creation
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS            - the operation was successful
+**                  NFCSTATUS_NOT_INITIALISED    - OSAL Module is not initialized
+**                  NFCSTATUS_INVALID_PARAMETER  - invalid parameter passed to the function
+**                  PH_OSALNFC_TIMER_STOP_ERROR  - timer could not be stopped due to system error
+**
+*******************************************************************************/
+NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId)
+{
+    NFCSTATUS wStopStatus=NFCSTATUS_SUCCESS;
+    static struct itimerspec its = {{0, 0}, {0, 0}};
+
+    uint32_t dwIndex;
+    phOsalNfc_TimerHandle_t *pTimerHandle;
+    dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
+    pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
+    /* OSAL Module and Timer needs to be initialized for timer usage */
+        /* Check whether the TimerId provided by user is valid */
+        if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId) &&
+                (pTimerHandle->eState != eTimerIdle) )
+        {
+            /* Stop the timer only if the callback has not been invoked */
+            if(pTimerHandle->eState == eTimerRunning)
+            {
+                if((timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL)) == -1)
+                {
+                    wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_STOP_ERROR);
+                }
+                else
+                {
+                    /* Change the state of timer to Stopped */
+                    pTimerHandle->eState = eTimerStopped;
+                }
+            }
+        }
+        else
+        {
+            wStopStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
+        }
+
+    return wStopStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_Timer_Delete
+**
+** Description      Deletes previously created timer
+**                  Allows to delete previously created timer. In case timer is running,
+**                  it is first stopped and then deleted
+**
+** Parameters       dwTimerId             - valid timer ID obtained during timer creation
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS             - the operation was successful
+**                  NFCSTATUS_NOT_INITIALISED     - OSAL Module is not initialized
+**                  NFCSTATUS_INVALID_PARAMETER   - invalid parameter passed to the function
+**                  PH_OSALNFC_TIMER_DELETE_ERROR - timer could not be stopped due to system error
+**
+*******************************************************************************/
+NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId)
+{
+    NFCSTATUS wDeleteStatus = NFCSTATUS_SUCCESS;
+
+    uint32_t dwIndex;
+    phOsalNfc_TimerHandle_t *pTimerHandle;
+    dwIndex = dwTimerId - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
+    pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
+    /* OSAL Module and Timer needs to be initialized for timer usage */
+
+        /* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
+        if( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 != pTimerHandle->TimerId)
+                && (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
+        )
+        {
+            /* Cancel the timer before deleting */
+            if(timer_delete(pTimerHandle->hTimerHandle) == -1)
+            {
+                wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, PH_OSALNFC_TIMER_DELETE_ERROR);
+            }
+            /* Clear Timer structure used to store timer related data */
+            memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
+        }
+        else
+        {
+            wDeleteStatus = PHNFCSTVAL(CID_NFC_OSAL, NFCSTATUS_INVALID_PARAMETER);
+        }
+    return wDeleteStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_Timer_Cleanup
+**
+** Description      Deletes all previously created timers
+**                  Allows to delete previously created timers. In case timer is running,
+**                  it is first stopped and then deleted
+**
+** Parameters       None
+**
+** Returns          None
+**
+*******************************************************************************/
+void phOsalNfc_Timer_Cleanup(void)
+{
+    /* Delete all timers */
+    uint32_t dwIndex;
+    phOsalNfc_TimerHandle_t *pTimerHandle;
+    for(dwIndex = 0; dwIndex < PH_NFC_MAX_TIMER; dwIndex++)
+    {
+        pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
+        /* OSAL Module and Timer needs to be initialized for timer usage */
+
+        /* Check whether the TimerId passed by user is valid and Deregistering of timer is successful */
+        if( (0x00 != pTimerHandle->TimerId)
+                && (NFCSTATUS_SUCCESS == phOsalNfc_CheckTimerPresence(pTimerHandle))
+        )
+        {
+            /* Cancel the timer before deleting */
+            if(timer_delete(pTimerHandle->hTimerHandle) == -1)
+            {
+                NXPLOG_TML_E("timer %d delete error!", dwIndex);
+            }
+            /* Clear Timer structure used to store timer related data */
+            memset(pTimerHandle,(uint8_t)0x00,sizeof(phOsalNfc_TimerHandle_t));
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_DeferredCall
+**
+** Description      Invokes the timer callback function after timer expiration.
+**                  Shall invoke the callback function registered by the timer caller function
+**
+** Parameters       pParams - parameters indicating the ID of the timer
+**
+** Returns          None                -
+**
+*******************************************************************************/
+static void phOsalNfc_DeferredCall (void *pParams)
+{
+    /* Retrieve the timer id from the parameter */
+    uint32_t dwIndex;
+    phOsalNfc_TimerHandle_t *pTimerHandle;
+    if(NULL != pParams)
+    {
+        /* Retrieve the index at which the timer handle structure is stored */
+        dwIndex = (uintptr_t)pParams - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
+        pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
+        if(pTimerHandle->Application_callback != NULL)
+        {
+            /* Invoke the callback function with osal Timer ID */
+            pTimerHandle->Application_callback((uintptr_t)pParams, pTimerHandle->pContext);
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_PostTimerMsg
+**
+** Description      Posts message on the user thread
+**                  Shall be invoked upon expiration of a timer
+**                  Shall post message on user thread through which timer callback function shall be invoked
+**
+** Parameters       pMsg - pointer to the message structure posted on user thread
+**
+** Returns          None                -
+**
+*******************************************************************************/
+static void phOsalNfc_PostTimerMsg(phLibNfc_Message_t *pMsg)
+{
+
+    (void)phDal4Nfc_msgsnd(nxpncihal_ctrl.gDrvCfg.nClientId/*gpphOsalNfc_Context->dwCallbackThreadID*/, pMsg,0);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_Timer_Expired
+**
+** Description      posts message upon expiration of timer
+**                  Shall be invoked when any one timer is expired
+**                  Shall post message on user thread to invoke respective
+**                  callback function provided by the caller of Timer function
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phOsalNfc_Timer_Expired(union sigval sv)
+{
+   uint32_t dwIndex;
+   phOsalNfc_TimerHandle_t *pTimerHandle;
+
+
+    dwIndex = ((uint32_t)(sv.sival_int)) - PH_NFC_TIMER_BASE_ADDRESS - 0x01;
+    pTimerHandle = (phOsalNfc_TimerHandle_t *)&apTimerInfo[dwIndex];
+    /* Timer is stopped when callback function is invoked */
+    pTimerHandle->eState = eTimerStopped;
+
+    pTimerHandle->tDeferedCallInfo.pDeferedCall = &phOsalNfc_DeferredCall;
+    pTimerHandle->tDeferedCallInfo.pParam = (void *) ((intptr_t)(sv.sival_int));
+
+    pTimerHandle->tOsalMessage.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
+    pTimerHandle->tOsalMessage.pMsgData = (void *)&pTimerHandle->tDeferedCallInfo;
+
+
+    /* Post a message on the queue to invoke the function */
+    phOsalNfc_PostTimerMsg ((phLibNfc_Message_t *)&pTimerHandle->tOsalMessage);
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         phUtilNfc_CheckForAvailableTimer
+**
+** Description      Find an available timer id
+**
+** Parameters       void
+**
+** Returns          Available timer id
+**
+*******************************************************************************/
+uint32_t phUtilNfc_CheckForAvailableTimer(void)
+{
+    /* Variable used to store the index at which the object structure details
+       can be stored. Initialize it as not available. */
+    uint32_t dwIndex = 0x00;
+    uint32_t dwRetval = 0x00;
+
+
+    /* Check whether Timer object can be created */
+     for(dwIndex = 0x00;
+             ( (dwIndex < PH_NFC_MAX_TIMER) && (0x00 == dwRetval) ); dwIndex++)
+     {
+         if(!(apTimerInfo[dwIndex].TimerId))
+         {
+             dwRetval = (dwIndex + 0x01);
+         }
+     }
+
+     return (dwRetval);
+
+}
+
+/*******************************************************************************
+**
+** Function         phOsalNfc_CheckTimerPresence
+**
+** Description      Checks the requested timer is present or not
+**
+** Parameters       pObjectHandle - timer context
+**
+** Returns          NFCSTATUS_SUCCESS if found
+**                  Other value if not found
+**
+*******************************************************************************/
+NFCSTATUS phOsalNfc_CheckTimerPresence(void *pObjectHandle)
+{
+    uint32_t dwIndex;
+    NFCSTATUS wRegisterStatus = NFCSTATUS_INVALID_PARAMETER;
+
+    for(dwIndex = 0x00; ( (dwIndex < PH_NFC_MAX_TIMER) &&
+            (wRegisterStatus != NFCSTATUS_SUCCESS) ); dwIndex++)
+    {
+        /* For Timer, check whether the requested handle is present or not */
+        if( ((&apTimerInfo[dwIndex]) ==
+                (phOsalNfc_TimerHandle_t *)pObjectHandle) &&
+                (apTimerInfo[dwIndex].TimerId) )
+        {
+            wRegisterStatus = NFCSTATUS_SUCCESS;
+        }
+    }
+    return wRegisterStatus;
+
+}
diff --git a/halimpl/pn54x/tml/phOsalNfc_Timer.h b/halimpl/pn54x/tml/phOsalNfc_Timer.h
new file mode 100644
index 0000000..6749785
--- /dev/null
+++ b/halimpl/pn54x/tml/phOsalNfc_Timer.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * OSAL header files related to Timer functions.
+ */
+
+#ifndef PHOSALNFC_TIMER_H
+#define PHOSALNFC_TIMER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+************************* Include Files ****************************************
+*/
+
+
+/*
+ * Timer callback interface which will be called once registered timer
+ * time out expires.
+ *        TimerId  - Timer Id for which callback is called.
+ *        pContext - Parameter to be passed to the callback function
+ */
+typedef void (*pphOsalNfc_TimerCallbck_t)(uint32_t TimerId, void *pContext);
+
+/*
+ * The Timer could not be created due to a
+ * system error */
+#define PH_OSALNFC_TIMER_CREATE_ERROR                   (0X00E0)
+
+/*
+ * The Timer could not be started due to a
+ * system error or invalid handle */
+#define PH_OSALNFC_TIMER_START_ERROR                    (0X00E1)
+
+/*
+ * The Timer could not be stopped due to a
+ * system error or invalid handle */
+#define PH_OSALNFC_TIMER_STOP_ERROR                     (0X00E2)
+
+/*
+ * The Timer could not be deleted due to a
+ * system error or invalid handle */
+#define PH_OSALNFC_TIMER_DELETE_ERROR                   (0X00E3)
+
+/*
+ * Invalid timer ID type.This ID used indicate timer creation is failed */
+#define PH_OSALNFC_TIMER_ID_INVALID                     (0xFFFF)
+
+/*
+ * OSAL timer message .This message type will be posted to
+ * calling application thread.*/
+#define PH_OSALNFC_TIMER_MSG                            (0x315)
+
+/*
+***************************Globals,Structure and Enumeration ******************
+*/
+
+uint32_t phOsalNfc_Timer_Create(void);
+NFCSTATUS phOsalNfc_Timer_Start(uint32_t dwTimerId, uint32_t dwRegTimeCnt, pphOsalNfc_TimerCallbck_t pApplication_callback, void *pContext);
+NFCSTATUS phOsalNfc_Timer_Stop(uint32_t dwTimerId);
+NFCSTATUS phOsalNfc_Timer_Delete(uint32_t dwTimerId);
+void phOsalNfc_Timer_Cleanup(void);
+uint32_t phUtilNfc_CheckForAvailableTimer(void);
+NFCSTATUS phOsalNfc_CheckTimerPresence(void *pObjectHandle);
+
+
+#ifdef __cplusplus
+}
+#endif /*  C++ Compilation guard */
+#endif /* PHOSALNFC_TIMER_H */
diff --git a/halimpl/pn54x/tml/phTmlNfc.c b/halimpl/pn54x/tml/phTmlNfc.c
new file mode 100644
index 0000000..e2ee759
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc.c
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * TML Implementation.
+ */
+
+#include <phTmlNfc.h>
+#include <phOsalNfc_Timer.h>
+#include <phNxpLog.h>
+#include <phDal4Nfc_messageQueueLib.h>
+#include <phTmlNfc_i2c.h>
+#include <phNxpNciHal_utils.h>
+
+/*
+ * Duration of Timer to wait after sending an Nci packet
+ */
+#define PHTMLNFC_MAXTIME_RETRANSMIT (200U)
+#define MAX_WRITE_RETRY_COUNT 0x03
+/* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
+static uint8_t bCurrentRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
+
+
+/* Value to reset variables of TML  */
+#define PH_TMLNFC_RESET_VALUE               (0x00)
+
+/* Indicates a Initial or offset value */
+#define PH_TMLNFC_VALUE_ONE                 (0x01)
+
+/* Initialize Context structure pointer used to access context structure */
+phTmlNfc_Context_t *gpphTmlNfc_Context = NULL;
+extern phTmlNfc_i2cfragmentation_t fragmentation_enabled = I2C_FRAGMENATATION_DISABLED;
+/* Local Function prototypes */
+static NFCSTATUS phTmlNfc_StartThread(void);
+static void phTmlNfc_CleanUp(void);
+static void phTmlNfc_ReadDeferredCb(void *pParams);
+static void phTmlNfc_WriteDeferredCb(void *pParams);
+static void phTmlNfc_TmlThread(void *pParam);
+static void phTmlNfc_TmlWriterThread(void *pParam);
+static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void *pContext);
+static NFCSTATUS phTmlNfc_InitiateTimer(void);
+
+
+/* Function definitions */
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_Init
+**
+** Description      Provides initialization of TML layer and hardware interface
+**                  Configures given hardware interface and sends handle to the caller
+**
+** Parameters       pConfig     - TML configuration details as provided by the upper layer
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS            - initialization successful
+**                  NFCSTATUS_INVALID_PARAMETER  - at least one parameter is invalid
+**                  NFCSTATUS_FAILED             - initialization failed
+**                                                 (for example, unable to open hardware interface)
+**                  NFCSTATUS_INVALID_DEVICE     - device has not been opened or has been disconnected
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig)
+{
+    NFCSTATUS wInitStatus = NFCSTATUS_SUCCESS;
+
+    /* Check if TML layer is already Initialized */
+    if (NULL != gpphTmlNfc_Context)
+    {
+        /* TML initialization is already completed */
+        wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_ALREADY_INITIALISED);
+    }
+    /* Validate Input parameters */
+    else if ((NULL == pConfig)  ||
+            (PH_TMLNFC_RESET_VALUE == pConfig->dwGetMsgThreadId))
+    {
+        /*Parameters passed to TML init are wrong */
+        wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
+    }
+    else
+    {
+        /* Allocate memory for TML context */
+        gpphTmlNfc_Context = malloc(sizeof(phTmlNfc_Context_t));
+
+        if (NULL == gpphTmlNfc_Context)
+        {
+            wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+        }
+        else
+        {
+            /* Initialise all the internal TML variables */
+            memset(gpphTmlNfc_Context, PH_TMLNFC_RESET_VALUE, sizeof(phTmlNfc_Context_t));
+            /* Make sure that the thread runs once it is created */
+            gpphTmlNfc_Context->bThreadDone = 1;
+
+            /* Open the device file to which data is read/written */
+            wInitStatus = phTmlNfc_i2c_open_and_configure(pConfig, &(gpphTmlNfc_Context->pDevHandle));
+
+            if (NFCSTATUS_SUCCESS != wInitStatus)
+            {
+                wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_DEVICE);
+                gpphTmlNfc_Context->pDevHandle = (void *) NFCSTATUS_INVALID_DEVICE;
+            }
+            else
+            {
+                gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+                gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+                gpphTmlNfc_Context->tReadInfo.bThreadBusy = FALSE;
+                gpphTmlNfc_Context->tWriteInfo.bThreadBusy = FALSE;
+
+                if(0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0))
+                {
+                    wInitStatus = NFCSTATUS_FAILED;
+                }
+                else if(0 != sem_init(&gpphTmlNfc_Context->txSemaphore, 0, 0))
+                {
+                    wInitStatus = NFCSTATUS_FAILED;
+                }
+                else if(0 != sem_init(&gpphTmlNfc_Context->postMsgSemaphore, 0, 0))
+                {
+                    wInitStatus = NFCSTATUS_FAILED;
+                }
+                else
+                {
+                    sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+                    /* Start TML thread (to handle write and read operations) */
+                    if (NFCSTATUS_SUCCESS != phTmlNfc_StartThread())
+                    {
+                        wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+                    }
+                    else
+                    {
+                        /* Create Timer used for Retransmission of NCI packets */
+                        gpphTmlNfc_Context->dwTimerId = phOsalNfc_Timer_Create();
+                        if (PH_OSALNFC_TIMER_ID_INVALID != gpphTmlNfc_Context->dwTimerId)
+                        {
+                            /* Store the Thread Identifier to which Message is to be posted */
+                            gpphTmlNfc_Context->dwCallbackThreadId = pConfig->dwGetMsgThreadId;
+                            /* Enable retransmission of Nci packet & set retry count to default */
+                            gpphTmlNfc_Context->eConfig = phTmlNfc_e_DisableRetrans;
+                            /** Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
+                            gpphTmlNfc_Context->bRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
+                            gpphTmlNfc_Context->bWriteCbInvoked = FALSE;
+                        }
+                        else
+                        {
+                            wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    /* Clean up all the TML resources if any error */
+    if (NFCSTATUS_SUCCESS != wInitStatus)
+    {
+        /* Clear all handles and memory locations initialized during init */
+        phTmlNfc_CleanUp();
+    }
+
+    return wInitStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_ConfigNciPktReTx
+**
+** Description      Provides Enable/Disable Retransmission of NCI packets
+**                  Needed in case of Timeout between Transmission and Reception of NCI packets
+**                  Retransmission can be enabled only if standby mode is enabled
+**
+** Parameters       eConfig     - values from phTmlNfc_ConfigRetrans_t
+**                  bRetryCount - Number of times Nci packets shall be retransmitted (default = 3)
+**
+** Returns          None
+**
+*******************************************************************************/
+void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration, uint8_t bRetryCounter)
+{
+    /* Enable/Disable Retransmission */
+
+    gpphTmlNfc_Context->eConfig = eConfiguration;
+    if (phTmlNfc_e_EnableRetrans == eConfiguration)
+    {
+        /* Check whether Retry counter passed is valid */
+        if (0 != bRetryCounter)
+        {
+            gpphTmlNfc_Context->bRetryCount = bRetryCounter;
+        }
+        /* Set retry counter to its default value */
+        else
+        {
+            /** Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
+            gpphTmlNfc_Context->bRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
+        }
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_StartThread
+**
+** Description      Initializes comport, reader and writer threads
+**
+** Parameters       None
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS    - threads initialized successfully
+**                  NFCSTATUS_FAILED     - initialization failed due to system error
+**
+*******************************************************************************/
+static NFCSTATUS phTmlNfc_StartThread(void)
+{
+    NFCSTATUS wStartStatus = NFCSTATUS_SUCCESS;
+    void *h_threadsEvent = 0x00;
+    uint32_t dwEvent;
+    int pthread_create_status = 0;
+
+    /* Create Reader and Writer threads */
+    pthread_create_status = pthread_create(&gpphTmlNfc_Context->readerThread,NULL,(void *)&phTmlNfc_TmlThread,
+                                  (void *)h_threadsEvent);
+    if(0 != pthread_create_status)
+    {
+        wStartStatus = NFCSTATUS_FAILED;
+    }
+    else
+    {
+        /*Start Writer Thread*/
+        pthread_create_status = pthread_create(&gpphTmlNfc_Context->writerThread,NULL,(void *)&phTmlNfc_TmlWriterThread,
+                                   (void *)h_threadsEvent);
+        if(0 != pthread_create_status)
+        {
+            wStartStatus = NFCSTATUS_FAILED;
+        }
+    }
+
+    return wStartStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_ReTxTimerCb
+**
+** Description      This is the timer callback function after timer expiration.
+**
+** Parameters       dwThreadId  - id of the thread posting message
+**                  pContext    - context provided by upper layer
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_ReTxTimerCb(uint32_t dwTimerId, void *pContext)
+{
+    if ((gpphTmlNfc_Context->dwTimerId == dwTimerId) &&
+            (NULL == pContext))
+    {
+        /* If Retry Count has reached its limit,Retransmit Nci
+           packet */
+        if (0 == bCurrentRetryCount)
+        {
+            /* Since the count has reached its limit,return from timer callback
+               Upper layer Timeout would have happened */
+        }
+        else
+        {
+            bCurrentRetryCount--;
+            gpphTmlNfc_Context->tWriteInfo.bThreadBusy = TRUE;
+            gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
+        }
+        sem_post(&gpphTmlNfc_Context->txSemaphore);
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_InitiateTimer
+**
+** Description      Start a timer for Tx and Rx thread.
+**
+** Parameters       void
+**
+** Returns          NFC status
+**
+*******************************************************************************/
+static NFCSTATUS phTmlNfc_InitiateTimer(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+    /* Start Timer once Nci packet is sent */
+    wStatus = phOsalNfc_Timer_Start(gpphTmlNfc_Context->dwTimerId,
+            (uint32_t) PHTMLNFC_MAXTIME_RETRANSMIT,
+            phTmlNfc_ReTxTimerCb, NULL);
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_TmlThread
+**
+** Description      Read the data from the lower layer driver
+**
+** Parameters       pParam  - parameters for Writer thread function
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_TmlThread(void *pParam)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+    uint8_t temp[260];
+    /* Transaction info buffer to be passed to Callback Thread */
+    static phTmlNfc_TransactInfo_t tTransactionInfo;
+    /* Structure containing Tml callback function and parameters to be invoked
+       by the callback thread */
+    static phLibNfc_DeferredCall_t tDeferredInfo;
+    /* Initialize Message structure to post message onto Callback Thread */
+    static phLibNfc_Message_t tMsg;
+    UNUSED(pParam);
+    NXPLOG_TML_D("PN54X - Tml Reader Thread Started................\n");
+
+    /* Writer thread loop shall be running till shutdown is invoked */
+    while (gpphTmlNfc_Context->bThreadDone)
+    {
+        /* If Tml write is requested */
+        /* Set the variable to success initially */
+        wStatus = NFCSTATUS_SUCCESS;
+        sem_wait(&gpphTmlNfc_Context->rxSemaphore);
+
+        /* If Tml read is requested */
+        if (1 == gpphTmlNfc_Context->tReadInfo.bEnable)
+        {
+            NXPLOG_TML_D("PN54X - Read requested.....\n");
+            /* Set the variable to success initially */
+            wStatus = NFCSTATUS_SUCCESS;
+
+            /* Variable to fetch the actual number of bytes read */
+            dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+
+            /* Read the data from the file onto the buffer */
+            if (NFCSTATUS_INVALID_DEVICE != (uintptr_t)gpphTmlNfc_Context->pDevHandle)
+            {
+                NXPLOG_TML_D("PN54X - Invoking I2C Read.....\n");
+                dwNoBytesWrRd = phTmlNfc_i2c_read(gpphTmlNfc_Context->pDevHandle, temp, 260);
+
+                if (-1 == dwNoBytesWrRd)
+                {
+                    NXPLOG_TML_E("PN54X - Error in I2C Read.....\n");
+                    sem_post(&gpphTmlNfc_Context->rxSemaphore);
+                }
+                else
+                {
+                    memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
+
+                    NXPLOG_TML_D("PN54X - I2C Read successful.....\n");
+                    /* This has to be reset only after a successful read */
+                    gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+                    if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
+                            (0x00 != (gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0xE0)))
+                    {
+
+                        NXPLOG_TML_D("PN54X - Retransmission timer stopped.....\n");
+                        /* Stop Timer to prevent Retransmission */
+                        uint32_t timerStatus = phOsalNfc_Timer_Stop(gpphTmlNfc_Context->dwTimerId);
+                        if (NFCSTATUS_SUCCESS != timerStatus)
+                        {
+                            NXPLOG_TML_E("PN54X - timer stopped returned failure.....\n");
+                        }
+                        else
+                        {
+                            gpphTmlNfc_Context->bWriteCbInvoked = FALSE;
+                        }
+                    }
+                    /* Update the actual number of bytes read including header */
+                    gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t) (dwNoBytesWrRd);
+                    phNxpNciHal_print_packet("RECV", gpphTmlNfc_Context->tReadInfo.pBuffer,
+                            gpphTmlNfc_Context->tReadInfo.wLength);
+
+                    dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+
+                    /* Fill the Transaction info structure to be passed to Callback Function */
+                    tTransactionInfo.wStatus = wStatus;
+                    tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer;
+                    /* Actual number of bytes read is filled in the structure */
+                    tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength;
+
+                    /* Read operation completed successfully. Post a Message onto Callback Thread*/
+                    /* Prepare the message to be posted on User thread */
+                    tDeferredInfo.pCallback = &phTmlNfc_ReadDeferredCb;
+                    tDeferredInfo.pParameter = &tTransactionInfo;
+                    tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
+                    tMsg.pMsgData = &tDeferredInfo;
+                    tMsg.Size = sizeof(tDeferredInfo);
+                    NXPLOG_TML_D("PN54X - Posting read message.....\n");
+                    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
+
+                }
+            }
+            else
+            {
+                NXPLOG_TML_D("PN54X - NFCSTATUS_INVALID_DEVICE == gpphTmlNfc_Context->pDevHandle");
+            }
+        }
+        else
+        {
+            NXPLOG_TML_D("PN54X - read request NOT enabled");
+            usleep(10*1000);
+        }
+    }/* End of While loop */
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_TmlWriterThread
+**
+** Description      Writes the requested data onto the lower layer driver
+**
+** Parameters       pParam  - context provided by upper layer
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_TmlWriterThread(void *pParam)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+    int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+    /* Transaction info buffer to be passed to Callback Thread */
+    static phTmlNfc_TransactInfo_t tTransactionInfo;
+    /* Structure containing Tml callback function and parameters to be invoked
+       by the callback thread */
+    static phLibNfc_DeferredCall_t tDeferredInfo;
+    /* Initialize Message structure to post message onto Callback Thread */
+    static phLibNfc_Message_t tMsg;
+    /* In case of I2C Write Retry */
+    static uint16_t retry_cnt;
+    UNUSED(pParam);
+    NXPLOG_TML_D("PN54X - Tml Writer Thread Started................\n");
+
+    /* Writer thread loop shall be running till shutdown is invoked */
+    while (gpphTmlNfc_Context->bThreadDone)
+    {
+        NXPLOG_TML_D("PN54X - Tml Writer Thread Running................\n");
+        sem_wait(&gpphTmlNfc_Context->txSemaphore);
+        /* If Tml write is requested */
+        if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable)
+        {
+            NXPLOG_TML_D("PN54X - Write requested.....\n");
+            /* Set the variable to success initially */
+            wStatus = NFCSTATUS_SUCCESS;
+            if (NFCSTATUS_INVALID_DEVICE != (uintptr_t)gpphTmlNfc_Context->pDevHandle)
+            {
+                retry:
+
+                gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+                /* Variable to fetch the actual number of bytes written */
+                dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
+                /* Write the data in the buffer onto the file */
+                NXPLOG_TML_D("PN54X - Invoking I2C Write.....\n");
+                dwNoBytesWrRd = phTmlNfc_i2c_write(gpphTmlNfc_Context->pDevHandle,
+                        gpphTmlNfc_Context->tWriteInfo.pBuffer,
+                        gpphTmlNfc_Context->tWriteInfo.wLength
+                        );
+
+                /* Try I2C Write Five Times, if it fails : Raju */
+                if (-1 == dwNoBytesWrRd)
+                {
+                    if (getDownloadFlag() == TRUE)
+                    {
+                        if (retry_cnt++ < MAX_WRITE_RETRY_COUNT)
+                        {
+                            NXPLOG_NCIHAL_E(
+                                    "PN54X - Error in I2C Write  - Retry 0x%x", retry_cnt);
+                            goto retry;
+                        }
+                    }
+                    NXPLOG_TML_E("PN54X - Error in I2C Write.....\n");
+                    wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
+                }
+                else
+                {
+                    phNxpNciHal_print_packet("SEND", gpphTmlNfc_Context->tWriteInfo.pBuffer,
+                            gpphTmlNfc_Context->tWriteInfo.wLength);
+                }
+                retry_cnt = 0;
+                if (NFCSTATUS_SUCCESS == wStatus)
+                {
+                    NXPLOG_TML_D("PN54X - I2C Write successful.....\n");
+                    dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE;
+                }
+                /* Fill the Transaction info structure to be passed to Callback Function */
+                tTransactionInfo.wStatus = wStatus;
+                tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer;
+                /* Actual number of bytes written is filled in the structure */
+                tTransactionInfo.wLength = (uint16_t) dwNoBytesWrRd;
+
+                /* Prepare the message to be posted on the User thread */
+                tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb;
+                tDeferredInfo.pParameter = &tTransactionInfo;
+                /* Write operation completed successfully. Post a Message onto Callback Thread*/
+                tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
+                tMsg.pMsgData = &tDeferredInfo;
+                tMsg.Size = sizeof(tDeferredInfo);
+
+                /* Check whether Retransmission needs to be started,
+                 * If yes, Post message only if
+                 * case 1. Message is not posted &&
+                 * case 11. Write status is success ||
+                 * case 12. Last retry of write is also failure
+                 */
+                if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
+                        (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0)))
+                {
+                    if (FALSE == gpphTmlNfc_Context->bWriteCbInvoked)
+                    {
+                        if ((NFCSTATUS_SUCCESS == wStatus) ||
+                                (bCurrentRetryCount == 0))
+                        {
+                                NXPLOG_TML_D("PN54X - Posting Write message.....\n");
+                                phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
+                                        &tMsg);
+                                gpphTmlNfc_Context->bWriteCbInvoked = TRUE;
+                        }
+                    }
+                }
+                else
+                {
+                    NXPLOG_TML_D("PN54X - Posting Fresh Write message.....\n");
+                    phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
+                }
+            }
+            else
+            {
+                NXPLOG_TML_D("PN54X - NFCSTATUS_INVALID_DEVICE != gpphTmlNfc_Context->pDevHandle");
+            }
+
+            /* If Data packet is sent, then NO retransmission */
+            if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
+                    (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0)))
+            {
+                NXPLOG_TML_D("PN54X - Starting timer for Retransmission case");
+                wStatus = phTmlNfc_InitiateTimer();
+                if (NFCSTATUS_SUCCESS != wStatus)
+                {
+                    /* Reset Variables used for Retransmission */
+                    NXPLOG_TML_D("PN54X - Retransmission timer initiate failed");
+                    gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+                    bCurrentRetryCount = 0;
+                }
+            }
+        }
+        else
+        {
+            NXPLOG_TML_D("PN54X - Write request NOT enabled");
+            usleep(10000);
+        }
+
+    }/* End of While loop */
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_CleanUp
+**
+** Description      Clears all handles opened during TML initialization
+**
+** Parameters       None
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_CleanUp(void)
+{
+    NFCSTATUS wRetval = NFCSTATUS_SUCCESS;
+
+    if (NULL != gpphTmlNfc_Context->pDevHandle)
+    {
+        (void) phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+        gpphTmlNfc_Context->bThreadDone = 0;
+    }
+    sem_destroy(&gpphTmlNfc_Context->rxSemaphore);
+    sem_destroy(&gpphTmlNfc_Context->txSemaphore);
+    sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore);
+    phTmlNfc_i2c_close(gpphTmlNfc_Context->pDevHandle);
+    gpphTmlNfc_Context->pDevHandle = NULL;
+    /* Clear memory allocated for storing Context variables */
+    free((void *) gpphTmlNfc_Context);
+    /* Set the pointer to NULL to indicate De-Initialization */
+    gpphTmlNfc_Context = NULL;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_Shutdown
+**
+** Description      Uninitializes TML layer and hardware interface
+**
+** Parameters       None
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS            - TML configuration released successfully
+**                  NFCSTATUS_INVALID_PARAMETER  - at least one parameter is invalid
+**                  NFCSTATUS_FAILED             - un-initialization failed (example: unable to close interface)
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Shutdown(void)
+{
+    NFCSTATUS wShutdownStatus = NFCSTATUS_SUCCESS;
+
+    /* Check whether TML is Initialized */
+    if (NULL != gpphTmlNfc_Context)
+    {
+        /* Reset thread variable to terminate the thread */
+        gpphTmlNfc_Context->bThreadDone = 0;
+        usleep(1000);
+        /* Clear All the resources allocated during initialization */
+        sem_post(&gpphTmlNfc_Context->rxSemaphore);
+        usleep(1000);
+        sem_post(&gpphTmlNfc_Context->txSemaphore);
+        usleep(1000);
+        sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+        usleep(1000);
+        sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+        usleep(1000);
+        if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL))
+        {
+            NXPLOG_TML_E ("Fail to kill reader thread!");
+        }
+        if (0 != pthread_join(gpphTmlNfc_Context->writerThread, (void**)NULL))
+        {
+            NXPLOG_TML_E ("Fail to kill writer thread!");
+        }
+        NXPLOG_TML_D ("bThreadDone == 0");
+
+        phTmlNfc_CleanUp();
+    }
+    else
+    {
+        wShutdownStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
+    }
+
+    return wShutdownStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_Write
+**
+** Description      Asynchronously writes given data block to hardware interface/driver
+**                  Enables writer thread if there are no write requests pending
+**                  Returns successfully once writer thread completes write operation
+**                  Notifies upper layer using callback mechanism
+**                  NOTE:
+**                  * it is important to post a message with id PH_TMLNFC_WRITE_MESSAGE
+**                    to IntegrationThread after data has been written to PN54X
+**                  * if CRC needs to be computed, then input buffer should be capable to store
+**                    two more bytes apart from length of packet
+**
+** Parameters       pBuffer              - data to be sent
+**                  wLength              - length of data buffer
+**                  pTmlWriteComplete    - pointer to the function to be invoked upon completion
+**                  pContext             - context provided by upper layer
+**
+** Returns          NFC status:
+**                  NFCSTATUS_PENDING             - command is yet to be processed
+**                  NFCSTATUS_INVALID_PARAMETER   - at least one parameter is invalid
+**                  NFCSTATUS_BUSY                - write request is already in progress
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Write(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete, void *pContext)
+{
+    NFCSTATUS wWriteStatus;
+
+    /* Check whether TML is Initialized */
+
+    if (NULL != gpphTmlNfc_Context)
+    {
+        if ((NULL != gpphTmlNfc_Context->pDevHandle) && (NULL != pBuffer) &&
+                (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlWriteComplete))
+        {
+            if (!gpphTmlNfc_Context->tWriteInfo.bThreadBusy)
+            {
+                /* Setting the flag marks beginning of a Write Operation */
+                gpphTmlNfc_Context->tWriteInfo.bThreadBusy = TRUE;
+                /* Copy the buffer, length and Callback function,
+                   This shall be utilized while invoking the Callback function in thread */
+                gpphTmlNfc_Context->tWriteInfo.pBuffer = pBuffer;
+                gpphTmlNfc_Context->tWriteInfo.wLength = wLength;
+                gpphTmlNfc_Context->tWriteInfo.pThread_Callback = pTmlWriteComplete;
+                gpphTmlNfc_Context->tWriteInfo.pContext = pContext;
+
+                wWriteStatus = NFCSTATUS_PENDING;
+                //FIXME: If retry is going on. Stop the retry thread/timer
+                if (phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig)
+                {
+                    /* Set retry count to default value */
+                    //FIXME: If the timer expired there, and meanwhile we have created
+                    // a new request. The expired timer will think that retry is still
+                    // ongoing.
+                    bCurrentRetryCount = gpphTmlNfc_Context->bRetryCount;
+                    gpphTmlNfc_Context->bWriteCbInvoked = FALSE;
+                }
+                /* Set event to invoke Writer Thread */
+                gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
+                sem_post(&gpphTmlNfc_Context->txSemaphore);
+            }
+            else
+            {
+                wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
+            }
+        }
+        else
+        {
+            wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
+        }
+    }
+    else
+    {
+        wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
+    }
+
+    return wWriteStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_Read
+**
+** Description      Asynchronously reads data from the driver
+**                  Number of bytes to be read and buffer are passed by upper layer
+**                  Enables reader thread if there are no read requests pending
+**                  Returns successfully once read operation is completed
+**                  Notifies upper layer using callback mechanism
+**
+** Parameters       pBuffer              - location to send read data to the upper layer via callback
+**                  wLength              - length of read data buffer passed by upper layer
+**                  pTmlReadComplete     - pointer to the function to be invoked upon completion of read operation
+**                  pContext             - context provided by upper layer
+**
+** Returns          NFC status:
+**                  NFCSTATUS_PENDING             - command is yet to be processed
+**                  NFCSTATUS_INVALID_PARAMETER   - at least one parameter is invalid
+**                  NFCSTATUS_BUSY                - read request is already in progress
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_Read(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlReadComplete, void *pContext)
+{
+    NFCSTATUS wReadStatus;
+
+    /* Check whether TML is Initialized */
+    if (NULL != gpphTmlNfc_Context)
+    {
+        if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) &&
+                (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete))
+        {
+            if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy)
+            {
+                /* Setting the flag marks beginning of a Read Operation */
+                gpphTmlNfc_Context->tReadInfo.bThreadBusy = TRUE;
+                /* Copy the buffer, length and Callback function,
+                   This shall be utilized while invoking the Callback function in thread */
+                gpphTmlNfc_Context->tReadInfo.pBuffer = pBuffer;
+                gpphTmlNfc_Context->tReadInfo.wLength = wLength;
+                gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete;
+                gpphTmlNfc_Context->tReadInfo.pContext = pContext;
+                wReadStatus = NFCSTATUS_PENDING;
+
+                /* Set event to invoke Reader Thread */
+                gpphTmlNfc_Context->tReadInfo.bEnable = 1;
+                sem_post(&gpphTmlNfc_Context->rxSemaphore);
+            }
+            else
+            {
+                wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
+            }
+        }
+        else
+        {
+            wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
+        }
+    }
+    else
+    {
+        wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
+    }
+
+    return wReadStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_ReadAbort
+**
+** Description      Aborts pending read request (if any)
+**
+** Parameters       None
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS                    - ongoing read operation aborted
+**                  NFCSTATUS_INVALID_PARAMETER          - at least one parameter is invalid
+**                  NFCSTATUS_NOT_INITIALIZED            - TML layer is not initialized
+**                  NFCSTATUS_BOARD_COMMUNICATION_ERROR  - unable to cancel read operation
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_ReadAbort(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
+    gpphTmlNfc_Context->tReadInfo.bEnable = 0;
+
+    /*Reset the flag to accept another Read Request */
+    gpphTmlNfc_Context->tReadInfo.bThreadBusy=FALSE;
+    wStatus = NFCSTATUS_SUCCESS;
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_WriteAbort
+**
+** Description      Aborts pending write request (if any)
+**
+** Parameters       None
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS                    - ongoing write operation aborted
+**                  NFCSTATUS_INVALID_PARAMETER          - at least one parameter is invalid
+**                  NFCSTATUS_NOT_INITIALIZED            - TML layer is not initialized
+**                  NFCSTATUS_BOARD_COMMUNICATION_ERROR  - unable to cancel write operation
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_WriteAbort(void)
+{
+    NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
+
+    gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
+    /* Stop if any retransmission is in progress */
+    bCurrentRetryCount = 0;
+
+    /* Reset the flag to accept another Write Request */
+    gpphTmlNfc_Context->tWriteInfo.bThreadBusy=FALSE;
+    wStatus = NFCSTATUS_SUCCESS;
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_IoCtl
+**
+** Description      Resets device when insisted by upper layer
+**                  Number of bytes to be read and buffer are passed by upper layer
+**                  Enables reader thread if there are no read requests pending
+**                  Returns successfully once read operation is completed
+**                  Notifies upper layer using callback mechanism
+**
+** Parameters       eControlCode       - control code for a specific operation
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS  - ioctl command completed successfully
+**                  NFCSTATUS_FAILED   - ioctl command request failed
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode)
+{
+    NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
+
+    if (NULL == gpphTmlNfc_Context)
+    {
+        wStatus = NFCSTATUS_FAILED;
+    }
+    else
+    {
+        switch (eControlCode)
+        {
+            case phTmlNfc_e_ResetDevice:
+                {
+                    /*Reset PN54X*/
+                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+                    usleep(100 * 1000);
+                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+                    usleep(100 * 1000);
+                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+                    break;
+                }
+            case phTmlNfc_e_EnableNormalMode:
+                {
+                    /*Reset PN54X*/
+                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 0);
+                    usleep(10 * 1000);
+                    phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle, 1);
+                    usleep(100 * 1000);
+                    break;
+                }
+            case phTmlNfc_e_EnableDownloadMode:
+                {
+                    phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
+                    (void)phTmlNfc_i2c_reset(gpphTmlNfc_Context->pDevHandle,2);
+                    usleep(100 * 1000);
+                    break;
+                }
+            default:
+                {
+                    wStatus = NFCSTATUS_INVALID_PARAMETER;
+                    break;
+                }
+        }
+    }
+
+    return wStatus;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_DeferredCall
+**
+** Description      Posts message on upper layer thread
+**                  upon successful read or write operation
+**
+** Parameters       dwThreadId  - id of the thread posting message
+**                  ptWorkerMsg - message to be posted
+**
+** Returns          None
+**
+*******************************************************************************/
+void phTmlNfc_DeferredCall(uintptr_t dwThreadId, phLibNfc_Message_t *ptWorkerMsg)
+{
+    intptr_t bPostStatus;
+    UNUSED(dwThreadId);
+    /* Post message on the user thread to invoke the callback function */
+    sem_wait(&gpphTmlNfc_Context->postMsgSemaphore);
+    bPostStatus = phDal4Nfc_msgsnd(gpphTmlNfc_Context->dwCallbackThreadId,
+            ptWorkerMsg,
+            0
+            );
+    sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_ReadDeferredCb
+**
+** Description      Read thread call back function
+**
+** Parameters       pParams - context provided by upper layer
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_ReadDeferredCb(void *pParams)
+{
+    /* Transaction info buffer to be passed to Callback Function */
+    phTmlNfc_TransactInfo_t *pTransactionInfo = (phTmlNfc_TransactInfo_t *) pParams;
+
+    /* Reset the flag to accept another Read Request */
+    gpphTmlNfc_Context->tReadInfo.bThreadBusy = FALSE;
+    gpphTmlNfc_Context->tReadInfo.pThread_Callback(gpphTmlNfc_Context->tReadInfo.pContext,
+            pTransactionInfo);
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_WriteDeferredCb
+**
+** Description      Write thread call back function
+**
+** Parameters       pParams - context provided by upper layer
+**
+** Returns          None
+**
+*******************************************************************************/
+static void phTmlNfc_WriteDeferredCb(void *pParams)
+{
+    /* Transaction info buffer to be passed to Callback Function */
+    phTmlNfc_TransactInfo_t *pTransactionInfo = (phTmlNfc_TransactInfo_t *) pParams;
+
+    /* Reset the flag to accept another Write Request */
+    gpphTmlNfc_Context->tWriteInfo.bThreadBusy = FALSE;
+    gpphTmlNfc_Context->tWriteInfo.pThread_Callback(gpphTmlNfc_Context->tWriteInfo.pContext,
+            pTransactionInfo);
+
+    return;
+}
+
+void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result)
+{
+    fragmentation_enabled = result;
+}
+
+phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled()
+{
+    return  fragmentation_enabled;
+}
diff --git a/halimpl/pn54x/tml/phTmlNfc.h b/halimpl/pn54x/tml/phTmlNfc.h
new file mode 100644
index 0000000..8a1641b
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * Transport Mapping Layer header files containing APIs related to initializing, reading
+ * and writing data into files provided by the driver interface.
+ *
+ * API listed here encompasses Transport Mapping Layer interfaces required to be mapped
+ * to different Interfaces and Platforms.
+ *
+ */
+
+#ifndef PHTMLNFC_H
+#define PHTMLNFC_H
+
+#include <phNfcCommon.h>
+
+/*
+ * Message posted by Reader thread upon
+ * completion of requested operation
+ */
+#define PH_TMLNFC_READ_MESSAGE              (0xAA)
+
+/*
+ * Message posted by Writer thread upon
+ * completion of requested operation
+ */
+#define PH_TMLNFC_WRITE_MESSAGE             (0x55)
+
+/*
+ * Value indicates to reset device
+ */
+#define PH_TMLNFC_RESETDEVICE               (0x00008001)
+
+/*
+***************************Globals,Structure and Enumeration ******************
+*/
+
+/*
+ * Transaction (Tx/Rx) completion information structure of TML
+ *
+ * This structure holds the completion callback information of the
+ * transaction passed from the TML layer to the Upper layer
+ * along with the completion callback.
+ *
+ * The value of field wStatus can be interpreted as:
+ *
+ *     - NFCSTATUS_SUCCESS                    Transaction performed successfully.
+ *     - NFCSTATUS_FAILED                     Failed to wait on Read/Write operation.
+ *     - NFCSTATUS_INSUFFICIENT_STORAGE       Not enough memory to store data in case of read.
+ *     - NFCSTATUS_BOARD_COMMUNICATION_ERROR  Failure to Read/Write from the file or timeout.
+ */
+
+typedef struct phTmlNfc_TransactInfo
+{
+    NFCSTATUS           wStatus;    /* Status of the Transaction Completion*/
+    uint8_t             *pBuff;     /* Response Data of the Transaction*/
+    uint16_t            wLength;    /* Data size of the Transaction*/
+}phTmlNfc_TransactInfo_t;           /* Instance of Transaction structure */
+
+/*
+ * TML transreceive completion callback to Upper Layer
+ *
+ * pContext - Context provided by upper layer
+ * pInfo    - Transaction info. See phTmlNfc_TransactInfo
+ */
+typedef void (*pphTmlNfc_TransactCompletionCb_t) (void *pContext, phTmlNfc_TransactInfo_t *pInfo);
+
+/*
+ * TML Deferred callback interface structure invoked by upper layer
+ *
+ * This could be used for read/write operations
+ *
+ * dwMsgPostedThread Message source identifier
+ * pParams Parameters for the deferred call processing
+ */
+typedef  void (*pphTmlNfc_DeferFuncPointer_t) (uint32_t dwMsgPostedThread,void *pParams);
+
+/*
+ * Enum definition contains  supported ioctl control codes.
+ *
+ * phTmlNfc_IoCtl
+ */
+typedef enum
+{
+    phTmlNfc_e_Invalid = 0,
+    phTmlNfc_e_ResetDevice = PH_TMLNFC_RESETDEVICE, /* Reset the device */
+    phTmlNfc_e_EnableDownloadMode, /* Do the hardware setting to enter into download mode */
+    phTmlNfc_e_EnableNormalMode /* Hardware setting for normal mode of operation */
+} phTmlNfc_ControlCode_t ;  /* Control code for IOCTL call */
+
+/*
+ * Enable / Disable Re-Transmission of Packets
+ *
+ * phTmlNfc_ConfigNciPktReTx
+ */
+typedef enum
+{
+    phTmlNfc_e_EnableRetrans = 0x00, /*Enable retransmission of Nci packet */
+    phTmlNfc_e_DisableRetrans = 0x01 /*Disable retransmission of Nci packet */
+} phTmlNfc_ConfigRetrans_t ;  /* Configuration for Retransmission */
+
+/*
+ * Structure containing details related to read and write operations
+ *
+ */
+typedef struct phTmlNfc_ReadWriteInfo
+{
+    volatile uint8_t bEnable; /*This flag shall decide whether to perform Write/Read operation */
+    uint8_t bThreadBusy; /*Flag to indicate thread is busy on respective operation */
+    /* Transaction completion Callback function */
+    pphTmlNfc_TransactCompletionCb_t pThread_Callback;
+    void *pContext; /*Context passed while invocation of operation */
+    uint8_t *pBuffer; /*Buffer passed while invocation of operation */
+    uint16_t wLength; /*Length of data read/written */
+    NFCSTATUS wWorkStatus; /*Status of the transaction performed */
+} phTmlNfc_ReadWriteInfo_t;
+
+/*
+ *Base Context Structure containing members required for entire session
+ */
+typedef struct phTmlNfc_Context
+{
+    pthread_t readerThread; /*Handle to the thread which handles write and read operations */
+    pthread_t writerThread;
+    volatile uint8_t bThreadDone; /*Flag to decide whether to run or abort the thread */
+    phTmlNfc_ConfigRetrans_t eConfig; /*Retransmission of Nci Packet during timeout */
+    uint8_t bRetryCount; /*Number of times retransmission shall happen */
+    uint8_t bWriteCbInvoked; /* Indicates whether write callback is invoked during retransmission */
+    uint32_t dwTimerId; /* Timer used to retransmit nci packet */
+    phTmlNfc_ReadWriteInfo_t tReadInfo; /*Pointer to Reader Thread Structure */
+    phTmlNfc_ReadWriteInfo_t tWriteInfo; /*Pointer to Writer Thread Structure */
+    void *pDevHandle; /* Pointer to Device Handle */
+    uintptr_t dwCallbackThreadId; /* Thread ID to which message to be posted */
+    uint8_t bEnableCrc; /*Flag to validate/not CRC for input buffer */
+    sem_t   rxSemaphore;
+    sem_t   txSemaphore; /* Lock/Aquire txRx Semaphore */
+    sem_t   postMsgSemaphore; /* Semaphore to post message atomically by Reader & writer thread */
+} phTmlNfc_Context_t;
+
+/*
+ * TML Configuration exposed to upper layer.
+ */
+typedef struct phTmlNfc_Config
+{
+    /* Port name connected to PN54X
+     *
+     * Platform specific canonical device name to which PN54X is connected.
+     *
+     * e.g. On Linux based systems this would be /dev/PN54X
+     */
+    int8_t *pDevName;
+    /* Callback Thread ID
+     *
+     * This is the thread ID on which the Reader & Writer thread posts message. */
+    uintptr_t dwGetMsgThreadId;
+    /* Communication speed between DH and PN54X
+     *
+     * This is the baudrate of the bus for communication between DH and PN54X */
+    uint32_t dwBaudRate;
+} phTmlNfc_Config_t,*pphTmlNfc_Config_t;    /* pointer to phTmlNfc_Config_t */
+
+/*
+ * TML Deferred Callback structure used to invoke Upper layer Callback function.
+ */
+typedef struct {
+    pphTmlNfc_DeferFuncPointer_t pDef_call; /*Deferred callback function to be invoked */
+    /* Source identifier
+     *
+     * Identifier of the source which posted the message
+     */
+    uint32_t dwMsgPostedThread;
+    /** Actual Message
+     *
+     * This is passed as a parameter passed to the deferred callback function pDef_call. */
+    void* pParams;
+} phTmlNfc_DeferMsg_t;                      /* DeferMsg structure passed to User Thread */
+
+typedef enum
+{
+    I2C_FRAGMENATATION_DISABLED,     /*i2c fragmentation_disabled           */
+    I2C_FRAGMENTATION_ENABLED      /*i2c_fragmentation_enabled          */
+} phTmlNfc_i2cfragmentation_t;
+/* Function declarations */
+NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig);
+NFCSTATUS phTmlNfc_Shutdown(void);
+NFCSTATUS phTmlNfc_Write(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,  void *pContext);
+NFCSTATUS phTmlNfc_Read(uint8_t *pBuffer, uint16_t wLength, pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,  void *pContext);
+NFCSTATUS phTmlNfc_WriteAbort(void);
+NFCSTATUS phTmlNfc_ReadAbort(void);
+NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode);
+void phTmlNfc_DeferredCall(uintptr_t dwThreadId, phLibNfc_Message_t *ptWorkerMsg);
+void phTmlNfc_ConfigNciPktReTx( phTmlNfc_ConfigRetrans_t eConfig, uint8_t bRetryCount);
+void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t enable);
+phTmlNfc_i2cfragmentation_t phTmlNfc_get_fragmentation_enabled();
+#endif /*  PHTMLNFC_H  */
diff --git a/halimpl/pn54x/tml/phTmlNfc_i2c.c b/halimpl/pn54x/tml/phTmlNfc_i2c.c
new file mode 100644
index 0000000..7add07f
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * DAL I2C port implementation for linux
+ *
+ * Project: Trusted NFC Linux
+ *
+ */
+#include <hardware/nfc.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <errno.h>
+
+#include <phNxpLog.h>
+#include <phTmlNfc_i2c.h>
+#include <phNfcStatus.h>
+#include <string.h>
+#include "phNxpNciHal_utils.h"
+
+#define CRC_LEN                     2
+#define NORMAL_MODE_HEADER_LEN      3
+#define FW_DNLD_HEADER_LEN          2
+#define FW_DNLD_LEN_OFFSET          1
+#define NORMAL_MODE_LEN_OFFSET      2
+#define FRAGMENTSIZE_MAX            PHNFC_I2C_FRAGMENT_SIZE
+static bool_t bFwDnldFlag = FALSE;
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_close
+**
+** Description      Closes PN54X device
+**
+** Parameters       pDevHandle - device handle
+**
+** Returns          None
+**
+*******************************************************************************/
+void phTmlNfc_i2c_close(void *pDevHandle)
+{
+    if (NULL != pDevHandle)
+    {
+        close((intptr_t)pDevHandle);
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_open_and_configure
+**
+** Description      Open and configure PN54X device
+**
+** Parameters       pConfig     - hardware information
+**                  pLinkHandle - device handle
+**
+** Returns          NFC status:
+**                  NFCSTATUS_SUCCESS            - open_and_configure operation success
+**                  NFCSTATUS_INVALID_DEVICE     - device open operation failure
+**
+*******************************************************************************/
+NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, void ** pLinkHandle)
+{
+    int nHandle;
+
+
+    NXPLOG_TML_D("Opening port=%s\n", pConfig->pDevName);
+    /* open port */
+    nHandle = open((char const *)pConfig->pDevName, O_RDWR);
+    if (nHandle < 0)
+    {
+        NXPLOG_TML_E("_i2c_open() Failed: retval %x",nHandle);
+        *pLinkHandle = NULL;
+        return NFCSTATUS_INVALID_DEVICE;
+    }
+
+    *pLinkHandle = (void*) ((intptr_t)nHandle);
+
+    /*Reset PN54X*/
+    phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 1);
+    usleep(100 * 1000);
+    phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 0);
+    usleep(100 * 1000);
+    phTmlNfc_i2c_reset((void *)((intptr_t)nHandle), 1);
+
+    return NFCSTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_read
+**
+** Description      Reads requested number of bytes from PN54X device into given buffer
+**
+** Parameters       pDevHandle       - valid device handle
+**                  pBuffer          - buffer for read data
+**                  nNbBytesToRead   - number of bytes requested to be read
+**
+** Returns          numRead   - number of successfully read bytes
+**                  -1        - read operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_read(void *pDevHandle, uint8_t * pBuffer, int nNbBytesToRead)
+{
+    int ret_Read;
+    int ret_Select;
+    int numRead = 0;
+    struct timeval tv;
+    fd_set rfds;
+    uint16_t totalBtyesToRead = 0;
+
+    int i;
+    UNUSED(nNbBytesToRead);
+    if (NULL == pDevHandle)
+    {
+        return -1;
+    }
+
+    if (FALSE == bFwDnldFlag)
+    {
+        totalBtyesToRead = NORMAL_MODE_HEADER_LEN;
+    }
+    else
+    {
+        totalBtyesToRead = FW_DNLD_HEADER_LEN;
+    }
+
+    /* Read with 2 second timeout, so that the read thread can be aborted
+       when the PN54X does not respond and we need to switch to FW download
+       mode. This should be done via a control socket instead. */
+    FD_ZERO(&rfds);
+    FD_SET((intptr_t) pDevHandle, &rfds);
+    tv.tv_sec = 2;
+    tv.tv_usec = 1;
+
+    ret_Select = select((int)((intptr_t)pDevHandle + (int)1), &rfds, NULL, NULL, &tv);
+    if (ret_Select < 0)
+    {
+        NXPLOG_TML_E("i2c select() errno : %x",errno);
+        return -1;
+    }
+    else if (ret_Select == 0)
+    {
+        NXPLOG_TML_E("i2c select() Timeout");
+        return -1;
+    }
+    else
+    {
+        ret_Read = read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead);
+        if (ret_Read > 0)
+        {
+            numRead += ret_Read;
+        }
+        else if (ret_Read == 0)
+        {
+            NXPLOG_TML_E("_i2c_read() [hdr]EOF");
+            return -1;
+        }
+        else
+        {
+            NXPLOG_TML_E("_i2c_read() [hdr] errno : %x",errno);
+            return -1;
+        }
+
+        if (FALSE == bFwDnldFlag)
+        {
+            totalBtyesToRead = NORMAL_MODE_HEADER_LEN;
+        }
+        else
+        {
+            totalBtyesToRead = FW_DNLD_HEADER_LEN;
+        }
+
+        if(numRead < totalBtyesToRead)
+        {
+            ret_Read = read((intptr_t)pDevHandle, pBuffer, totalBtyesToRead - numRead);
+            if (ret_Read != totalBtyesToRead - numRead)
+            {
+                NXPLOG_TML_E("_i2c_read() [hdr] errno : %x",errno);
+                return -1;
+            }
+            else
+            {
+                numRead += ret_Read;
+            }
+        }
+        if(TRUE == bFwDnldFlag)
+        {
+            totalBtyesToRead = pBuffer[FW_DNLD_LEN_OFFSET] + FW_DNLD_HEADER_LEN + CRC_LEN;
+        }
+        else
+        {
+            totalBtyesToRead = pBuffer[NORMAL_MODE_LEN_OFFSET] + NORMAL_MODE_HEADER_LEN;
+        }
+        ret_Read = read((intptr_t)pDevHandle, (pBuffer + numRead), totalBtyesToRead - numRead);
+        if (ret_Read > 0)
+        {
+            numRead += ret_Read;
+        }
+        else if (ret_Read == 0)
+        {
+            NXPLOG_TML_E("_i2c_read() [pyld] EOF");
+            return -1;
+        }
+        else
+        {
+            if(FALSE == bFwDnldFlag)
+            {
+                NXPLOG_TML_E("_i2c_read() [hdr] received");
+                phNxpNciHal_print_packet("RECV",pBuffer, NORMAL_MODE_HEADER_LEN);
+            }
+            NXPLOG_TML_E("_i2c_read() [pyld] errno : %x",errno);
+            return -1;
+        }
+    }
+    return numRead;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_write
+**
+** Description      Writes requested number of bytes from given buffer into PN54X device
+**
+** Parameters       pDevHandle       - valid device handle
+**                  pBuffer          - buffer for read data
+**                  nNbBytesToWrite  - number of bytes requested to be written
+**
+** Returns          numWrote   - number of successfully written bytes
+**                  -1         - write operation failure
+**
+*******************************************************************************/
+int phTmlNfc_i2c_write(void *pDevHandle, uint8_t * pBuffer, int nNbBytesToWrite)
+{
+    int ret;
+    int numWrote = 0;
+    int i;
+    int numBytes = nNbBytesToWrite;
+    if (NULL == pDevHandle)
+    {
+        return -1;
+    }
+    if(fragmentation_enabled == I2C_FRAGMENATATION_DISABLED && nNbBytesToWrite > FRAGMENTSIZE_MAX)
+    {
+        NXPLOG_TML_E("i2c_write() data larger than maximum I2C  size,enable I2C fragmentation");
+        return -1;
+    }
+    while (numWrote < nNbBytesToWrite)
+    {
+        if(fragmentation_enabled == I2C_FRAGMENTATION_ENABLED && nNbBytesToWrite > FRAGMENTSIZE_MAX)
+        {
+            if(nNbBytesToWrite - numWrote > FRAGMENTSIZE_MAX)
+            {
+                numBytes = numWrote+ FRAGMENTSIZE_MAX;
+            }
+            else
+            {
+                numBytes = nNbBytesToWrite;
+            }
+        }
+        ret = write((intptr_t)pDevHandle, pBuffer + numWrote, numBytes - numWrote);
+        if (ret > 0)
+        {
+            numWrote += ret;
+            if(fragmentation_enabled == I2C_FRAGMENTATION_ENABLED && numWrote < nNbBytesToWrite)
+            {
+                usleep(500);
+            }
+        }
+        else if (ret == 0)
+        {
+            NXPLOG_TML_E("_i2c_write() EOF");
+            return -1;
+        }
+        else
+        {
+            NXPLOG_TML_E("_i2c_write() errno : %x",errno);
+            if (errno == EINTR || errno == EAGAIN)
+            {
+                continue;
+            }
+            return -1;
+        }
+    }
+
+    return numWrote;
+}
+
+/*******************************************************************************
+**
+** Function         phTmlNfc_i2c_reset
+**
+** Description      Reset PN54X device, using VEN pin
+**
+** Parameters       pDevHandle     - valid device handle
+**                  level          - reset level
+**
+** Returns           0   - reset operation success
+**                  -1   - reset operation failure
+**
+*******************************************************************************/
+#define PN544_SET_PWR _IOW(0xe9, 0x01, unsigned int)
+int phTmlNfc_i2c_reset(void *pDevHandle, long level)
+{
+    int ret;
+    NXPLOG_TML_D("phTmlNfc_i2c_reset(), VEN level %ld", level);
+
+    if (NULL == pDevHandle)
+    {
+        return -1;
+    }
+
+    ret = ioctl((intptr_t)pDevHandle, PN544_SET_PWR, level);
+    if(level == 2 && ret == 0)
+    {
+        bFwDnldFlag = TRUE;
+    }else{
+        bFwDnldFlag = FALSE;
+    }
+    return ret;
+}
+
+/*******************************************************************************
+**
+** Function         getDownloadFlag
+**
+** Description      Returns the current mode
+**
+** Parameters       none
+**
+** Returns           Current mode download/NCI
+*******************************************************************************/
+bool_t getDownloadFlag(void)
+{
+
+    return bFwDnldFlag;
+}
diff --git a/halimpl/pn54x/tml/phTmlNfc_i2c.h b/halimpl/pn54x/tml/phTmlNfc_i2c.h
new file mode 100644
index 0000000..724a2bd
--- /dev/null
+++ b/halimpl/pn54x/tml/phTmlNfc_i2c.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010-2014 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.
+ */
+
+/*
+ * TML I2C port implementation for linux
+ */
+
+/* Basic type definitions */
+#include <phNfcTypes.h>
+#include <phTmlNfc.h>
+
+/* Function declarations */
+void phTmlNfc_i2c_close(void *pDevHandle);
+NFCSTATUS phTmlNfc_i2c_open_and_configure(pphTmlNfc_Config_t pConfig, void ** pLinkHandle);
+int phTmlNfc_i2c_read(void *pDevHandle, uint8_t * pBuffer, int nNbBytesToRead);
+int phTmlNfc_i2c_write(void *pDevHandle,uint8_t * pBuffer, int nNbBytesToWrite);
+int phTmlNfc_i2c_reset(void *pDevHandle,long level);
+bool_t getDownloadFlag(void);
+phTmlNfc_i2cfragmentation_t fragmentation_enabled;
diff --git a/halimpl/pn54x/utils/phNxpConfig.cpp b/halimpl/pn54x/utils/phNxpConfig.cpp
new file mode 100644
index 0000000..b44d018
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpConfig.cpp
@@ -0,0 +1,1024 @@
+/******************************************************************************
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2013-2014 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 <string>
+#include <vector>
+#include <list>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include <phNxpConfig.h>
+#include <phNxpLog.h>
+
+#if GENERIC_TARGET
+const char alternative_config_path[] = "/data/nfc/";
+#else
+const char alternative_config_path[] = "";
+#endif
+
+#if 1
+const char transport_config_path[] = "/etc/";
+#else
+const char transport_config_path[] = "res/";
+#endif
+
+#define config_name             "libnfc-nxp.conf"
+#define extra_config_base       "libnfc-nxp-"
+#define extra_config_ext        ".conf"
+#define     IsStringValue       0x80000000
+
+const char config_timestamp_path[] = "/data/nfc/libnfc-nxpConfigState.bin";
+
+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);
+    int updateTimestamp();
+    int checkTimestamp();
+
+    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;
+    bool    getValue(const char* name, char* pValue, long len,long* readlen) 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 m_timeStamp;
+
+    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: determine if 'c' is printable
+**
+** Returns:     1, if printable, otherwise 0
+**
+*******************************************************************************/
+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: determine if 'c' is numeral digit
+**
+** Returns:     true, if numerical digit
+**
+*******************************************************************************/
+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 numerical value of a decimal or hex char
+**
+** Returns:     numerical value if decimal or hex char, otherwise 0
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+    if ('0' <= c && c <= '9')
+        return c - '0';
+    if (base == 16)
+    {
+        if ('A' <= c && c <= 'F')
+            return c - 'A' + 10;
+        else if ('a' <= c && c <= 'f')
+            return c - 'a' + 10;
+    }
+    return 0;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+**              move the element from linked list to a array at the end
+**
+** Returns:     1, if there are any config data, 0 otherwise
+**
+*******************************************************************************/
+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;
+    struct stat buf;
+    string  token;
+    string  strValue;
+    unsigned long    numValue = 0;
+    CNfcParam* pParam = NULL;
+    int     i = 0;
+    int     base = 0;
+    char    c;
+    int     bflag = 0;
+    state = BEGIN_LINE;
+    /* open config file, read it into a buffer */
+    if ((fd = fopen(name, "rb")) == NULL)
+    {
+        ALOGE("%s Cannot open config file %s\n", __func__, name);
+        if (bResetContent)
+        {
+            ALOGE("%s Using default value for all settings\n", __func__);
+            mValidFile = false;
+        }
+        return false;
+    }
+    stat(name, &buf);
+    m_timeStamp = (unsigned long)buf.st_mtime;
+
+    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;
+                bflag = 1;
+                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;
+            }
+            // fall through to numValue to handle numValue
+
+        case NUM_VALUE:
+            if (isDigit(c, base))
+            {
+                numValue *= base;
+                numValue += getDigitValue(c, base);
+                ++i;
+            }
+            else if(bflag == 1 && (c == ' ' || c == '\r' || c=='\n' || c=='\t'))
+            {
+                break;
+            }
+            else if (base == 16 && (c== ','|| c == ':' || c == '-' || c == ' ' || c == '}'))
+            {
+
+                if( c=='}' )
+                {
+                    bflag = 0;
+                }
+                if (i > 0)
+                {
+                    int n = (i+1) / 2;
+                    while (n-- > 0)
+                    {
+                        numValue = numValue >> (n * 8);
+                        unsigned char c = (numValue)  & 0xFF;
+                        strValue.push_back(c);
+                    }
+                }
+
+                Set(IsStringValue);
+                numValue = 0;
+                i = 0;
+            }
+            else
+            {
+                if (c == '\n' || c == '\r')
+                {
+                    if(bflag == 0 )
+                    {
+                        state = BEGIN_LINE;
+                    }
+                }
+                else
+                {
+                    if( bflag == 0)
+                    {
+                        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),
+    m_timeStamp(0),
+    state(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig()
+{
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns:     none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance()
+{
+    static CNfcConfig theInstance;
+
+    if (theInstance.size() == 0 && theInstance.mValidFile)
+    {
+        string strPath;
+        if (alternative_config_path[0] != '\0')
+        {
+            strPath.assign(alternative_config_path);
+            strPath += config_name;
+            theInstance.readConfig(strPath.c_str(), true);
+            if (!theInstance.empty())
+            {
+                return theInstance;
+            }
+        }
+        strPath.assign(transport_config_path);
+        strPath += config_name;
+        theInstance.readConfig(strPath.c_str(), true);
+    }
+
+    return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns:     true if setting exists
+**              false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t len) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() > 0)
+    {
+        memset(pValue, 0, len);
+        memcpy(pValue, pParam->str_value(), pParam->str_len());
+        return true;
+    }
+    return false;
+}
+
+bool CNfcConfig::getValue(const char* name, char* pValue, long len,long* readlen) const
+{
+    const CNfcParam* pParam = find(name);
+    if (pParam == NULL)
+        return false;
+
+    if (pParam->str_len() > 0)
+    {
+        if(pParam->str_len() <= (unsigned long)len)
+        {
+            memset(pValue, 0, len);
+            memcpy(pValue, pParam->str_value(), pParam->str_len());
+            *readlen = pParam->str_len();
+        }
+        else
+        {
+            *readlen = -1;
+        }
+
+        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)
+            {
+                NXPLOG_EXTNS_D("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+            }
+            else
+            {
+                NXPLOG_EXTNS_D("%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();
+}
+
+#if 0
+/*******************************************************************************
+**
+** Function:    CNfcConfig::checkTimestamp()
+**
+** Description: check if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::checkTimestamp()
+{
+    FILE*   fd;
+    struct stat st;
+    unsigned long value = 0;
+    int ret = 0;
+
+    if(stat(config_timestamp_path, &st) != 0)
+    {
+        ALOGD("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
+        if ((fd = fopen(config_timestamp_path, "w+")) != NULL)
+        {
+            fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+            fclose(fd);
+        }
+        return 1;
+    }
+    else
+    {
+        fd = fopen(config_timestamp_path, "r+");
+        if(fd == NULL)
+        {
+            ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
+            return 1;
+        }
+
+        fread(&value, sizeof(unsigned long), 1, fd);
+        ret = (value != m_timeStamp);
+        if(ret)
+        {
+            fseek(fd, 0, SEEK_SET);
+            fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+        }
+        fclose(fd);
+    }
+    return ret;
+}
+
+#endif
+/*******************************************************************************
+**
+** Function:    CNfcConfig::checkforTimestamp()
+**
+** Description: check if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::checkTimestamp()
+{
+    FILE*   fd;
+    struct stat st;
+    unsigned long value = 0;
+    int ret = 0;
+
+    if(stat(config_timestamp_path, &st) != 0)
+    {
+        ALOGD("%s file not exist.\n", __func__);
+        return 1;
+    }
+    else
+    {
+        fd = fopen(config_timestamp_path, "r+");
+        if(fd == NULL)
+        {
+            ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
+            return 1;
+        }
+
+        fread(&value, sizeof(unsigned long), 1, fd);
+        ret = (value != m_timeStamp);
+        fclose(fd);
+    }
+    return ret;
+}
+
+/*******************************************************************************
+**
+** Function:    CNfcConfig::updateTimestamp()
+**
+** Description: update if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+int CNfcConfig::updateTimestamp()
+{
+    FILE*   fd;
+    struct stat st;
+    unsigned long value = 0;
+    int ret = 0;
+
+    if(stat(config_timestamp_path, &st) != 0)
+    {
+        ALOGD("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
+        if ((fd = fopen(config_timestamp_path, "w+")) != NULL)
+        {
+            fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+            fclose(fd);
+        }
+        return 1;
+    }
+    else
+    {
+        fd = fopen(config_timestamp_path, "r+");
+        if(fd == NULL)
+        {
+            ALOGE("%s Cannot open file %s\n", __func__, config_timestamp_path);
+            return 1;
+        }
+
+        fread(&value, sizeof(unsigned long), 1, fd);
+        ret = (value != m_timeStamp);
+        if(ret)
+        {
+            fseek(fd, 0, SEEK_SET);
+            fwrite(&m_timeStamp, sizeof(unsigned long), 1, fd);
+        }
+        fclose(fd);
+    }
+    return ret;
+}
+
+/*******************************************************************************
+**
+** 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:     True if found, otherwise False.
+**
+*******************************************************************************/
+extern "C" int GetNxpStrValue(const char* name, char* pValue, unsigned long len)
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    return rConfig.getValue(name, pValue, len);
+}
+
+/*******************************************************************************
+**
+** Function:    GetByteArrayValue()
+**
+** Description: Read byte array value from the config file.
+**
+** Parameters:
+**              name    - name of the config param to read.
+**              pValue  - pointer to input buffer.
+**              bufflen - input buffer length.
+**              len     - out parameter to return the number of bytes read from config file,
+**                        return -1 in case bufflen is not enough.
+**
+** Returns:     TRUE[1] if config param name is found in the config file, else FALSE[0]
+**
+*******************************************************************************/
+extern "C" int GetNxpByteArrayValue(const char* name, char* pValue,long bufflen, long *len)
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    return rConfig.getValue(name, pValue, bufflen,len);
+}
+
+/*******************************************************************************
+**
+** Function:    GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns:     true, if successful
+**
+*******************************************************************************/
+extern "C" int GetNxpNumValue(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 (unsigned int i = 0 ; i < pParam->str_len(); ++i)
+        {
+            v *= 256;
+            v += *p++;
+        }
+    }
+    switch (len)
+    {
+    case sizeof(unsigned long):
+        *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+        break;
+    case sizeof(unsigned short):
+        *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+        break;
+    case sizeof(unsigned char):
+        *(static_cast<unsigned char*> (pValue)) = (unsigned char)v;
+        break;
+    default:
+        return false;
+    }
+    return true;
+}
+
+/*******************************************************************************
+**
+** Function:    resetConfig
+**
+** Description: reset settings array
+**
+** Returns:     none
+**
+*******************************************************************************/
+extern "C" void resetNxpConfig()
+
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+    rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function:    readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns:     none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra)
+{
+    string strPath;
+    strPath.assign(transport_config_path);
+    if (alternative_config_path[0] != '\0')
+        strPath.assign(alternative_config_path);
+
+    strPath += extra_config_base;
+    strPath += extra;
+    strPath += extra_config_ext;
+    CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
+/*******************************************************************************
+**
+** Function:    isNxpConfigModified()
+**
+** Description: check if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int isNxpConfigModified()
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+    return rConfig.checkTimestamp();
+}
+
+/*******************************************************************************
+**
+** Function:    updateNxpConfigTimestamp()
+**
+** Description: update if config file has modified
+**
+** Returns:     0 if not modified, 1 otherwise.
+**
+*******************************************************************************/
+extern "C" int updateNxpConfigTimestamp()
+{
+    CNfcConfig& rConfig = CNfcConfig::GetInstance();
+    return rConfig.updateTimestamp();
+}
diff --git a/halimpl/pn54x/utils/phNxpConfig.h b/halimpl/pn54x/utils/phNxpConfig.h
new file mode 100644
index 0000000..45c1ecd
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpConfig.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  The original Work has been changed by NXP Semiconductors.
+ *
+ *  Copyright (C) 2013-2014 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 __CONFIG_H
+#define __CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int GetNxpStrValue(const char* name, char* p_value, unsigned long len);
+int GetNxpNumValue(const char* name, void* p_value, unsigned long len);
+int GetNxpByteArrayValue(const char* name, char* pValue,long bufflen, long *len);
+void resetNxpConfig(void);
+int isNxpConfigModified();
+int updateNxpConfigTimestamp();
+
+#ifdef __cplusplus
+};
+#endif
+
+#define NAME_NXPLOG_EXTNS_LOGLEVEL   "NXPLOG_EXTNS_LOGLEVEL"
+#define NAME_NXPLOG_NCIHAL_LOGLEVEL  "NXPLOG_NCIHAL_LOGLEVEL"
+#define NAME_NXPLOG_NCIX_LOGLEVEL    "NXPLOG_NCIX_LOGLEVEL"
+#define NAME_NXPLOG_NCIR_LOGLEVEL    "NXPLOG_NCIR_LOGLEVEL"
+#define NAME_NXPLOG_FWDNLD_LOGLEVEL  "NXPLOG_FWDNLD_LOGLEVEL"
+#define NAME_NXPLOG_TML_LOGLEVEL     "NXPLOG_TML_LOGLEVEL"
+
+#define NAME_MIFARE_READER_ENABLE    "MIFARE_READER_ENABLE"
+#define NAME_FW_STORAGE              "FW_STORAGE"
+#define NAME_NXP_FW_PROTECION_OVERRIDE "NXP_FW_PROTECION_OVERRIDE"
+#define NAME_NXP_SYS_CLK_SRC_SEL     "NXP_SYS_CLK_SRC_SEL"
+#define NAME_NXP_SYS_CLK_FREQ_SEL    "NXP_SYS_CLK_FREQ_SEL"
+#define NAME_NXP_SYS_CLOCK_TO_CFG    "NXP_SYS_CLOCK_TO_CFG"
+#define NAME_NXP_ACT_PROP_EXTN       "NXP_ACT_PROP_EXTN"
+#define NAME_NXP_EXT_TVDD_CFG        "NXP_EXT_TVDD_CFG"
+#define NAME_NXP_EXT_TVDD_CFG_1      "NXP_EXT_TVDD_CFG_1"
+#define NAME_NXP_EXT_TVDD_CFG_2      "NXP_EXT_TVDD_CFG_2"
+#define NAME_NXP_EXT_TVDD_CFG_3      "NXP_EXT_TVDD_CFG_3"
+#define NAME_NXP_RF_CONF_BLK_1       "NXP_RF_CONF_BLK_1"
+#define NAME_NXP_RF_CONF_BLK_2       "NXP_RF_CONF_BLK_2"
+#define NAME_NXP_RF_CONF_BLK_3       "NXP_RF_CONF_BLK_3"
+#define NAME_NXP_RF_CONF_BLK_4       "NXP_RF_CONF_BLK_4"
+#define NAME_NXP_RF_CONF_BLK_5       "NXP_RF_CONF_BLK_5"
+#define NAME_NXP_RF_CONF_BLK_6       "NXP_RF_CONF_BLK_6"
+#define NAME_NXP_CORE_CONF_EXTN      "NXP_CORE_CONF_EXTN"
+#define NAME_NXP_CORE_CONF           "NXP_CORE_CONF"
+#define NAME_NXP_CORE_MFCKEY_SETTING "NXP_CORE_MFCKEY_SETTING"
+#define NAME_NXP_CORE_STANDBY        "NXP_CORE_STANDBY"
+#define NAME_NXP_NFC_PROFILE_EXTN    "NXP_NFC_PROFILE_EXTN"
+#define NAME_NXP_CHINA_TIANJIN_RF_ENABLED  "NXP_CHINA_TIANJIN_RF_ENABLED"
+#define NAME_NXP_SWP_SWITCH_TIMEOUT  "NXP_SWP_SWITCH_TIMEOUT"
+#define NAME_NXP_SWP_FULL_PWR_ON     "NXP_SWP_FULL_PWR_ON"
+#define NAME_NXP_CORE_RF_FIELD       "NXP_CORE_RF_FIELD"
+#define NAME_NXP_NFC_MERGE_RF_PARAMS "NXP_NFC_MERGE_RF_PARAMS"
+#define NAME_NXP_I2C_FRAGMENTATION_ENABLED "NXP_I2C_FRAGMENTATION_ENABLED"
+#define NAME_AID_MATCHING_PLATFORM "AID_MATCHING_PLATFORM"
+
+
+/* default configuration */
+#define default_storage_location "/data/nfc"
+
+#endif
diff --git a/halimpl/pn54x/utils/phNxpNciHal_utils.c b/halimpl/pn54x/utils/phNxpNciHal_utils.c
new file mode 100644
index 0000000..65ec89d
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpNciHal_utils.c
@@ -0,0 +1,506 @@
+/*
+ *
+ *  Copyright (C) 2013-2014 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 <phNxpNciHal_utils.h>
+#include <errno.h>
+#include <phNxpLog.h>
+
+/*********************** Link list functions **********************************/
+
+/*******************************************************************************
+**
+** Function         listInit
+**
+** Description      List initialization
+**
+** Returns          1, if list initialized, 0 otherwise
+**
+*******************************************************************************/
+int listInit(struct listHead* pList)
+{
+    pList->pFirst = NULL;
+    if (pthread_mutex_init(&pList->mutex, NULL) == -1)
+    {
+        NXPLOG_NCIHAL_E("Mutex creation failed (errno=0x%08x)", errno);
+        return 0;
+    }
+
+    return 1;
+}
+
+/*******************************************************************************
+**
+** Function         listDestroy
+**
+** Description      List destruction
+**
+** Returns          1, if list destroyed, 0 if failed
+**
+*******************************************************************************/
+int listDestroy(struct listHead* pList)
+{
+    int bListNotEmpty = 1;
+    while (bListNotEmpty)
+    {
+        bListNotEmpty = listGetAndRemoveNext(pList, NULL);
+    }
+
+    if (pthread_mutex_destroy(&pList->mutex) == -1)
+    {
+        NXPLOG_NCIHAL_E("Mutex destruction failed (errno=0x%08x)", errno);
+        return 0;
+    }
+
+    return 1;
+}
+
+/*******************************************************************************
+**
+** Function         listAdd
+**
+** Description      Add a node to the list
+**
+** Returns          1, if added, 0 if otherwise
+**
+*******************************************************************************/
+int listAdd(struct listHead* pList, void* pData)
+{
+    struct listNode* pNode;
+    struct listNode* pLastNode;
+    int result;
+
+    /* Create node */
+    pNode = (struct listNode*) malloc(sizeof(struct listNode));
+    if (pNode == NULL)
+    {
+        result = 0;
+        NXPLOG_NCIHAL_E("Failed to malloc");
+        goto clean_and_return;
+    }
+    pNode->pData = pData;
+    pNode->pNext = NULL;
+
+    pthread_mutex_lock(&pList->mutex);
+
+    /* Add the node to the list */
+    if (pList->pFirst == NULL)
+    {
+        /* Set the node as the head */
+        pList->pFirst = pNode;
+    }
+    else
+    {
+        /* Seek to the end of the list */
+        pLastNode = pList->pFirst;
+        while (pLastNode->pNext != NULL)
+        {
+            pLastNode = pLastNode->pNext;
+        }
+
+        /* Add the node to the current list */
+        pLastNode->pNext = pNode;
+    }
+
+    result = 1;
+
+clean_and_return:
+    pthread_mutex_unlock(&pList->mutex);
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         listRemove
+**
+** Description      Remove node from the list
+**
+** Returns          1, if removed, 0 if otherwise
+**
+*******************************************************************************/
+int listRemove(struct listHead* pList, void* pData)
+{
+    struct listNode* pNode;
+    struct listNode* pRemovedNode;
+    int result;
+
+    pthread_mutex_lock(&pList->mutex);
+
+    if (pList->pFirst == NULL)
+    {
+        /* Empty list */
+        NXPLOG_NCIHAL_E("Failed to deallocate (list empty)");
+        result = 0;
+        goto clean_and_return;
+    }
+
+    pNode = pList->pFirst;
+    if (pList->pFirst->pData == pData)
+    {
+        /* Get the removed node */
+        pRemovedNode = pNode;
+
+        /* Remove the first node */
+        pList->pFirst = pList->pFirst->pNext;
+    }
+    else
+    {
+        while (pNode->pNext != NULL)
+        {
+            if (pNode->pNext->pData == pData)
+            {
+                /* Node found ! */
+                break;
+            }
+            pNode = pNode->pNext;
+        }
+
+        if (pNode->pNext == NULL)
+        {
+            /* Node not found */
+            result = 0;
+            NXPLOG_NCIHAL_E("Failed to deallocate (not found %8p)", pData);
+            goto clean_and_return;
+        }
+
+        /* Get the removed node */
+        pRemovedNode = pNode->pNext;
+
+        /* Remove the node from the list */
+        pNode->pNext = pNode->pNext->pNext;
+    }
+
+    /* Deallocate the node */
+    free(pRemovedNode);
+
+    result = 1;
+
+clean_and_return:
+    pthread_mutex_unlock(&pList->mutex);
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         listGetAndRemoveNext
+**
+** Description      Get next node on the list and remove it
+**
+** Returns          1, if successful, 0 if otherwise
+**
+*******************************************************************************/
+int listGetAndRemoveNext(struct listHead* pList, void** ppData)
+{
+    struct listNode* pNode;
+    int result;
+
+    pthread_mutex_lock(&pList->mutex);
+
+    if (pList->pFirst ==  NULL)
+    {
+        /* Empty list */
+        NXPLOG_NCIHAL_D("Failed to deallocate (list empty)");
+        result = 0;
+        goto clean_and_return;
+    }
+
+    /* Work on the first node */
+    pNode = pList->pFirst;
+
+    /* Return the data */
+    if (ppData != NULL)
+    {
+        *ppData = pNode->pData;
+    }
+
+    /* Remove and deallocate the node */
+    pList->pFirst = pNode->pNext;
+    free(pNode);
+
+    result = 1;
+
+clean_and_return:
+    listDump(pList);
+    pthread_mutex_unlock(&pList->mutex);
+    return result;
+}
+
+/*******************************************************************************
+**
+** Function         listDump
+**
+** Description      Dump list information
+**
+** Returns          None
+**
+*******************************************************************************/
+void listDump(struct listHead* pList)
+{
+    struct listNode* pNode = pList->pFirst;
+
+    NXPLOG_NCIHAL_D("Node dump:");
+    while (pNode != NULL)
+    {
+        NXPLOG_NCIHAL_D("- %8p (%8p)", pNode, pNode->pData);
+        pNode = pNode->pNext;
+    }
+
+    return;
+}
+
+/* END Linked list source code */
+
+/****************** Semaphore and mutex helper functions **********************/
+
+static phNxpNciHal_Monitor_t *nxpncihal_monitor = NULL;
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_init_monitor
+**
+** Description      Initialize the semaphore monitor
+**
+** Returns          Pointer to monitor, otherwise NULL if failed
+**
+*******************************************************************************/
+phNxpNciHal_Monitor_t*
+phNxpNciHal_init_monitor(void)
+{
+    NXPLOG_NCIHAL_D("Entering phNxpNciHal_init_monitor");
+
+    if (nxpncihal_monitor == NULL)
+    {
+        nxpncihal_monitor = (phNxpNciHal_Monitor_t *) malloc(
+                sizeof(phNxpNciHal_Monitor_t));
+    }
+
+    if (nxpncihal_monitor != NULL)
+    {
+        memset(nxpncihal_monitor, 0x00, sizeof(phNxpNciHal_Monitor_t));
+
+        if (pthread_mutex_init(&nxpncihal_monitor->reentrance_mutex, NULL)
+                == -1)
+        {
+            NXPLOG_NCIHAL_E("reentrance_mutex creation returned 0x%08x", errno);
+            goto clean_and_return;
+        }
+
+        if (pthread_mutex_init(&nxpncihal_monitor->concurrency_mutex, NULL)
+                == -1)
+        {
+            NXPLOG_NCIHAL_E("concurrency_mutex creation returned 0x%08x", errno);
+            pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex);
+            goto clean_and_return;
+        }
+
+        if (listInit(&nxpncihal_monitor->sem_list) != 1)
+        {
+            NXPLOG_NCIHAL_E("Semaphore List creation failed");
+            pthread_mutex_destroy(&nxpncihal_monitor->concurrency_mutex);
+            pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex);
+            goto clean_and_return;
+        }
+    }
+    else
+    {
+        NXPLOG_NCIHAL_E("nxphal_monitor creation failed");
+        goto clean_and_return;
+    }
+
+    NXPLOG_NCIHAL_D("Returning with SUCCESS");
+
+    return nxpncihal_monitor;
+
+clean_and_return:
+    NXPLOG_NCIHAL_D("Returning with FAILURE");
+
+    if (nxpncihal_monitor != NULL)
+    {
+        free(nxpncihal_monitor);
+        nxpncihal_monitor = NULL;
+    }
+
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_cleanup_monitor
+**
+** Description      Clean up semaphore monitor
+**
+** Returns          None
+**
+*******************************************************************************/
+void phNxpNciHal_cleanup_monitor(void)
+{
+    if (nxpncihal_monitor != NULL)
+    {
+        pthread_mutex_destroy(&nxpncihal_monitor->concurrency_mutex);
+        REENTRANCE_UNLOCK();
+        pthread_mutex_destroy(&nxpncihal_monitor->reentrance_mutex);
+        phNxpNciHal_releaseall_cb_data();
+        listDestroy(&nxpncihal_monitor->sem_list);
+    }
+
+    free(nxpncihal_monitor);
+    nxpncihal_monitor = NULL;
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_get_monitor
+**
+** Description      Get monitor
+**
+** Returns          Pointer to monitor
+**
+*******************************************************************************/
+phNxpNciHal_Monitor_t*
+phNxpNciHal_get_monitor(void)
+{
+    return nxpncihal_monitor;
+}
+
+/* Initialize the callback data */
+NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t *pCallbackData,
+        void *pContext)
+{
+    /* Create semaphore */
+    if (sem_init(&pCallbackData->sem, 0, 0) == -1)
+    {
+        NXPLOG_NCIHAL_E("Semaphore creation failed (errno=0x%08x)", errno);
+        return NFCSTATUS_FAILED;
+    }
+
+    /* Set default status value */
+    pCallbackData->status = NFCSTATUS_FAILED;
+
+    /* Copy the context */
+    pCallbackData->pContext = pContext;
+
+    /* Add to active semaphore list */
+    if (listAdd(&phNxpNciHal_get_monitor()->sem_list, pCallbackData) != 1)
+    {
+        NXPLOG_NCIHAL_E("Failed to add the semaphore to the list");
+    }
+
+    return NFCSTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_cleanup_cb_data
+**
+** Description      Clean up callback data
+**
+** Returns          None
+**
+*******************************************************************************/
+void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData)
+{
+    /* Destroy semaphore */
+    if (sem_destroy(&pCallbackData->sem))
+    {
+        NXPLOG_NCIHAL_E("phNxpNciHal_cleanup_cb_data: Failed to destroy semaphore (errno=0x%08x)", errno);
+    }
+
+    /* Remove from active semaphore list */
+    if (listRemove(&phNxpNciHal_get_monitor()->sem_list, pCallbackData) != 1)
+    {
+        NXPLOG_NCIHAL_E("phNxpNciHal_cleanup_cb_data: Failed to remove semaphore from the list");
+    }
+
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_releaseall_cb_data
+**
+** Description      Release all callback data
+**
+** Returns          None
+**
+*******************************************************************************/
+void phNxpNciHal_releaseall_cb_data(void)
+{
+    phNxpNciHal_Sem_t* pCallbackData;
+
+    while (listGetAndRemoveNext(&phNxpNciHal_get_monitor()->sem_list,
+            (void**) &pCallbackData))
+    {
+        pCallbackData->status = NFCSTATUS_FAILED;
+        sem_post(&pCallbackData->sem);
+    }
+
+    return;
+}
+
+/* END Semaphore and mutex helper functions */
+
+/**************************** Other functions *********************************/
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_print_packet
+**
+** Description      Print packet
+**
+** Returns          None
+**
+*******************************************************************************/
+void phNxpNciHal_print_packet(const char *pString, const uint8_t *p_data,
+        uint16_t len)
+{
+    uint32_t i, j;
+    char print_buffer[len * 3 + 1];
+
+    memset (print_buffer, 0, sizeof(print_buffer));
+    for (i = 0; i < len; i++) {
+        snprintf(&print_buffer[i * 2], 3, "%02X", p_data[i]);
+    }
+    if( 0 == memcmp(pString,"SEND",0x04))
+    {
+        NXPLOG_NCIX_D("len = %3d > %s", len, print_buffer);
+    }
+    else if( 0 == memcmp(pString,"RECV",0x04))
+    {
+        NXPLOG_NCIR_D("len = %3d > %s", len, print_buffer);
+    }
+
+    return;
+}
+
+
+/*******************************************************************************
+**
+** Function         phNxpNciHal_emergency_recovery
+**
+** Description      Emergency recovery in case of no other way out
+**
+** Returns          None
+**
+*******************************************************************************/
+
+void phNxpNciHal_emergency_recovery(void)
+{
+    NXPLOG_NCIHAL_E("%s: abort()", __FUNCTION__);
+    //    abort();
+}
diff --git a/halimpl/pn54x/utils/phNxpNciHal_utils.h b/halimpl/pn54x/utils/phNxpNciHal_utils.h
new file mode 100644
index 0000000..f7bdfa2
--- /dev/null
+++ b/halimpl/pn54x/utils/phNxpNciHal_utils.h
@@ -0,0 +1,103 @@
+/*
+ *
+ *  Copyright (C) 2013-2014 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 _PHNXPNCIHAL_UTILS_H_
+#define _PHNXPNCIHAL_UTILS_H_
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <phNfcStatus.h>
+#include <assert.h>
+
+/********************* Definitions and structures *****************************/
+
+/* List structures */
+struct listNode
+{
+    void* pData;
+    struct listNode* pNext;
+};
+
+struct listHead
+{
+    struct listNode* pFirst;
+    pthread_mutex_t mutex;
+};
+
+
+/* Semaphore handling structure */
+typedef struct phNxpNciHal_Sem
+{
+    /* Semaphore used to wait for callback */
+    sem_t sem;
+
+    /* Used to store the status sent by the callback */
+    NFCSTATUS status;
+
+    /* Used to provide a local context to the callback */
+    void* pContext;
+
+} phNxpNciHal_Sem_t;
+
+/* Semaphore helper macros */
+#define SEM_WAIT(cb_data) sem_wait(&((cb_data).sem))
+#define SEM_POST(p_cb_data) sem_post(&((p_cb_data)->sem))
+
+/* Semaphore and mutex monitor */
+typedef struct phNxpNciHal_Monitor
+{
+    /* Mutex protecting native library against reentrance */
+    pthread_mutex_t reentrance_mutex;
+
+    /* Mutex protecting native library against concurrency */
+    pthread_mutex_t concurrency_mutex;
+
+    /* List used to track pending semaphores waiting for callback */
+    struct listHead sem_list;
+
+} phNxpNciHal_Monitor_t;
+
+/************************ Exposed functions ***********************************/
+/* List functions */
+int listInit(struct listHead* pList);
+int listDestroy(struct listHead* pList);
+int listAdd(struct listHead* pList, void* pData);
+int listRemove(struct listHead* pList, void* pData);
+int listGetAndRemoveNext(struct listHead* pList, void** ppData);
+void listDump(struct listHead* pList);
+
+/* NXP NCI HAL utility functions */
+phNxpNciHal_Monitor_t* phNxpNciHal_init_monitor(void);
+void phNxpNciHal_cleanup_monitor(void);
+phNxpNciHal_Monitor_t* phNxpNciHal_get_monitor(void);
+NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t *pCallbackData,
+        void *pContext);
+void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData);
+void phNxpNciHal_releaseall_cb_data(void);
+void phNxpNciHal_print_packet(const char *pString, const uint8_t *p_data,
+        uint16_t len);
+void phNxpNciHal_emergency_recovery(void);
+
+/* Lock unlock helper macros */
+/* Lock unlock helper macros */
+#define REENTRANCE_LOCK()      if (phNxpNciHal_get_monitor()) pthread_mutex_lock(&phNxpNciHal_get_monitor()->reentrance_mutex)
+#define REENTRANCE_UNLOCK()    if (phNxpNciHal_get_monitor()) pthread_mutex_unlock(&phNxpNciHal_get_monitor()->reentrance_mutex)
+#define CONCURRENCY_LOCK()     if (phNxpNciHal_get_monitor()) pthread_mutex_lock(&phNxpNciHal_get_monitor()->concurrency_mutex)
+#define CONCURRENCY_UNLOCK()   if (phNxpNciHal_get_monitor()) pthread_mutex_unlock(&phNxpNciHal_get_monitor()->concurrency_mutex)
+
+#endif /* _PHNXPNCIHAL_UTILS_H_ */